@agent-native/core 0.90.10 → 0.91.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 (360) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +30 -0
  3. package/corpus/core/docs/content/toolkit-settings.mdx +56 -3
  4. package/corpus/core/package.json +2 -1
  5. package/corpus/core/src/agent/durable-background.ts +5 -5
  6. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +40 -8
  7. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -7
  8. package/corpus/core/src/agent/engine/output-tokens.ts +94 -0
  9. package/corpus/core/src/agent/production-agent.ts +34 -6
  10. package/corpus/core/src/agent/run-ownership.ts +29 -1
  11. package/corpus/core/src/agent/types.ts +3 -2
  12. package/corpus/core/src/changelog/parse.ts +78 -0
  13. package/corpus/core/src/chat-threads/schema.ts +43 -0
  14. package/corpus/core/src/chat-threads/store.ts +144 -12
  15. package/corpus/core/src/cli/workspace-dev.ts +25 -5
  16. package/corpus/core/src/client/AgentPanel.tsx +79 -14
  17. package/corpus/core/src/client/AssistantChat.tsx +359 -425
  18. package/corpus/core/src/client/analytics-session.ts +70 -0
  19. package/corpus/core/src/client/analytics.ts +175 -49
  20. package/corpus/core/src/client/chat/message-components.tsx +22 -2
  21. package/corpus/core/src/client/components/ui/message-scroller.tsx +131 -0
  22. package/corpus/core/src/client/conversation/AgentConversation.tsx +63 -41
  23. package/corpus/core/src/client/error-capture.ts +616 -0
  24. package/corpus/core/src/client/index.ts +12 -0
  25. package/corpus/core/src/client/session-replay.ts +57 -7
  26. package/corpus/core/src/client/settings/SettingsPanel.tsx +123 -1
  27. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +292 -45
  28. package/corpus/core/src/client/settings/index.ts +1 -0
  29. package/corpus/core/src/client/sharing/ShareButton.tsx +14 -11
  30. package/corpus/core/src/client/sharing/ShareDialog.tsx +13 -10
  31. package/corpus/core/src/db/client.ts +12 -9
  32. package/corpus/core/src/mcp/builtin-tools.ts +29 -2
  33. package/corpus/core/src/server/agent-chat-plugin.ts +174 -79
  34. package/corpus/core/src/server/onboarding-html.ts +28 -16
  35. package/corpus/core/src/shared/reasoning-effort.ts +23 -0
  36. package/corpus/core/src/sharing/actions/list-resource-shares.ts +45 -1
  37. package/corpus/core/src/sharing/actions/share-resource.ts +9 -0
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
  40. package/corpus/core/src/vite/client.ts +217 -35
  41. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +8 -7
  42. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +14 -10
  43. package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +15 -15
  44. package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +1 -0
  45. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -22
  46. package/corpus/templates/analytics/.agents/skills/data-programs/SKILL.md +114 -61
  47. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -0
  48. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +7 -7
  49. package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +1 -0
  50. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +1 -1
  51. package/corpus/templates/analytics/.builder/skills/bigquery/SKILL.md +17 -17
  52. package/corpus/templates/analytics/.builder/skills/gcloud/SKILL.md +5 -5
  53. package/corpus/templates/analytics/.builder/skills/github/SKILL.md +7 -7
  54. package/corpus/templates/analytics/.builder/skills/gong/SKILL.md +12 -12
  55. package/corpus/templates/analytics/.builder/skills/grafana/SKILL.md +7 -7
  56. package/corpus/templates/analytics/.builder/skills/sentry/SKILL.md +7 -7
  57. package/corpus/templates/analytics/.builder/skills/slack/SKILL.md +6 -6
  58. package/corpus/templates/analytics/.builder/skills/stripe/SKILL.md +7 -7
  59. package/corpus/templates/analytics/AGENTS.md +47 -2
  60. package/corpus/templates/analytics/actions/add-status-page-monitor.ts +36 -0
  61. package/corpus/templates/analytics/actions/capture-test-error.ts +33 -0
  62. package/corpus/templates/analytics/actions/delete-monitor.ts +24 -0
  63. package/corpus/templates/analytics/actions/delete-status-page.ts +23 -0
  64. package/corpus/templates/analytics/actions/get-error-issue.ts +36 -0
  65. package/corpus/templates/analytics/actions/get-monitor-stats.ts +55 -0
  66. package/corpus/templates/analytics/actions/get-monitor.ts +27 -0
  67. package/corpus/templates/analytics/actions/get-public-status-page.ts +41 -0
  68. package/corpus/templates/analytics/actions/get-status-page.ts +29 -0
  69. package/corpus/templates/analytics/actions/list-error-issues.ts +40 -0
  70. package/corpus/templates/analytics/actions/list-monitors.ts +21 -0
  71. package/corpus/templates/analytics/actions/list-status-pages.ts +21 -0
  72. package/corpus/templates/analytics/actions/match-error-issues.ts +51 -0
  73. package/corpus/templates/analytics/actions/navigate.ts +58 -4
  74. package/corpus/templates/analytics/actions/remove-status-page-monitor.ts +22 -0
  75. package/corpus/templates/analytics/actions/reorder-status-page-monitors.ts +25 -0
  76. package/corpus/templates/analytics/actions/resolve-error-issue.ts +38 -0
  77. package/corpus/templates/analytics/actions/run-monitor-check.ts +23 -0
  78. package/corpus/templates/analytics/actions/save-analysis.ts +1 -0
  79. package/corpus/templates/analytics/actions/save-monitor.ts +145 -0
  80. package/corpus/templates/analytics/actions/save-status-page.ts +47 -0
  81. package/corpus/templates/analytics/actions/view-screen.ts +212 -0
  82. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  83. package/corpus/templates/analytics/app/components/layout/Layout.tsx +10 -1
  84. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +134 -39
  85. package/corpus/templates/analytics/app/components/monitoring/PublicStatusView.tsx +351 -0
  86. package/corpus/templates/analytics/app/components/monitoring/ResponseTimeChart.tsx +174 -0
  87. package/corpus/templates/analytics/app/components/monitoring/UptimeStatCards.tsx +85 -0
  88. package/corpus/templates/analytics/app/components/monitoring/UptimeTimelineBars.tsx +106 -0
  89. package/corpus/templates/analytics/app/components/monitoring/chart-utils.ts +101 -0
  90. package/corpus/templates/analytics/app/components/monitoring/index.ts +28 -0
  91. package/corpus/templates/analytics/app/components/monitoring/types.ts +42 -0
  92. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +34 -0
  93. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -0
  94. package/corpus/templates/analytics/app/i18n-data.ts +33 -0
  95. package/corpus/templates/analytics/app/pages/DataSources.tsx +28 -0
  96. package/corpus/templates/analytics/app/pages/Settings.tsx +77 -9
  97. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +3 -3
  98. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +7 -0
  99. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +205 -0
  100. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +100 -0
  101. package/corpus/templates/analytics/app/pages/monitoring/UptimePanel.tsx +475 -0
  102. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +372 -0
  103. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +360 -0
  104. package/corpus/templates/analytics/app/pages/monitoring/errors/Sparkline.tsx +55 -0
  105. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +106 -0
  106. package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +75 -0
  107. package/corpus/templates/analytics/app/pages/monitoring/errors/utils.ts +132 -0
  108. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorDetail.tsx +535 -0
  109. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +1026 -0
  110. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorList.tsx +311 -0
  111. package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +235 -0
  112. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPageEditor.tsx +661 -0
  113. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPagesView.tsx +355 -0
  114. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/i18n.ts +106 -0
  115. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/slug.ts +24 -0
  116. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/types.ts +20 -0
  117. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-summary.ts +87 -0
  118. package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +161 -0
  119. package/corpus/templates/analytics/app/pages/monitoring/uptime/utils.ts +210 -0
  120. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +76 -1
  121. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +74 -9
  122. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +197 -20
  123. package/corpus/templates/analytics/app/root.tsx +33 -1
  124. package/corpus/templates/analytics/app/routes/monitoring._index.tsx +10 -0
  125. package/corpus/templates/analytics/app/routes/status.$slug.tsx +118 -0
  126. package/corpus/templates/analytics/changelog/2026-07-08-add-uptime-monitors-that-ping-your-urls-and-alert-you-when-t.md +6 -0
  127. package/corpus/templates/analytics/changelog/2026-07-08-analytics-chats-keep-large-data-dictionaries-compact-so-prov.md +6 -0
  128. package/corpus/templates/analytics/changelog/2026-07-08-create-public-status-pages-that-share-the-live-health-of-cho.md +6 -0
  129. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-extension-panels-use-clearer-open-copy.md +6 -0
  130. package/corpus/templates/analytics/changelog/2026-07-08-error-capture.md +6 -0
  131. package/corpus/templates/analytics/changelog/2026-07-08-fixed-single-panel-dashboard-drags-so-they-no-longer-rewrite.md +6 -0
  132. package/corpus/templates/analytics/changelog/2026-07-08-jump-straight-from-an-error-in-a-session-recording-to-its-fu.md +6 -0
  133. package/corpus/templates/analytics/changelog/2026-07-08-monitor-detail-and-list-now-show-colorful-uptime-timelines-r.md +6 -0
  134. package/corpus/templates/analytics/changelog/2026-07-08-pinned-ask-chats-now-show-a-pin-icon-in-the-sidebar.md +6 -0
  135. package/corpus/templates/analytics/changelog/2026-07-08-publish-a-public-uptime-status-page-with-colorful-uptime-tim.md +6 -0
  136. package/corpus/templates/analytics/changelog/2026-07-08-sessions-now-hide-visitor-emails-in-demo-mode-and-show-clean.md +6 -0
  137. package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +5 -0
  138. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +5 -0
  139. package/corpus/templates/analytics/changelog/2026-07-08-the-uptime-monitor-list-now-has-a-current-status-overview-wi.md +6 -0
  140. package/corpus/templates/analytics/docs/error-capture.md +172 -0
  141. package/corpus/templates/analytics/docs/uptime-monitoring.md +150 -0
  142. package/corpus/templates/analytics/server/db/schema-errors.ts +150 -0
  143. package/corpus/templates/analytics/server/db/schema-monitoring.ts +177 -0
  144. package/corpus/templates/analytics/server/db/schema.ts +6 -0
  145. package/corpus/templates/analytics/server/jobs/uptime-monitors.ts +123 -0
  146. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +41 -0
  147. package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +55 -12
  148. package/corpus/templates/analytics/server/lib/error-capture.ts +1331 -0
  149. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +47 -1
  150. package/corpus/templates/analytics/server/lib/monitor-stats.ts +494 -0
  151. package/corpus/templates/analytics/server/lib/status-pages.ts +798 -0
  152. package/corpus/templates/analytics/server/lib/uptime-monitors.ts +1665 -0
  153. package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -37
  154. package/corpus/templates/analytics/server/plugins/auth.ts +11 -1
  155. package/corpus/templates/analytics/server/plugins/db.ts +408 -0
  156. package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +63 -0
  157. package/corpus/templates/assets/app/routes/_index.tsx +1 -1
  158. package/corpus/templates/assets/app/routes/settings.tsx +22 -1
  159. package/corpus/templates/assets/changelog/2026-07-08-recent-drafts-keep-comfortable-side-padding.md +6 -0
  160. package/corpus/templates/assets/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  161. package/corpus/templates/brain/app/routes/settings.tsx +43 -5
  162. package/corpus/templates/brain/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  163. package/corpus/templates/calendar/app/pages/Settings.tsx +44 -6
  164. package/corpus/templates/calendar/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  165. package/corpus/templates/chat/app/routes/settings.tsx +16 -1
  166. package/corpus/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  167. package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +79 -37
  168. package/corpus/templates/clips/actions/regenerate-chapters.ts +7 -0
  169. package/corpus/templates/clips/app/components/player/player-controls.tsx +35 -0
  170. package/corpus/templates/clips/app/components/player/video-player.tsx +162 -18
  171. package/corpus/templates/clips/app/hooks/use-auto-title.ts +15 -5
  172. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +63 -6
  173. package/corpus/templates/clips/app/routes/download.tsx +12 -4
  174. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
  175. package/corpus/templates/clips/app/routes/record.tsx +18 -1
  176. package/corpus/templates/clips/changelog/2026-07-07-auto-generated-chapter-requests-now-open-the-matching-agent-.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-07-shared-clips-start-playback-reliably-from-the-first-play-click.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-07-the-clips-desktop-download-page-now-uses-the-agent-native-ap.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-camera-and-microphone-menus-now-show-which-.md +6 -0
  180. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-copies-new-clip-links-after-saving.md +6 -0
  181. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-recordings-now-continue-after-granting-came.md +6 -0
  182. package/corpus/templates/clips/changelog/2026-07-08-mobile-shared-clips-now-have-loom-style-tap-and-skip-controls.md +6 -0
  183. package/corpus/templates/clips/changelog/2026-07-08-recordings-and-uploads-copy-links-after-saving.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-08-settings-are-cleaner-searchable-and-collapse-s3-with-builder.md +5 -0
  185. package/corpus/templates/clips/changelog/2026-07-08-transcripts-are-more-reliable-for-longer-desktop-recordings-.md +6 -0
  186. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -0
  187. package/corpus/templates/clips/chrome-extension/src/background.ts +162 -13
  188. package/corpus/templates/clips/chrome-extension/src/content-script.ts +14 -0
  189. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +36 -0
  190. package/corpus/templates/clips/chrome-extension/src/overlay.ts +99 -25
  191. package/corpus/templates/clips/chrome-extension/src/permission.ts +63 -14
  192. package/corpus/templates/clips/chrome-extension/src/popup.ts +123 -23
  193. package/corpus/templates/content/actions/_builder-cms-read-client.ts +47 -0
  194. package/corpus/templates/content/actions/_database-source-utils.ts +33 -4
  195. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +214 -29
  196. package/corpus/templates/content/actions/attach-content-database-source.ts +3 -0
  197. package/corpus/templates/content/actions/change-content-database-source-role.ts +1 -0
  198. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +42 -32
  199. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +352 -81
  200. package/corpus/templates/content/app/components/editor/database/settings.tsx +49 -24
  201. package/corpus/templates/content/app/routes/_app.settings.tsx +19 -1
  202. package/corpus/templates/content/changelog/2026-07-07-builder-source-tag-fields-now-import-as-multi-select.md +6 -0
  203. package/corpus/templates/content/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  204. package/corpus/templates/content/shared/api.ts +3 -0
  205. package/corpus/templates/content/shared/properties.ts +42 -0
  206. package/corpus/templates/design/actions/generate-design.ts +3 -0
  207. package/corpus/templates/design/actions/get-design-system.ts +147 -1
  208. package/corpus/templates/design/app/routes/settings.tsx +16 -1
  209. package/corpus/templates/design/changelog/2026-07-08-design-generation-now-follows-hydrated-builder-design-system.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  211. package/corpus/templates/dispatch/app/routes/settings.tsx +23 -2
  212. package/corpus/templates/dispatch/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  213. package/corpus/templates/forms/app/routes/_app.settings.tsx +16 -1
  214. package/corpus/templates/forms/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  215. package/corpus/templates/macros/app/routes/settings.tsx +16 -1
  216. package/corpus/templates/macros/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  217. package/corpus/templates/mail/app/components/settings/GmailFiltersSection.tsx +1 -1
  218. package/corpus/templates/mail/app/components/settings/SnippetsSection.tsx +1 -1
  219. package/corpus/templates/mail/app/pages/SettingsPage.tsx +123 -105
  220. package/corpus/templates/mail/changelog/2026-07-08-settings-redesigned-with-a-consistent-searchable-layout.md +5 -0
  221. package/corpus/templates/plan/app/routes/settings.tsx +23 -2
  222. package/corpus/templates/plan/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  223. package/corpus/templates/slides/actions/add-slide.ts +1 -0
  224. package/corpus/templates/slides/actions/get-design-system.ts +147 -1
  225. package/corpus/templates/slides/app/pages/Index.tsx +46 -1
  226. package/corpus/templates/slides/app/routes/settings.tsx +16 -1
  227. package/corpus/templates/slides/changelog/2026-07-08-deck-generation-now-follows-hydrated-builder-design-system-g.md +6 -0
  228. package/corpus/templates/slides/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  229. package/dist/agent/durable-background.d.ts +1 -1
  230. package/dist/agent/durable-background.d.ts.map +1 -1
  231. package/dist/agent/durable-background.js +5 -3
  232. package/dist/agent/durable-background.js.map +1 -1
  233. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  234. package/dist/agent/engine/ai-sdk-engine.js +24 -4
  235. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  236. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  237. package/dist/agent/engine/anthropic-engine.js +13 -3
  238. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  239. package/dist/agent/engine/output-tokens.d.ts +27 -0
  240. package/dist/agent/engine/output-tokens.d.ts.map +1 -1
  241. package/dist/agent/engine/output-tokens.js +70 -0
  242. package/dist/agent/engine/output-tokens.js.map +1 -1
  243. package/dist/agent/production-agent.d.ts.map +1 -1
  244. package/dist/agent/production-agent.js +28 -7
  245. package/dist/agent/production-agent.js.map +1 -1
  246. package/dist/agent/run-ownership.d.ts +6 -0
  247. package/dist/agent/run-ownership.d.ts.map +1 -1
  248. package/dist/agent/run-ownership.js +11 -1
  249. package/dist/agent/run-ownership.js.map +1 -1
  250. package/dist/agent/types.d.ts +3 -2
  251. package/dist/agent/types.d.ts.map +1 -1
  252. package/dist/agent/types.js.map +1 -1
  253. package/dist/changelog/parse.d.ts +7 -0
  254. package/dist/changelog/parse.d.ts.map +1 -1
  255. package/dist/changelog/parse.js +64 -0
  256. package/dist/changelog/parse.js.map +1 -1
  257. package/dist/chat-threads/schema.d.ts +445 -0
  258. package/dist/chat-threads/schema.d.ts.map +1 -0
  259. package/dist/chat-threads/schema.js +39 -0
  260. package/dist/chat-threads/schema.js.map +1 -0
  261. package/dist/chat-threads/store.d.ts +12 -0
  262. package/dist/chat-threads/store.d.ts.map +1 -1
  263. package/dist/chat-threads/store.js +99 -10
  264. package/dist/chat-threads/store.js.map +1 -1
  265. package/dist/cli/workspace-dev.d.ts.map +1 -1
  266. package/dist/cli/workspace-dev.js +20 -5
  267. package/dist/cli/workspace-dev.js.map +1 -1
  268. package/dist/client/AgentPanel.d.ts.map +1 -1
  269. package/dist/client/AgentPanel.js +35 -7
  270. package/dist/client/AgentPanel.js.map +1 -1
  271. package/dist/client/AssistantChat.d.ts.map +1 -1
  272. package/dist/client/AssistantChat.js +105 -183
  273. package/dist/client/AssistantChat.js.map +1 -1
  274. package/dist/client/analytics-session.d.ts +3 -0
  275. package/dist/client/analytics-session.d.ts.map +1 -0
  276. package/dist/client/analytics-session.js +66 -0
  277. package/dist/client/analytics-session.js.map +1 -0
  278. package/dist/client/analytics.d.ts +32 -0
  279. package/dist/client/analytics.d.ts.map +1 -1
  280. package/dist/client/analytics.js +116 -46
  281. package/dist/client/analytics.js.map +1 -1
  282. package/dist/client/chat/message-components.d.ts +2 -1
  283. package/dist/client/chat/message-components.d.ts.map +1 -1
  284. package/dist/client/chat/message-components.js +16 -6
  285. package/dist/client/chat/message-components.js.map +1 -1
  286. package/dist/client/components/ui/message-scroller.d.ts +16 -0
  287. package/dist/client/components/ui/message-scroller.d.ts.map +1 -0
  288. package/dist/client/components/ui/message-scroller.js +25 -0
  289. package/dist/client/components/ui/message-scroller.js.map +1 -0
  290. package/dist/client/conversation/AgentConversation.d.ts +1 -1
  291. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  292. package/dist/client/conversation/AgentConversation.js +3 -8
  293. package/dist/client/conversation/AgentConversation.js.map +1 -1
  294. package/dist/client/error-capture.d.ts +99 -0
  295. package/dist/client/error-capture.d.ts.map +1 -0
  296. package/dist/client/error-capture.js +437 -0
  297. package/dist/client/error-capture.js.map +1 -0
  298. package/dist/client/index.d.ts +2 -2
  299. package/dist/client/index.d.ts.map +1 -1
  300. package/dist/client/index.js +3 -1
  301. package/dist/client/index.js.map +1 -1
  302. package/dist/client/session-replay.d.ts +22 -0
  303. package/dist/client/session-replay.d.ts.map +1 -1
  304. package/dist/client/session-replay.js +45 -4
  305. package/dist/client/session-replay.js.map +1 -1
  306. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  307. package/dist/client/settings/SettingsPanel.js +100 -5
  308. package/dist/client/settings/SettingsPanel.js.map +1 -1
  309. package/dist/client/settings/SettingsTabsPage.d.ts +49 -1
  310. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  311. package/dist/client/settings/SettingsTabsPage.js +131 -19
  312. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  313. package/dist/client/settings/index.d.ts +1 -1
  314. package/dist/client/settings/index.d.ts.map +1 -1
  315. package/dist/client/settings/index.js.map +1 -1
  316. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  317. package/dist/client/sharing/ShareButton.js +13 -8
  318. package/dist/client/sharing/ShareButton.js.map +1 -1
  319. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  320. package/dist/client/sharing/ShareDialog.js +12 -7
  321. package/dist/client/sharing/ShareDialog.js.map +1 -1
  322. package/dist/collab/routes.d.ts +1 -1
  323. package/dist/collab/struct-routes.d.ts +1 -1
  324. package/dist/db/client.d.ts.map +1 -1
  325. package/dist/db/client.js +12 -7
  326. package/dist/db/client.js.map +1 -1
  327. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  328. package/dist/mcp/builtin-tools.js +21 -2
  329. package/dist/mcp/builtin-tools.js.map +1 -1
  330. package/dist/notifications/routes.d.ts +1 -1
  331. package/dist/observability/routes.d.ts +5 -5
  332. package/dist/org/schema.d.ts +15 -15
  333. package/dist/progress/routes.d.ts +1 -1
  334. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  335. package/dist/resources/handlers.d.ts +3 -3
  336. package/dist/secrets/routes.d.ts +9 -9
  337. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  338. package/dist/server/agent-chat-plugin.js +109 -73
  339. package/dist/server/agent-chat-plugin.js.map +1 -1
  340. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  341. package/dist/server/onboarding-html.d.ts.map +1 -1
  342. package/dist/server/onboarding-html.js +28 -16
  343. package/dist/server/onboarding-html.js.map +1 -1
  344. package/dist/shared/reasoning-effort.d.ts +1 -0
  345. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  346. package/dist/shared/reasoning-effort.js +18 -0
  347. package/dist/shared/reasoning-effort.js.map +1 -1
  348. package/dist/sharing/actions/list-resource-shares.js +30 -1
  349. package/dist/sharing/actions/list-resource-shares.js.map +1 -1
  350. package/dist/sharing/actions/share-resource.js +6 -0
  351. package/dist/sharing/actions/share-resource.js.map +1 -1
  352. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  353. package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
  354. package/dist/vite/client.d.ts.map +1 -1
  355. package/dist/vite/client.js +192 -30
  356. package/dist/vite/client.js.map +1 -1
  357. package/docs/content/toolkit-settings.mdx +56 -3
  358. package/package.json +2 -1
  359. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  360. package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
@@ -2,11 +2,39 @@ import { type ComponentType, type ReactNode } from "react";
2
2
  type SettingsTabIcon = ComponentType<{
3
3
  className?: string;
4
4
  }>;
5
+ /**
6
+ * A single deep-link target inside settings that the settings search can jump
7
+ * to. Entries usually map to a section within a tab (via a `hash`/anchor id),
8
+ * making individual controls discoverable without hunting through every tab.
9
+ */
10
+ export interface SettingsSearchEntry {
11
+ /** Stable unique id for the entry. */
12
+ id: string;
13
+ /** Primary label shown in the search results. */
14
+ label: string;
15
+ /** Extra space-separated terms to match against (synonyms, provider names). */
16
+ keywords?: string;
17
+ /** Optional secondary description shown under the label. */
18
+ description?: string;
19
+ /** Tab to activate when the entry is picked. Defaults to the owning tab. */
20
+ tabId?: string;
21
+ /**
22
+ * Optional section id / DOM element id to open + scroll to after switching
23
+ * tabs. Handled by the inner panels' own hash listeners.
24
+ */
25
+ hash?: string;
26
+ /** Optional icon override; defaults to the owning tab's icon. */
27
+ icon?: SettingsTabIcon;
28
+ }
5
29
  export interface SettingsTabItem {
6
30
  id: string;
7
31
  label: string;
8
32
  icon?: SettingsTabIcon;
9
33
  content: ReactNode;
34
+ /** Extra space-separated terms so this tab is findable via search. */
35
+ keywords?: string;
36
+ /** Deep-link entries within this tab for the settings search. */
37
+ searchEntries?: SettingsSearchEntry[];
10
38
  }
11
39
  export interface SettingsTabsPageProps {
12
40
  general: ReactNode;
@@ -21,7 +49,27 @@ export interface SettingsTabsPageProps {
21
49
  className?: string;
22
50
  navClassName?: string;
23
51
  contentClassName?: string;
52
+ /** Whether to render the settings search box. Defaults to true. */
53
+ enableSearch?: boolean;
54
+ /** Placeholder for the settings search box. */
55
+ searchPlaceholder?: string;
56
+ /** Extra global search entries (e.g. anchors within the General tab). */
57
+ searchEntries?: SettingsSearchEntry[];
58
+ /** Deep-link entries for the General tab. */
59
+ generalSearchEntries?: SettingsSearchEntry[];
60
+ /**
61
+ * Controlled active tab id. When provided, the parent owns tab state (and is
62
+ * responsible for URL/app-state sync); the component skips its own hash-based
63
+ * tab tracking. Leave undefined for the default uncontrolled, hash-driven
64
+ * behavior.
65
+ */
66
+ value?: string;
67
+ /**
68
+ * Called whenever the active tab changes via a tab click or a search result
69
+ * selection. Fires in both controlled and uncontrolled modes.
70
+ */
71
+ onValueChange?: (tabId: string) => void;
24
72
  }
25
- export declare function SettingsTabsPage({ general, team, whatsNew, extraTabs, generalLabel, teamLabel, whatsNewLabel, ariaLabel, defaultTab, className, navClassName, contentClassName, }: SettingsTabsPageProps): import("react").JSX.Element;
73
+ export declare function SettingsTabsPage({ general, team, whatsNew, extraTabs, generalLabel, teamLabel, whatsNewLabel, ariaLabel, defaultTab, className, navClassName, contentClassName, enableSearch, searchPlaceholder, searchEntries, generalSearchEntries, value, onValueChange, }: SettingsTabsPageProps): import("react").JSX.Element;
26
74
  export {};
27
75
  //# sourceMappingURL=SettingsTabsPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsTabsPage.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,KAAK,eAAe,GAAG,aAAa,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4CD,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAc,EACd,YAAwB,EACxB,SAAkB,EAClB,aAA4B,EAC5B,SAA+B,EAC/B,UAAsB,EACtB,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,EAAE,qBAAqB,+BA2HvB"}
1
+ {"version":3,"file":"SettingsTabsPage.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,KAAK,eAAe,GAAG,aAAa,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,SAAS,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACtC,6CAA6C;IAC7C,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC7C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAmDD,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAc,EACd,YAAwB,EACxB,SAAkB,EAClB,aAA4B,EAC5B,SAA+B,EAC/B,UAAsB,EACtB,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,YAAmB,EACnB,iBAAqC,EACrC,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,aAAa,GACd,EAAE,qBAAqB,+BA6SvB"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { IconHistory, IconSettings, IconUsers } from "@tabler/icons-react";
3
- import { useEffect, useMemo, useState, } from "react";
2
+ import { IconHistory, IconSearch, IconSettings, IconUsers, IconX, } from "@tabler/icons-react";
3
+ import { useCallback, useEffect, useMemo, useState, } from "react";
4
4
  import { cn } from "../utils.js";
5
5
  function normalizeTabId(value) {
6
6
  const normalized = value
@@ -40,7 +40,7 @@ function updateHashForTab(tabId) {
40
40
  const hash = tabId === "general" ? "" : `#${encodeURIComponent(tabId)}`;
41
41
  window.history.pushState(null, "", `${pathname}${search}${hash}`);
42
42
  }
43
- export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], generalLabel = "General", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "general", className, navClassName, contentClassName, }) {
43
+ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], generalLabel = "General", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "general", className, navClassName, contentClassName, enableSearch = true, searchPlaceholder = "Search settings", searchEntries, generalSearchEntries, value, onValueChange, }) {
44
44
  const tabs = useMemo(() => {
45
45
  const next = [
46
46
  {
@@ -48,6 +48,7 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
48
48
  label: generalLabel,
49
49
  icon: IconSettings,
50
50
  content: general,
51
+ searchEntries: generalSearchEntries,
51
52
  },
52
53
  ];
53
54
  next.push(...extraTabs);
@@ -72,6 +73,7 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
72
73
  extraTabs,
73
74
  general,
74
75
  generalLabel,
76
+ generalSearchEntries,
75
77
  team,
76
78
  teamLabel,
77
79
  whatsNew,
@@ -80,29 +82,139 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
80
82
  const fallbackTab = tabs.some((tab) => tab.id === defaultTab)
81
83
  ? defaultTab
82
84
  : (tabs[0]?.id ?? "general");
83
- const [activeTab, setActiveTab] = useState(() => activeTabFromHash(tabs, fallbackTab));
85
+ const isControlled = value !== undefined;
86
+ const [internalTab, setInternalTab] = useState(() => activeTabFromHash(tabs, fallbackTab));
87
+ const activeTab = isControlled ? value : internalTab;
88
+ const [query, setQuery] = useState("");
89
+ const changeTab = useCallback((tabId) => {
90
+ if (!isControlled)
91
+ setInternalTab(tabId);
92
+ onValueChange?.(tabId);
93
+ }, [isControlled, onValueChange]);
84
94
  useEffect(() => {
85
- if (tabs.some((tab) => tab.id === activeTab))
95
+ // In controlled mode the parent owns (and validates) the active tab.
96
+ if (isControlled)
86
97
  return;
87
- setActiveTab(fallbackTab);
88
- }, [activeTab, fallbackTab, tabs]);
98
+ if (tabs.some((tab) => tab.id === internalTab))
99
+ return;
100
+ setInternalTab(fallbackTab);
101
+ }, [fallbackTab, internalTab, isControlled, tabs]);
89
102
  useEffect(() => {
103
+ // Hash-driven tab tracking only applies to the uncontrolled mode. Only
104
+ // react to hashes that name a top-level tab. Section-level hashes
105
+ // (e.g. `#llm`, `#secrets`) are consumed by the inner panels, so leave
106
+ // the active tab untouched to avoid bouncing back to General.
107
+ if (isControlled)
108
+ return;
90
109
  const handleHashChange = () => {
91
- setActiveTab(activeTabFromHash(tabs, fallbackTab));
110
+ const fromHash = normalizeTabId(window.location.hash);
111
+ if (fromHash && tabs.some((tab) => tab.id === fromHash)) {
112
+ setInternalTab(fromHash);
113
+ }
92
114
  };
93
115
  window.addEventListener("hashchange", handleHashChange);
94
116
  return () => window.removeEventListener("hashchange", handleHashChange);
95
- }, [fallbackTab, tabs]);
117
+ }, [isControlled, tabs]);
96
118
  const selectedTab = tabs.find((tab) => tab.id === activeTab) ?? tabs[0];
97
- return (_jsxs("div", { className: cn("flex min-h-full w-full flex-col overflow-hidden bg-background sm:flex-row", className), children: [_jsx("nav", { "aria-label": ariaLabel, role: "tablist", className: cn("flex shrink-0 gap-1 overflow-x-auto border-b border-border/50 bg-muted/30 p-2 sm:w-48 sm:flex-col sm:overflow-x-visible sm:border-b-0 sm:border-e", navClassName), children: tabs.map((tab) => {
98
- const Icon = tab.icon;
99
- const selected = tab.id === selectedTab?.id;
100
- return (_jsxs("button", { type: "button", role: "tab", "aria-selected": selected, "aria-controls": `settings-tabpanel-${tab.id}`, id: `settings-tab-${tab.id}`, onClick: () => {
101
- setActiveTab(tab.id);
102
- updateHashForTab(tab.id);
103
- }, className: cn("flex min-h-9 shrink-0 items-center gap-2 rounded-md px-3 py-2 text-start text-sm font-medium transition-colors sm:w-full", selected
104
- ? "bg-background text-foreground shadow-sm ring-1 ring-border/60"
105
- : "text-muted-foreground hover:bg-accent/60 hover:text-foreground"), children: [Icon ? (_jsx(Icon, { className: cn("size-4 shrink-0", selected ? "text-foreground" : "text-muted-foreground") })) : null, _jsx("span", { className: "truncate", children: tab.label })] }, tab.id));
106
- }) }), _jsx("div", { id: `settings-tabpanel-${selectedTab?.id ?? "general"}`, role: "tabpanel", "aria-labelledby": `settings-tab-${selectedTab?.id ?? "general"}`, className: cn("min-w-0 flex-1 overflow-y-auto p-4 sm:p-6", contentClassName), children: selectedTab?.content })] }));
119
+ // Flatten tab + deep-link entries into one searchable index.
120
+ const searchIndex = useMemo(() => {
121
+ const entries = [];
122
+ const seen = new Set();
123
+ const add = (entry) => {
124
+ if (seen.has(entry.id))
125
+ return;
126
+ seen.add(entry.id);
127
+ entries.push(entry);
128
+ };
129
+ for (const tab of tabs) {
130
+ add({
131
+ id: `tab:${tab.id}`,
132
+ label: tab.label,
133
+ keywords: tab.keywords,
134
+ tabId: tab.id,
135
+ tabLabel: tab.label,
136
+ icon: tab.icon,
137
+ haystack: `${tab.label} ${tab.keywords ?? ""}`.toLowerCase(),
138
+ });
139
+ for (const sub of tab.searchEntries ?? []) {
140
+ add({
141
+ ...sub,
142
+ tabId: sub.tabId ?? tab.id,
143
+ tabLabel: tab.label,
144
+ icon: sub.icon ?? tab.icon,
145
+ haystack: `${sub.label} ${sub.keywords ?? ""} ${sub.description ?? ""} ${tab.label}`.toLowerCase(),
146
+ });
147
+ }
148
+ }
149
+ for (const sub of searchEntries ?? []) {
150
+ const owner = tabs.find((tab) => tab.id === (sub.tabId ?? "general"));
151
+ add({
152
+ ...sub,
153
+ tabId: sub.tabId ?? "general",
154
+ tabLabel: owner?.label ?? sub.tabId ?? "General",
155
+ icon: sub.icon ?? owner?.icon,
156
+ haystack: `${sub.label} ${sub.keywords ?? ""} ${sub.description ?? ""} ${owner?.label ?? ""}`.toLowerCase(),
157
+ });
158
+ }
159
+ return entries;
160
+ }, [searchEntries, tabs]);
161
+ const trimmedQuery = query.trim().toLowerCase();
162
+ const results = useMemo(() => {
163
+ if (!trimmedQuery)
164
+ return [];
165
+ const terms = trimmedQuery.split(/\s+/).filter(Boolean);
166
+ return searchIndex
167
+ .filter((entry) => terms.every((term) => entry.haystack.includes(term)))
168
+ .sort((a, b) => {
169
+ const aStarts = a.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;
170
+ const bStarts = b.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;
171
+ if (aStarts !== bStarts)
172
+ return aStarts - bStarts;
173
+ return a.label.localeCompare(b.label);
174
+ });
175
+ }, [searchIndex, trimmedQuery]);
176
+ const selectEntry = (entry) => {
177
+ changeTab(entry.tabId);
178
+ setQuery("");
179
+ if (typeof window === "undefined")
180
+ return;
181
+ const hash = entry.hash?.replace(/^#/, "");
182
+ if (hash) {
183
+ const { pathname, search } = window.location;
184
+ window.history.pushState(null, "", `${pathname}${search}#${hash}`);
185
+ // Let the inner panels open + scroll to their section.
186
+ window.dispatchEvent(new Event("hashchange"));
187
+ window.requestAnimationFrame(() => {
188
+ document
189
+ .getElementById(hash)
190
+ ?.scrollIntoView({ block: "start", behavior: "smooth" });
191
+ });
192
+ }
193
+ else if (!isControlled) {
194
+ updateHashForTab(entry.tabId);
195
+ }
196
+ };
197
+ const searching = enableSearch && trimmedQuery.length > 0;
198
+ return (_jsxs("div", { className: cn("flex h-full min-h-0 w-full flex-col overflow-hidden bg-background sm:flex-row", className), children: [_jsxs("div", { className: cn("flex shrink-0 flex-col gap-2 border-b border-border bg-background p-2 sm:min-h-0 sm:w-56 sm:overflow-y-auto sm:border-b-0 sm:border-e sm:p-3", navClassName), children: [enableSearch ? (_jsxs("div", { className: "relative sm:mb-1", children: [_jsx(IconSearch, { className: "pointer-events-none absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { type: "search", value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: (event) => {
199
+ if (event.key === "Escape")
200
+ setQuery("");
201
+ if (event.key === "Enter" && results[0]) {
202
+ event.preventDefault();
203
+ selectEntry(results[0]);
204
+ }
205
+ }, placeholder: searchPlaceholder, "aria-label": searchPlaceholder, className: "h-8 w-full rounded-md border border-border bg-background ps-8 pe-7 text-[13px] text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-foreground/30 focus:ring-2 focus:ring-accent/40" }), query ? (_jsx("button", { type: "button", onClick: () => setQuery(""), "aria-label": "Clear search", className: "absolute end-1.5 top-1/2 flex size-5 -translate-y-1/2 items-center justify-center rounded text-muted-foreground hover:bg-accent/60 hover:text-foreground", children: _jsx(IconX, { className: "size-3.5" }) })) : null] })) : null, searching ? (_jsx("div", { role: "listbox", "aria-label": "Settings search results", className: "flex flex-col gap-0.5", children: results.length === 0 ? (_jsx("p", { className: "px-2 py-6 text-center text-[12px] text-muted-foreground", children: "No matching settings" })) : (results.map((entry) => {
206
+ const Icon = entry.icon;
207
+ return (_jsxs("button", { type: "button", role: "option", "aria-selected": false, onClick: () => selectEntry(entry), className: "flex items-start gap-2 rounded-md px-2.5 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent/60", children: [Icon ? (_jsx(Icon, { className: "mt-0.5 size-4 shrink-0 text-muted-foreground" })) : null, _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate font-medium", children: entry.label }), _jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: entry.description ?? entry.tabLabel })] })] }, entry.id));
208
+ })) })) : (_jsx("nav", { "aria-label": ariaLabel, role: "tablist", className: "flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible", children: tabs.map((tab) => {
209
+ const Icon = tab.icon;
210
+ const selected = tab.id === selectedTab?.id;
211
+ return (_jsxs("button", { type: "button", role: "tab", "aria-selected": selected, "aria-controls": `settings-tabpanel-${tab.id}`, id: `settings-tab-${tab.id}`, onClick: () => {
212
+ changeTab(tab.id);
213
+ if (!isControlled)
214
+ updateHashForTab(tab.id);
215
+ }, className: cn("flex min-h-9 shrink-0 items-center gap-2 rounded-md px-3 py-2 text-start text-sm font-medium transition-colors sm:w-full", selected
216
+ ? "bg-accent text-foreground"
217
+ : "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: [Icon ? (_jsx(Icon, { className: cn("size-4 shrink-0", selected ? "text-foreground" : "text-muted-foreground") })) : null, _jsx("span", { className: "truncate", children: tab.label })] }, tab.id));
218
+ }) }))] }), _jsx("div", { id: `settings-tabpanel-${selectedTab?.id ?? "general"}`, role: "tabpanel", "aria-labelledby": `settings-tab-${selectedTab?.id ?? "general"}`, className: cn("min-h-0 min-w-0 flex-1 overflow-y-auto p-4 sm:p-6", contentClassName), children: selectedTab?.content })] }));
107
219
  }
108
220
  //# sourceMappingURL=SettingsTabsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsTabsPage.js","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconHistory, IconSettings, IconUsers } from \"@tabler/icons-react\";\nimport {\n useEffect,\n useMemo,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"../utils.js\";\n\ntype SettingsTabIcon = ComponentType<{ className?: string }>;\n\nexport interface SettingsTabItem {\n id: string;\n label: string;\n icon?: SettingsTabIcon;\n content: ReactNode;\n}\n\nexport interface SettingsTabsPageProps {\n general: ReactNode;\n team?: ReactNode;\n whatsNew?: ReactNode;\n extraTabs?: SettingsTabItem[];\n generalLabel?: string;\n teamLabel?: string;\n whatsNewLabel?: string;\n ariaLabel?: string;\n defaultTab?: string;\n className?: string;\n navClassName?: string;\n contentClassName?: string;\n}\n\nfunction normalizeTabId(value?: string | null): string | null {\n const normalized = value\n ?.replace(/^#/, \"\")\n .trim()\n .toLowerCase()\n .replace(/['\"]/g, \"\")\n .replace(/[\\s_]+/g, \"-\");\n if (!normalized) return null;\n if (\n normalized === \"whats-new\" ||\n normalized === \"what-s-new\" ||\n normalized === \"changelog\" ||\n normalized === \"updates\"\n ) {\n return \"whats-new\";\n }\n if (normalized === \"workspace\" || normalized === \"workspace-settings\") {\n return \"workspace\";\n }\n if (normalized === \"organization\" || normalized === \"org\") {\n return \"team\";\n }\n return normalized;\n}\n\nfunction activeTabFromHash(\n tabs: SettingsTabItem[],\n defaultTab: string,\n): string {\n if (typeof window === \"undefined\") return defaultTab;\n const fromHash = normalizeTabId(window.location.hash);\n if (fromHash && tabs.some((tab) => tab.id === fromHash)) return fromHash;\n return defaultTab;\n}\n\nfunction updateHashForTab(tabId: string) {\n if (typeof window === \"undefined\") return;\n const { pathname, search } = window.location;\n const hash = tabId === \"general\" ? \"\" : `#${encodeURIComponent(tabId)}`;\n window.history.pushState(null, \"\", `${pathname}${search}${hash}`);\n}\n\nexport function SettingsTabsPage({\n general,\n team,\n whatsNew,\n extraTabs = [],\n generalLabel = \"General\",\n teamLabel = \"Team\",\n whatsNewLabel = \"What's new\",\n ariaLabel = \"Settings sections\",\n defaultTab = \"general\",\n className,\n navClassName,\n contentClassName,\n}: SettingsTabsPageProps) {\n const tabs = useMemo<SettingsTabItem[]>(() => {\n const next: SettingsTabItem[] = [\n {\n id: \"general\",\n label: generalLabel,\n icon: IconSettings,\n content: general,\n },\n ];\n next.push(...extraTabs);\n if (team) {\n next.push({\n id: \"team\",\n label: teamLabel,\n icon: IconUsers,\n content: team,\n });\n }\n if (whatsNew) {\n next.push({\n id: \"whats-new\",\n label: whatsNewLabel,\n icon: IconHistory,\n content: whatsNew,\n });\n }\n return next;\n }, [\n extraTabs,\n general,\n generalLabel,\n team,\n teamLabel,\n whatsNew,\n whatsNewLabel,\n ]);\n\n const fallbackTab = tabs.some((tab) => tab.id === defaultTab)\n ? defaultTab\n : (tabs[0]?.id ?? \"general\");\n const [activeTab, setActiveTab] = useState(() =>\n activeTabFromHash(tabs, fallbackTab),\n );\n\n useEffect(() => {\n if (tabs.some((tab) => tab.id === activeTab)) return;\n setActiveTab(fallbackTab);\n }, [activeTab, fallbackTab, tabs]);\n\n useEffect(() => {\n const handleHashChange = () => {\n setActiveTab(activeTabFromHash(tabs, fallbackTab));\n };\n window.addEventListener(\"hashchange\", handleHashChange);\n return () => window.removeEventListener(\"hashchange\", handleHashChange);\n }, [fallbackTab, tabs]);\n\n const selectedTab = tabs.find((tab) => tab.id === activeTab) ?? tabs[0];\n\n return (\n <div\n className={cn(\n \"flex min-h-full w-full flex-col overflow-hidden bg-background sm:flex-row\",\n className,\n )}\n >\n <nav\n aria-label={ariaLabel}\n role=\"tablist\"\n className={cn(\n \"flex shrink-0 gap-1 overflow-x-auto border-b border-border/50 bg-muted/30 p-2 sm:w-48 sm:flex-col sm:overflow-x-visible sm:border-b-0 sm:border-e\",\n navClassName,\n )}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n const selected = tab.id === selectedTab?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={`settings-tabpanel-${tab.id}`}\n id={`settings-tab-${tab.id}`}\n onClick={() => {\n setActiveTab(tab.id);\n updateHashForTab(tab.id);\n }}\n className={cn(\n \"flex min-h-9 shrink-0 items-center gap-2 rounded-md px-3 py-2 text-start text-sm font-medium transition-colors sm:w-full\",\n selected\n ? \"bg-background text-foreground shadow-sm ring-1 ring-border/60\"\n : \"text-muted-foreground hover:bg-accent/60 hover:text-foreground\",\n )}\n >\n {Icon ? (\n <Icon\n className={cn(\n \"size-4 shrink-0\",\n selected ? \"text-foreground\" : \"text-muted-foreground\",\n )}\n />\n ) : null}\n <span className=\"truncate\">{tab.label}</span>\n </button>\n );\n })}\n </nav>\n <div\n id={`settings-tabpanel-${selectedTab?.id ?? \"general\"}`}\n role=\"tabpanel\"\n aria-labelledby={`settings-tab-${selectedTab?.id ?? \"general\"}`}\n className={cn(\n \"min-w-0 flex-1 overflow-y-auto p-4 sm:p-6\",\n contentClassName,\n )}\n >\n {selectedTab?.content}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"SettingsTabsPage.js","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconHistory,\n IconSearch,\n IconSettings,\n IconUsers,\n IconX,\n} from \"@tabler/icons-react\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"../utils.js\";\n\ntype SettingsTabIcon = ComponentType<{ className?: string }>;\n\n/**\n * A single deep-link target inside settings that the settings search can jump\n * to. Entries usually map to a section within a tab (via a `hash`/anchor id),\n * making individual controls discoverable without hunting through every tab.\n */\nexport interface SettingsSearchEntry {\n /** Stable unique id for the entry. */\n id: string;\n /** Primary label shown in the search results. */\n label: string;\n /** Extra space-separated terms to match against (synonyms, provider names). */\n keywords?: string;\n /** Optional secondary description shown under the label. */\n description?: string;\n /** Tab to activate when the entry is picked. Defaults to the owning tab. */\n tabId?: string;\n /**\n * Optional section id / DOM element id to open + scroll to after switching\n * tabs. Handled by the inner panels' own hash listeners.\n */\n hash?: string;\n /** Optional icon override; defaults to the owning tab's icon. */\n icon?: SettingsTabIcon;\n}\n\nexport interface SettingsTabItem {\n id: string;\n label: string;\n icon?: SettingsTabIcon;\n content: ReactNode;\n /** Extra space-separated terms so this tab is findable via search. */\n keywords?: string;\n /** Deep-link entries within this tab for the settings search. */\n searchEntries?: SettingsSearchEntry[];\n}\n\nexport interface SettingsTabsPageProps {\n general: ReactNode;\n team?: ReactNode;\n whatsNew?: ReactNode;\n extraTabs?: SettingsTabItem[];\n generalLabel?: string;\n teamLabel?: string;\n whatsNewLabel?: string;\n ariaLabel?: string;\n defaultTab?: string;\n className?: string;\n navClassName?: string;\n contentClassName?: string;\n /** Whether to render the settings search box. Defaults to true. */\n enableSearch?: boolean;\n /** Placeholder for the settings search box. */\n searchPlaceholder?: string;\n /** Extra global search entries (e.g. anchors within the General tab). */\n searchEntries?: SettingsSearchEntry[];\n /** Deep-link entries for the General tab. */\n generalSearchEntries?: SettingsSearchEntry[];\n /**\n * Controlled active tab id. When provided, the parent owns tab state (and is\n * responsible for URL/app-state sync); the component skips its own hash-based\n * tab tracking. Leave undefined for the default uncontrolled, hash-driven\n * behavior.\n */\n value?: string;\n /**\n * Called whenever the active tab changes via a tab click or a search result\n * selection. Fires in both controlled and uncontrolled modes.\n */\n onValueChange?: (tabId: string) => void;\n}\n\ninterface ResolvedSearchEntry extends SettingsSearchEntry {\n tabId: string;\n tabLabel: string;\n icon?: SettingsTabIcon;\n haystack: string;\n}\n\nfunction normalizeTabId(value?: string | null): string | null {\n const normalized = value\n ?.replace(/^#/, \"\")\n .trim()\n .toLowerCase()\n .replace(/['\"]/g, \"\")\n .replace(/[\\s_]+/g, \"-\");\n if (!normalized) return null;\n if (\n normalized === \"whats-new\" ||\n normalized === \"what-s-new\" ||\n normalized === \"changelog\" ||\n normalized === \"updates\"\n ) {\n return \"whats-new\";\n }\n if (normalized === \"workspace\" || normalized === \"workspace-settings\") {\n return \"workspace\";\n }\n if (normalized === \"organization\" || normalized === \"org\") {\n return \"team\";\n }\n return normalized;\n}\n\nfunction activeTabFromHash(\n tabs: SettingsTabItem[],\n defaultTab: string,\n): string {\n if (typeof window === \"undefined\") return defaultTab;\n const fromHash = normalizeTabId(window.location.hash);\n if (fromHash && tabs.some((tab) => tab.id === fromHash)) return fromHash;\n return defaultTab;\n}\n\nfunction updateHashForTab(tabId: string) {\n if (typeof window === \"undefined\") return;\n const { pathname, search } = window.location;\n const hash = tabId === \"general\" ? \"\" : `#${encodeURIComponent(tabId)}`;\n window.history.pushState(null, \"\", `${pathname}${search}${hash}`);\n}\n\nexport function SettingsTabsPage({\n general,\n team,\n whatsNew,\n extraTabs = [],\n generalLabel = \"General\",\n teamLabel = \"Team\",\n whatsNewLabel = \"What's new\",\n ariaLabel = \"Settings sections\",\n defaultTab = \"general\",\n className,\n navClassName,\n contentClassName,\n enableSearch = true,\n searchPlaceholder = \"Search settings\",\n searchEntries,\n generalSearchEntries,\n value,\n onValueChange,\n}: SettingsTabsPageProps) {\n const tabs = useMemo<SettingsTabItem[]>(() => {\n const next: SettingsTabItem[] = [\n {\n id: \"general\",\n label: generalLabel,\n icon: IconSettings,\n content: general,\n searchEntries: generalSearchEntries,\n },\n ];\n next.push(...extraTabs);\n if (team) {\n next.push({\n id: \"team\",\n label: teamLabel,\n icon: IconUsers,\n content: team,\n });\n }\n if (whatsNew) {\n next.push({\n id: \"whats-new\",\n label: whatsNewLabel,\n icon: IconHistory,\n content: whatsNew,\n });\n }\n return next;\n }, [\n extraTabs,\n general,\n generalLabel,\n generalSearchEntries,\n team,\n teamLabel,\n whatsNew,\n whatsNewLabel,\n ]);\n\n const fallbackTab = tabs.some((tab) => tab.id === defaultTab)\n ? defaultTab\n : (tabs[0]?.id ?? \"general\");\n const isControlled = value !== undefined;\n const [internalTab, setInternalTab] = useState(() =>\n activeTabFromHash(tabs, fallbackTab),\n );\n const activeTab = isControlled ? value : internalTab;\n const [query, setQuery] = useState(\"\");\n\n const changeTab = useCallback(\n (tabId: string) => {\n if (!isControlled) setInternalTab(tabId);\n onValueChange?.(tabId);\n },\n [isControlled, onValueChange],\n );\n\n useEffect(() => {\n // In controlled mode the parent owns (and validates) the active tab.\n if (isControlled) return;\n if (tabs.some((tab) => tab.id === internalTab)) return;\n setInternalTab(fallbackTab);\n }, [fallbackTab, internalTab, isControlled, tabs]);\n\n useEffect(() => {\n // Hash-driven tab tracking only applies to the uncontrolled mode. Only\n // react to hashes that name a top-level tab. Section-level hashes\n // (e.g. `#llm`, `#secrets`) are consumed by the inner panels, so leave\n // the active tab untouched to avoid bouncing back to General.\n if (isControlled) return;\n const handleHashChange = () => {\n const fromHash = normalizeTabId(window.location.hash);\n if (fromHash && tabs.some((tab) => tab.id === fromHash)) {\n setInternalTab(fromHash);\n }\n };\n window.addEventListener(\"hashchange\", handleHashChange);\n return () => window.removeEventListener(\"hashchange\", handleHashChange);\n }, [isControlled, tabs]);\n\n const selectedTab = tabs.find((tab) => tab.id === activeTab) ?? tabs[0];\n\n // Flatten tab + deep-link entries into one searchable index.\n const searchIndex = useMemo<ResolvedSearchEntry[]>(() => {\n const entries: ResolvedSearchEntry[] = [];\n const seen = new Set<string>();\n const add = (entry: ResolvedSearchEntry) => {\n if (seen.has(entry.id)) return;\n seen.add(entry.id);\n entries.push(entry);\n };\n for (const tab of tabs) {\n add({\n id: `tab:${tab.id}`,\n label: tab.label,\n keywords: tab.keywords,\n tabId: tab.id,\n tabLabel: tab.label,\n icon: tab.icon,\n haystack: `${tab.label} ${tab.keywords ?? \"\"}`.toLowerCase(),\n });\n for (const sub of tab.searchEntries ?? []) {\n add({\n ...sub,\n tabId: sub.tabId ?? tab.id,\n tabLabel: tab.label,\n icon: sub.icon ?? tab.icon,\n haystack:\n `${sub.label} ${sub.keywords ?? \"\"} ${sub.description ?? \"\"} ${tab.label}`.toLowerCase(),\n });\n }\n }\n for (const sub of searchEntries ?? []) {\n const owner = tabs.find((tab) => tab.id === (sub.tabId ?? \"general\"));\n add({\n ...sub,\n tabId: sub.tabId ?? \"general\",\n tabLabel: owner?.label ?? sub.tabId ?? \"General\",\n icon: sub.icon ?? owner?.icon,\n haystack:\n `${sub.label} ${sub.keywords ?? \"\"} ${sub.description ?? \"\"} ${owner?.label ?? \"\"}`.toLowerCase(),\n });\n }\n return entries;\n }, [searchEntries, tabs]);\n\n const trimmedQuery = query.trim().toLowerCase();\n const results = useMemo<ResolvedSearchEntry[]>(() => {\n if (!trimmedQuery) return [];\n const terms = trimmedQuery.split(/\\s+/).filter(Boolean);\n return searchIndex\n .filter((entry) => terms.every((term) => entry.haystack.includes(term)))\n .sort((a, b) => {\n const aStarts = a.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;\n const bStarts = b.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;\n if (aStarts !== bStarts) return aStarts - bStarts;\n return a.label.localeCompare(b.label);\n });\n }, [searchIndex, trimmedQuery]);\n\n const selectEntry = (entry: ResolvedSearchEntry) => {\n changeTab(entry.tabId);\n setQuery(\"\");\n if (typeof window === \"undefined\") return;\n const hash = entry.hash?.replace(/^#/, \"\");\n if (hash) {\n const { pathname, search } = window.location;\n window.history.pushState(null, \"\", `${pathname}${search}#${hash}`);\n // Let the inner panels open + scroll to their section.\n window.dispatchEvent(new Event(\"hashchange\"));\n window.requestAnimationFrame(() => {\n document\n .getElementById(hash)\n ?.scrollIntoView({ block: \"start\", behavior: \"smooth\" });\n });\n } else if (!isControlled) {\n updateHashForTab(entry.tabId);\n }\n };\n\n const searching = enableSearch && trimmedQuery.length > 0;\n\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full flex-col overflow-hidden bg-background sm:flex-row\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex shrink-0 flex-col gap-2 border-b border-border bg-background p-2 sm:min-h-0 sm:w-56 sm:overflow-y-auto sm:border-b-0 sm:border-e sm:p-3\",\n navClassName,\n )}\n >\n {enableSearch ? (\n <div className=\"relative sm:mb-1\">\n <IconSearch className=\"pointer-events-none absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Escape\") setQuery(\"\");\n if (event.key === \"Enter\" && results[0]) {\n event.preventDefault();\n selectEntry(results[0]);\n }\n }}\n placeholder={searchPlaceholder}\n aria-label={searchPlaceholder}\n className=\"h-8 w-full rounded-md border border-border bg-background ps-8 pe-7 text-[13px] text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-foreground/30 focus:ring-2 focus:ring-accent/40\"\n />\n {query ? (\n <button\n type=\"button\"\n onClick={() => setQuery(\"\")}\n aria-label=\"Clear search\"\n className=\"absolute end-1.5 top-1/2 flex size-5 -translate-y-1/2 items-center justify-center rounded text-muted-foreground hover:bg-accent/60 hover:text-foreground\"\n >\n <IconX className=\"size-3.5\" />\n </button>\n ) : null}\n </div>\n ) : null}\n\n {searching ? (\n <div\n role=\"listbox\"\n aria-label=\"Settings search results\"\n className=\"flex flex-col gap-0.5\"\n >\n {results.length === 0 ? (\n <p className=\"px-2 py-6 text-center text-[12px] text-muted-foreground\">\n No matching settings\n </p>\n ) : (\n results.map((entry) => {\n const Icon = entry.icon;\n return (\n <button\n key={entry.id}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n onClick={() => selectEntry(entry)}\n className=\"flex items-start gap-2 rounded-md px-2.5 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent/60\"\n >\n {Icon ? (\n <Icon className=\"mt-0.5 size-4 shrink-0 text-muted-foreground\" />\n ) : null}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate font-medium\">\n {entry.label}\n </span>\n <span className=\"truncate text-[11px] text-muted-foreground\">\n {entry.description ?? entry.tabLabel}\n </span>\n </span>\n </button>\n );\n })\n )}\n </div>\n ) : (\n <nav\n aria-label={ariaLabel}\n role=\"tablist\"\n className=\"flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible\"\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n const selected = tab.id === selectedTab?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={`settings-tabpanel-${tab.id}`}\n id={`settings-tab-${tab.id}`}\n onClick={() => {\n changeTab(tab.id);\n if (!isControlled) updateHashForTab(tab.id);\n }}\n className={cn(\n \"flex min-h-9 shrink-0 items-center gap-2 rounded-md px-3 py-2 text-start text-sm font-medium transition-colors sm:w-full\",\n selected\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground hover:bg-accent/50 hover:text-foreground\",\n )}\n >\n {Icon ? (\n <Icon\n className={cn(\n \"size-4 shrink-0\",\n selected ? \"text-foreground\" : \"text-muted-foreground\",\n )}\n />\n ) : null}\n <span className=\"truncate\">{tab.label}</span>\n </button>\n );\n })}\n </nav>\n )}\n </div>\n <div\n id={`settings-tabpanel-${selectedTab?.id ?? \"general\"}`}\n role=\"tabpanel\"\n aria-labelledby={`settings-tab-${selectedTab?.id ?? \"general\"}`}\n className={cn(\n \"min-h-0 min-w-0 flex-1 overflow-y-auto p-4 sm:p-6\",\n contentClassName,\n )}\n >\n {selectedTab?.content}\n </div>\n </div>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  export { SettingsPanel, useAgentSettingsTabs, type SettingsPanelProps, } from "./SettingsPanel.js";
2
- export { SettingsTabsPage, type SettingsTabItem, type SettingsTabsPageProps, } from "./SettingsTabsPage.js";
2
+ export { SettingsTabsPage, type SettingsSearchEntry, type SettingsTabItem, type SettingsTabsPageProps, } from "./SettingsTabsPage.js";
3
3
  export { openBuilderConnectPopup, useBuilderConnectFlow, useBuilderStatus, withBuilderConnectTrackingParams, type BuilderConnectFlow, type BuilderConnectFlowOptions, type BuilderConnectStartOptions, type BuilderStatus, type OpenBuilderConnectPopupOptions, } from "./useBuilderStatus.js";
4
4
  export { SecretsSection, type SecretsSectionProps } from "./SecretsSection.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,EAChC,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,KAAK,8BAA8B,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,EAChC,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,KAAK,8BAA8B,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,GAMjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAA4B,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n SettingsPanel,\n useAgentSettingsTabs,\n type SettingsPanelProps,\n} from \"./SettingsPanel.js\";\nexport {\n SettingsTabsPage,\n type SettingsTabItem,\n type SettingsTabsPageProps,\n} from \"./SettingsTabsPage.js\";\nexport {\n openBuilderConnectPopup,\n useBuilderConnectFlow,\n useBuilderStatus,\n withBuilderConnectTrackingParams,\n type BuilderConnectFlow,\n type BuilderConnectFlowOptions,\n type BuilderConnectStartOptions,\n type BuilderStatus,\n type OpenBuilderConnectPopupOptions,\n} from \"./useBuilderStatus.js\";\nexport { SecretsSection, type SecretsSectionProps } from \"./SecretsSection.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,GAIjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,GAMjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAA4B,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n SettingsPanel,\n useAgentSettingsTabs,\n type SettingsPanelProps,\n} from \"./SettingsPanel.js\";\nexport {\n SettingsTabsPage,\n type SettingsSearchEntry,\n type SettingsTabItem,\n type SettingsTabsPageProps,\n} from \"./SettingsTabsPage.js\";\nexport {\n openBuilderConnectPopup,\n useBuilderConnectFlow,\n useBuilderStatus,\n withBuilderConnectTrackingParams,\n type BuilderConnectFlow,\n type BuilderConnectFlowOptions,\n type BuilderConnectStartOptions,\n type BuilderStatus,\n type OpenBuilderConnectPopupOptions,\n} from \"./useBuilderStatus.js\";\nexport { SecretsSection, type SecretsSectionProps } from \"./SecretsSection.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"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"}
@@ -522,11 +522,7 @@ function SharePanel(props) {
522
522
  setShareError(null);
523
523
  }, onSubmit: handleAdd, placeholder: policy.requireOrgMemberForUserShares
524
524
  ? "Add people from your organization"
525
- : "Add people by email", suggestions: memberSuggestions, search: memberSearch }), _jsx(RoleSelect, { value: role, onChange: setRole })] }), shareError ? (_jsx("div", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, hasInviteEmail ? (_jsxs("label", { className: "inline-flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx("input", { type: "checkbox", checked: notifyPeople, onChange: (e) => setNotifyPeople(e.target.checked), className: "h-4 w-4 rounded border-input accent-primary" }), "Notify people"] })) : null] })) : null, _jsx("div", { className: "mb-2 text-sm font-semibold", children: peopleAccessLabel }), _jsxs("ul", { className: "mb-4 flex flex-col gap-1 list-none p-0 m-0", children: [data?.ownerEmail ? (_jsxs("li", { className: "flex items-center gap-3 px-1 py-1.5 text-sm", children: [_jsx(Avatar, { label: displayName(data.ownerEmail, knownMembers) }), _jsx("span", { className: "flex-1 min-w-0 truncate", children: displayName(data.ownerEmail, knownMembers) }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Owner" })] })) : null, shares.map((s) => (_jsxs("li", { className: cn("flex items-center gap-3 px-1 py-1.5 text-sm", inFlight.has(keyOf(s)) && "opacity-60"), children: [_jsx(Avatar, { label: s.principalType === "org"
526
- ? s.principalId
527
- : displayName(s.principalId, knownMembers), org: s.principalType === "org" }), _jsx("span", { className: "flex-1 min-w-0 truncate", children: s.principalType === "org"
528
- ? s.principalId
529
- : displayName(s.principalId, knownMembers) }), canManage ? (_jsx(RoleSelect, { value: s.role, onChange: (r) => handleChangeRole(s, r), disabled: inFlight.has(keyOf(s)), plain: true })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: cap(s.role) })), canManage ? (_jsx("button", { type: "button", "aria-label": "Remove", onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: "No one has access yet." })) : null] }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: generalAccessLabel }), _jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage, visibilityCopy: props.visibilityCopy, allowPublic: policy.allowPublic }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: meta.description }), visibility === "org" && props.hideInSearchControl ? (_jsx(AdvancedAccessPopover, { control: props.hideInSearchControl, canManage: canManage, onToggle: handleHideInSearch })) : null] })] })] }), shareError && !canManage ? (_jsx("div", { role: "alert", className: "mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, props.accessNote ? (_jsx("div", { className: "mb-4 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground", children: props.accessNote })) : null, showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null, props.shareFooterContent, showDoneButton ? (_jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { type: "button", onClick: handleDone, className: BUTTON_PRIMARY_SM, children: "Done" }) })) : null] }));
525
+ : "Add people by email", suggestions: memberSuggestions, search: memberSearch }), _jsx(RoleSelect, { value: role, onChange: setRole })] }), shareError ? (_jsx("div", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, hasInviteEmail ? (_jsxs("label", { className: "inline-flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx("input", { type: "checkbox", checked: notifyPeople, onChange: (e) => setNotifyPeople(e.target.checked), className: "h-4 w-4 rounded border-input accent-primary" }), "Notify people"] })) : null] })) : null, _jsx("div", { className: "mb-2 text-sm font-semibold", children: peopleAccessLabel }), _jsxs("ul", { className: "mb-4 flex flex-col gap-1 list-none p-0 m-0", children: [data?.ownerEmail ? (_jsxs("li", { className: "flex items-center gap-3 px-1 py-1.5 text-sm", children: [_jsx(Avatar, { label: displayName(data.ownerEmail, knownMembers) }), _jsx("span", { className: "flex-1 min-w-0 truncate", children: displayName(data.ownerEmail, knownMembers) }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Owner" })] })) : null, shares.map((s) => (_jsxs("li", { className: cn("flex items-center gap-3 px-1 py-1.5 text-sm", inFlight.has(keyOf(s)) && "opacity-60"), children: [_jsx(Avatar, { label: principalLabel(s, knownMembers), org: s.principalType === "org" }), _jsx("span", { className: "flex-1 min-w-0 truncate", children: principalLabel(s, knownMembers) }), canManage ? (_jsx(RoleSelect, { value: s.role, onChange: (r) => handleChangeRole(s, r), disabled: inFlight.has(keyOf(s)), plain: true })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: cap(s.role) })), canManage ? (_jsx("button", { type: "button", "aria-label": "Remove", onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: "No one has access yet." })) : null] }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: generalAccessLabel }), _jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage, visibilityCopy: props.visibilityCopy, allowPublic: policy.allowPublic }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: meta.description }), visibility === "org" && props.hideInSearchControl ? (_jsx(AdvancedAccessPopover, { control: props.hideInSearchControl, canManage: canManage, onToggle: handleHideInSearch })) : null] })] })] }), shareError && !canManage ? (_jsx("div", { role: "alert", className: "mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, props.accessNote ? (_jsx("div", { className: "mb-4 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground", children: props.accessNote })) : null, showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null, props.shareFooterContent, showDoneButton ? (_jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { type: "button", onClick: handleDone, className: BUTTON_PRIMARY_SM, children: "Done" }) })) : null] }));
530
526
  if (!hasTabs)
531
527
  return sharePanel;
532
528
  const tabs = [
@@ -756,10 +752,19 @@ function initials(s) {
756
752
  const name = s.split("@")[0] ?? s;
757
753
  return (name[0] ?? "?").toUpperCase();
758
754
  }
759
- function displayName(email, members) {
760
- const match = members.find((m) => m.email === email);
755
+ function principalLabel(share, members) {
756
+ const serverLabel = share.displayName?.trim();
757
+ if (serverLabel)
758
+ return serverLabel;
759
+ if (share.principalType === "org")
760
+ return "Organization";
761
+ return displayName(share.principalId, members);
762
+ }
763
+ function displayName(emailOrId, members) {
764
+ const normalized = emailOrId.trim().toLowerCase();
765
+ const match = members.find((m) => m.email.toLowerCase() === normalized);
761
766
  if (match?.name && match.name.trim())
762
767
  return match.name;
763
- return email;
768
+ return normalized.includes("@") ? emailOrId : "Unknown person";
764
769
  }
765
770
  //# sourceMappingURL=ShareButton.js.map