@agent-native/core 0.141.6 → 0.141.7

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 (210) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
  3. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
  4. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
  5. package/corpus/templates/analytics/AGENTS.md +2 -2
  6. package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
  7. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
  8. package/corpus/templates/analytics/actions/navigate.ts +1 -1
  9. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -2
  10. package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
  11. package/corpus/templates/analytics/actions/view-screen.ts +0 -20
  12. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  13. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
  14. package/corpus/templates/analytics/app/i18n-data.ts +2 -90
  15. package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
  16. package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
  17. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
  18. package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
  19. package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
  20. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  21. package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
  22. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
  23. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
  24. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
  25. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1058 -0
  26. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
  27. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
  28. package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
  29. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -4
  30. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +8 -6
  31. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
  32. package/corpus/templates/assets/AGENTS.md +1 -0
  33. package/corpus/templates/assets/actions/_helpers.ts +12 -0
  34. package/corpus/templates/assets/actions/generate-image.ts +9 -3
  35. package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
  36. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  37. package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
  38. package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
  39. package/corpus/templates/assets/app/routes/settings.tsx +5 -0
  40. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  41. package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
  42. package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
  43. package/corpus/templates/assets/server/lib/generation.ts +58 -0
  44. package/corpus/templates/assets/shared/api.ts +12 -0
  45. package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
  46. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  47. package/corpus/templates/brain/app/routes.ts +1 -1
  48. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  49. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
  50. package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
  51. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  52. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  53. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  54. package/corpus/templates/chat/app/root.tsx +1 -1
  55. package/corpus/templates/chat/app/routes/agent.tsx +7 -7
  56. package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
  57. package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
  58. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  59. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  60. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  61. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
  62. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
  63. package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
  64. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
  65. package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
  66. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  67. package/corpus/templates/content/e2e/global-setup.ts +1 -1
  68. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
  69. package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
  70. package/corpus/templates/design/actions/import-from-url.ts +6 -5
  71. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
  72. package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
  73. package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
  74. package/corpus/templates/design/app/routes/team.tsx +1 -1
  75. package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
  76. package/corpus/templates/design/e2e/global-setup.ts +1 -1
  77. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  78. package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
  79. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  80. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
  81. package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
  82. package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
  83. package/corpus/templates/factory/app/routes/team.tsx +1 -1
  84. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
  85. package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
  86. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  87. package/corpus/templates/forms/shared/navigation.ts +1 -1
  88. package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
  89. package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
  90. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  91. package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
  92. package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
  93. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  94. package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
  95. package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
  96. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  97. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +3 -1
  98. package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
  99. package/corpus/templates/slides/actions/import-from-url.ts +6 -6
  100. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  101. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +3 -0
  102. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +9 -3
  103. package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
  104. package/corpus/templates/slides/app/global.css +6 -0
  105. package/corpus/templates/slides/app/lib/create-deck-generation.ts +9 -5
  106. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
  107. package/corpus/templates/slides/app/pages/Index.tsx +16 -5
  108. package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
  109. package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
  110. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  111. package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
  112. package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
  113. package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
  114. package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
  115. package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
  116. package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
  117. package/dist/agent/engine/ai-sdk-engine.js +49 -3
  118. package/dist/agent/production-agent.d.ts +1 -0
  119. package/dist/agent/production-agent.js +8 -0
  120. package/dist/agent/types.d.ts +7 -0
  121. package/dist/client/agent-chat-adapter.d.ts +1 -1
  122. package/dist/client/agent-chat-adapter.js +30 -3
  123. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
  124. package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
  125. package/dist/client/chat/run-recovery.js +5 -1
  126. package/dist/client/embed-auth.js +6 -2
  127. package/dist/client/error-format.js +12 -0
  128. package/dist/client/integrations/IntegrationsPanel.js +40 -6
  129. package/dist/client/org/OrgSwitcher.js +2 -2
  130. package/dist/client/org/TeamPage.js +92 -72
  131. package/dist/client/require-session.d.ts +1 -1
  132. package/dist/client/require-session.js +3 -3
  133. package/dist/client/resources/use-mcp-servers.d.ts +5 -0
  134. package/dist/client/resources/use-mcp-servers.js +36 -0
  135. package/dist/client/settings/AccountSettingsCard.js +40 -35
  136. package/dist/client/settings/AutomationsSection.js +1 -1
  137. package/dist/client/settings/DemoModeSection.d.ts +3 -1
  138. package/dist/client/settings/DemoModeSection.js +4 -1
  139. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  140. package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
  141. package/dist/client/settings/SchedulingTimezoneField.js +9 -5
  142. package/dist/client/settings/SettingsPanel.d.ts +4 -1
  143. package/dist/client/settings/SettingsPanel.js +21 -21
  144. package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
  145. package/dist/client/settings/SettingsTabsPage.js +98 -45
  146. package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
  147. package/dist/client/settings/useSettingsPanelController.js +47 -8
  148. package/dist/collab/struct-routes.d.ts +1 -1
  149. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  150. package/dist/ingestion/website.d.ts +30 -0
  151. package/dist/localization/default-messages.d.ts +5 -0
  152. package/dist/localization/default-messages.js +5 -0
  153. package/dist/mcp-client/oauth-routes.js +1 -1
  154. package/dist/mcp-client/routes.d.ts +1 -0
  155. package/dist/mcp-client/routes.js +49 -0
  156. package/dist/navigation/index.js +16 -5
  157. package/dist/observability/routes.d.ts +5 -5
  158. package/dist/progress/routes.d.ts +1 -1
  159. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  160. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  161. package/dist/resources/handlers.d.ts +1 -1
  162. package/dist/scripts/call-agent.js +11 -0
  163. package/dist/secrets/routes.d.ts +3 -3
  164. package/dist/server/auth.js +9 -7
  165. package/dist/server/identity-sso.js +2 -1
  166. package/dist/server/onboarding-html.js +57 -34
  167. package/dist/server/realtime-token.d.ts +1 -1
  168. package/dist/server/transcribe-voice.d.ts +1 -1
  169. package/dist/server/workspace-provider-oauth.js +1 -1
  170. package/dist/setup-connections/onboarding.js +1 -1
  171. package/dist/shared/index.d.ts +1 -1
  172. package/dist/shared/index.js +1 -1
  173. package/dist/shared/sign-in-journey.d.ts +5 -2
  174. package/dist/shared/sign-in-journey.js +10 -4
  175. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  176. package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  177. package/dist/templates/chat/app/root.tsx +1 -1
  178. package/dist/templates/chat/app/routes/agent.tsx +7 -7
  179. package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
  180. package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
  181. package/dist/templates/chat/app/routes/team.tsx +1 -1
  182. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  183. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  184. package/docs/content/authentication.mdx +4 -5
  185. package/docs/content/template-analytics-developers.mdx +1 -1
  186. package/docs/content/template-calendar-developers.mdx +1 -1
  187. package/docs/content/template-chat-developers.mdx +2 -2
  188. package/docs/content/template-content-developers.mdx +1 -1
  189. package/docs/content/template-mail-developers.mdx +1 -1
  190. package/docs/content/template-plan-developers.mdx +1 -1
  191. package/docs/content/toolkit-command-navigation.mdx +6 -6
  192. package/docs/content/toolkit-org-team.mdx +1 -1
  193. package/docs/content/toolkit-settings.mdx +8 -8
  194. package/docs/content/toolkit-setup-connections.mdx +1 -1
  195. package/package.json +1 -1
  196. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  197. package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  198. package/src/templates/chat/app/root.tsx +1 -1
  199. package/src/templates/chat/app/routes/agent.tsx +7 -7
  200. package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
  201. package/src/templates/chat/app/routes/settings.$.tsx +1 -0
  202. package/src/templates/chat/app/routes/team.tsx +1 -1
  203. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  204. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  205. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
  206. package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
  207. package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
  208. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
  209. package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
  210. package/src/templates/default/actions/navigate.spec.ts +0 -53
@@ -1,8 +1,9 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Tabs, useDesignSystem } from "@agent-native/toolkit/design-system";
3
- import { IconArrowLeft, IconArrowUpRight, IconHistory, IconSearch, IconSettings, IconUserCircle, IconUsers, IconX, } from "@tabler/icons-react";
3
+ import { IconArrowUpRight, IconHistory, IconSearch, IconSettings, IconUserCircle, IconUsers, IconX, } from "@tabler/icons-react";
4
4
  import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
5
5
  import { Link } from "react-router";
6
+ import { buildSettingsRoute } from "../../navigation/index.js";
6
7
  import { cn } from "../utils.js";
7
8
  function normalizeTabId(value) {
8
9
  let decoded = value?.replace(/^#/, "").trim() ?? "";
@@ -61,17 +62,52 @@ function resolveTabId(tabs, value) {
61
62
  }
62
63
  return null;
63
64
  }
64
- function activeTabFromHash(tabs, defaultTab) {
65
+ function activeTabFromLocation(tabs, defaultTab) {
65
66
  if (typeof window === "undefined")
66
67
  return defaultTab;
68
+ const settingsPrefix = "/settings";
69
+ if (window.location.pathname === settingsPrefix) {
70
+ return resolveTabId(tabs, window.location.hash) ?? defaultTab;
71
+ }
72
+ if (window.location.pathname.startsWith(`${settingsPrefix}/`)) {
73
+ const segments = window.location.pathname
74
+ .slice(`${settingsPrefix}/`.length)
75
+ .split("/")
76
+ .filter(Boolean)
77
+ .map((segment) => {
78
+ try {
79
+ return decodeURIComponent(segment);
80
+ }
81
+ catch {
82
+ return segment;
83
+ }
84
+ });
85
+ for (let length = segments.length; length > 0; length -= 1) {
86
+ const tabId = resolveTabId(tabs, segments.slice(0, length).join(":"));
87
+ if (tabId)
88
+ return tabId;
89
+ }
90
+ }
67
91
  return resolveTabId(tabs, window.location.hash) ?? defaultTab;
68
92
  }
69
- function updateHashForTab(tabId) {
93
+ function buildSettingsEntryRoute(tabId, section) {
94
+ const normalizedSection = section?.replace(/^#/, "").trim();
95
+ if (!normalizedSection || normalizedSection === tabId) {
96
+ return buildSettingsRoute(tabId);
97
+ }
98
+ if (normalizedSection.startsWith("agent:")) {
99
+ return buildSettingsRoute(normalizedSection);
100
+ }
101
+ if (normalizedSection.startsWith(`${tabId}:`)) {
102
+ return buildSettingsRoute(normalizedSection);
103
+ }
104
+ return buildSettingsRoute(`${tabId}:${normalizedSection}`);
105
+ }
106
+ function updateRouteForTab(tabId, section) {
70
107
  if (typeof window === "undefined")
71
108
  return;
72
- const { pathname, search } = window.location;
73
- const hash = tabId === "general" ? "" : `#${tabId}`;
74
- window.history.pushState(null, "", `${pathname}${search}${hash}`);
109
+ const route = buildSettingsEntryRoute(tabId, section);
110
+ window.history.pushState(null, "", `${route}${window.location.search}`);
75
111
  }
76
112
  function isEditableElement(element) {
77
113
  if (!(element instanceof HTMLElement))
@@ -82,7 +118,7 @@ function isEditableElement(element) {
82
118
  tagName === "select" ||
83
119
  element.isContentEditable);
84
120
  }
85
- export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs = [], generalLabel = "General", accountLabel = "Account", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "integrations", className, navClassName, contentClassName, enableSearch = true, searchPlaceholder = "Search settings", searchEntries, generalSearchEntries, value, onValueChange, }) {
121
+ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs = [], generalLabel = "General", accountLabel = "Account", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "general", className, navClassName, contentClassName, enableSearch = true, searchPlaceholder = "Search settings", searchEntries, generalSearchEntries, value, onValueChange, }) {
86
122
  const rootRef = useRef(null);
87
123
  const searchInputRef = useRef(null);
88
124
  const autoFocusedSearchRef = useRef(false);
@@ -166,7 +202,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
166
202
  agent: "Agent",
167
203
  };
168
204
  const isControlled = value !== undefined;
169
- const [internalTab, setInternalTab] = useState(() => activeTabFromHash(tabs, fallbackTab));
205
+ const [internalTab, setInternalTab] = useState(() => activeTabFromLocation(tabs, fallbackTab));
170
206
  const activeTab = isControlled ? value : internalTab;
171
207
  const [query, setQuery] = useState("");
172
208
  const designSystem = useDesignSystem();
@@ -186,39 +222,55 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
186
222
  setInternalTab(fallbackTab);
187
223
  }, [fallbackTab, internalTab, isControlled, tabs]);
188
224
  useEffect(() => {
189
- // Hash-driven tab tracking only applies to the uncontrolled mode. Only
190
- // react to hashes that name a top-level tab. Section-level hashes
191
- // (e.g. `#llm`, `#secrets`) are consumed by the inner panels, so leave
192
- // the active tab untouched to avoid bouncing back to General.
193
225
  if (isControlled)
194
226
  return;
195
- const handleHashChange = () => {
196
- const fromHash = resolveTabId(tabs, window.location.hash);
197
- if (fromHash) {
198
- setInternalTab(fromHash);
199
- }
227
+ const syncLocation = () => {
228
+ const fromPath = activeTabFromLocation(tabs, fallbackTab);
229
+ if (fromPath)
230
+ setInternalTab(fromPath);
231
+ if (window.location.pathname.startsWith("/settings/"))
232
+ return;
233
+ const hashValue = window.location.hash.replace(/^#/, "");
234
+ const fromHash = resolveTabId(tabs, hashValue);
235
+ if (!fromHash || !hashValue)
236
+ return;
237
+ const isTabHash = fromHash === hashValue;
238
+ updateRouteForTab(fromHash, isTabHash ? undefined : hashValue);
239
+ };
240
+ syncLocation();
241
+ window.addEventListener("hashchange", syncLocation);
242
+ window.addEventListener("popstate", syncLocation);
243
+ return () => {
244
+ window.removeEventListener("hashchange", syncLocation);
245
+ window.removeEventListener("popstate", syncLocation);
200
246
  };
201
- window.addEventListener("hashchange", handleHashChange);
202
- return () => window.removeEventListener("hashchange", handleHashChange);
203
- }, [isControlled, tabs]);
247
+ }, [fallbackTab, isControlled, tabs]);
204
248
  useEffect(() => {
205
- // Controlled pages retain ownership of their active state, but shared
206
- // organization navigation uses a hash deep link. Report only recognized
207
- // top-level tab hashes; section hashes remain available to inner panels.
208
249
  if (!isControlled)
209
250
  return;
210
- const syncControlledHash = () => {
211
- const hash = window.location.hash;
212
- const fromHash = resolveTabId(tabs, hash);
213
- if (!fromHash || controlledHashRef.current === hash)
251
+ const syncControlledLocation = () => {
252
+ const fromPath = window.location.pathname.startsWith("/settings/")
253
+ ? activeTabFromLocation(tabs, defaultTab)
254
+ : null;
255
+ const hashValue = window.location.hash.replace(/^#/, "");
256
+ const fromHash = hashValue ? resolveTabId(tabs, hashValue) : null;
257
+ const next = fromPath ?? fromHash;
258
+ const key = `${window.location.pathname}${window.location.hash}`;
259
+ if (!next || next === value || controlledHashRef.current === key) {
260
+ controlledHashRef.current = key;
214
261
  return;
215
- controlledHashRef.current = hash;
216
- onValueChange?.(fromHash);
262
+ }
263
+ controlledHashRef.current = key;
264
+ onValueChange?.(next);
265
+ };
266
+ syncControlledLocation();
267
+ window.addEventListener("hashchange", syncControlledLocation);
268
+ window.addEventListener("popstate", syncControlledLocation);
269
+ return () => {
270
+ window.removeEventListener("hashchange", syncControlledLocation);
271
+ window.removeEventListener("popstate", syncControlledLocation);
217
272
  };
218
- syncControlledHash();
219
- window.addEventListener("hashchange", syncControlledHash);
220
- return () => window.removeEventListener("hashchange", syncControlledHash);
221
- }, [isControlled, onValueChange, tabs, value]);
273
+ }, [defaultTab, isControlled, onValueChange, tabs, value]);
222
274
  useEffect(() => {
223
275
  if (!enableSearch || autoFocusedSearchRef.current)
224
276
  return;
@@ -306,24 +358,24 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
306
358
  setQuery("");
307
359
  if (typeof window === "undefined")
308
360
  return;
309
- const hash = entry.hash?.replace(/^#/, "");
310
- if (hash) {
311
- const { pathname, search } = window.location;
312
- window.history.pushState(null, "", `${pathname}${search}#${hash}`);
361
+ const section = entry.hash?.replace(/^#/, "");
362
+ if (section) {
363
+ updateRouteForTab(entry.tabId, section);
313
364
  // Let the inner panels open + scroll to their section.
365
+ window.dispatchEvent(new Event("popstate"));
314
366
  window.dispatchEvent(new Event("hashchange"));
315
367
  window.requestAnimationFrame(() => {
316
368
  document
317
- .getElementById(hash)
369
+ .getElementById(section)
318
370
  ?.scrollIntoView({ block: "start", behavior: "smooth" });
319
371
  });
320
372
  }
321
373
  else if (!isControlled) {
322
- updateHashForTab(entry.tabId);
374
+ updateRouteForTab(entry.tabId);
323
375
  }
324
376
  };
325
377
  const searching = enableSearch && trimmedQuery.length > 0;
326
- return (_jsxs("div", { ref: rootRef, 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 bg-background p-2 sm:min-h-0 sm:w-60 sm:overflow-y-auto sm:p-4", navClassName), children: [_jsxs("a", { href: "/", className: "flex min-h-8 items-center gap-2 rounded-md px-2 text-sm text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground", children: [_jsx(IconArrowLeft, { className: "size-4 shrink-0 rtl:-scale-x-100" }), _jsx("span", { children: "Back to app" })] }), enableSearch ? (_jsxs("div", { className: "relative sm:mb-2", 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", { ref: searchInputRef, type: "search", value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: (event) => {
378
+ return (_jsxs("div", { ref: rootRef, 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 bg-background p-2 sm:min-h-0 sm:w-60 sm:overflow-y-auto sm:p-4", navClassName), children: [enableSearch ? (_jsxs("div", { className: "relative sm:mb-2", 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", { ref: searchInputRef, type: "search", value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: (event) => {
327
379
  if (event.key === "Escape")
328
380
  setQuery("");
329
381
  if (event.key === "Enter" && results[0]) {
@@ -333,11 +385,12 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
333
385
  }, 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) => {
334
386
  const Icon = entry.icon;
335
387
  const tab = tabs.find((candidate) => candidate.id === entry.tabId);
388
+ const entryHash = entry.hash?.replace(/^#/, "");
336
389
  const resultHref = tab?.href
337
- ? entry.hash
338
- ? `${tab.href.split("#", 1)[0]}#${entry.hash.replace(/^#/, "")}`
390
+ ? entryHash
391
+ ? buildSettingsEntryRoute(entry.tabId, entryHash)
339
392
  : tab.href
340
- : null;
393
+ : buildSettingsEntryRoute(entry.tabId, entryHash);
341
394
  const result = (_jsxs(_Fragment, { 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 })] })] }));
342
395
  return resultHref ? (_jsx(Link, { to: resultHref, role: "option", "aria-selected": false, 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: result }, entry.id)) : (_jsx("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: result }, entry.id));
343
396
  })) })) : hasCustomTabs ? (_jsx(Tabs, { items: tabs.map((tab) => ({
@@ -351,7 +404,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
351
404
  const nextTab = String(tabId);
352
405
  changeTab(nextTab);
353
406
  if (!isControlled)
354
- updateHashForTab(nextTab);
407
+ updateRouteForTab(nextTab);
355
408
  }, orientation: "vertical", "aria-label": ariaLabel, className: "flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible" })) : (_jsx("nav", { "aria-label": ariaLabel, role: "tablist", className: "flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible", children: tabGroups.map((group, groupIndex) => (_jsx("div", { "data-settings-tab-group": group.id, className: cn("contents sm:block", groupIndex > 0 && "sm:mt-3 sm:pt-1"), children: _jsxs("div", { className: "contents sm:flex sm:flex-col sm:gap-1", children: [_jsx("div", { className: "hidden px-3 pb-1 pt-1 text-[11px] font-medium text-muted-foreground sm:block", children: tabGroupLabels[group.id] ?? group.id }), group.tabs.map((tab) => {
356
409
  const Icon = tab.icon;
357
410
  const selected = tab.id === selectedTab?.id;
@@ -366,7 +419,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
366
419
  return (_jsx("button", { type: "button", role: "tab", "aria-selected": selected, "aria-controls": `settings-tabpanel-${tab.id}`, id: `settings-tab-${tab.id}`, onClick: () => {
367
420
  changeTab(tab.id);
368
421
  if (!isControlled)
369
- updateHashForTab(tab.id);
422
+ updateRouteForTab(tab.id);
370
423
  }, 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
371
424
  ? "bg-accent text-foreground"
372
425
  : "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: tabContent }, tab.id));
@@ -13,6 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import { Picker, Switch } from "@agent-native/toolkit/design-system";
14
14
  import { IconAlertCircle, IconCheck, IconChevronDown, IconChevronRight, IconExternalLink, IconLoader2, IconLockOpen, } from "@tabler/icons-react";
15
15
  import { useCallback, useEffect, useState } from "react";
16
+ import { buildSettingsRoute } from "../../navigation/index.js";
16
17
  import { agentNativePath } from "../api-path.js";
17
18
  import { SettingsRow } from "./SettingsRow.js";
18
19
  import { openBuilderConnectPopup, useBuilderStatus, } from "./useBuilderStatus.js";
@@ -221,7 +222,8 @@ export function VoiceTranscriptionSection({ compact = false, } = {}) {
221
222
  const focusKey = (key) => {
222
223
  if (typeof window === "undefined")
223
224
  return;
224
- window.location.hash = `#secrets:${key}`;
225
+ window.history.pushState(null, "", buildSettingsRoute(`integrations:secrets:${key}`));
226
+ window.dispatchEvent(new Event("popstate"));
225
227
  };
226
228
  const chooseSource = (next) => {
227
229
  if (next === transcriptionMode)
@@ -266,6 +268,9 @@ export function VoiceTranscriptionSection({ compact = false, } = {}) {
266
268
  }
267
269
  };
268
270
  if (transcriptionMode === null) {
271
+ if (compact) {
272
+ return (_jsx(SettingsRow, { label: "Voice transcription", description: "Choose how voice input is transcribed.", control: _jsx("div", { className: "h-9 w-44 animate-pulse rounded-md border border-border bg-muted-foreground/10", "aria-label": "Loading voice transcription" }) }));
273
+ }
269
274
  return (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading\u2026"] }));
270
275
  }
271
276
  if (compact) {
@@ -34,13 +34,35 @@ function firstVisibleSection(sections) {
34
34
  return "llm";
35
35
  return sections[0] ?? "llm";
36
36
  }
37
+ function settingsPathParts() {
38
+ if (typeof window === "undefined")
39
+ return [];
40
+ const pathParts = window.location.pathname.split("/").filter(Boolean);
41
+ const settingsIndex = pathParts.indexOf("settings");
42
+ return settingsIndex === -1 ? [] : pathParts.slice(settingsIndex + 1);
43
+ }
44
+ function secretKeyFromPath(pathParts) {
45
+ const secretsIndex = pathParts.findIndex((part) => part.toLowerCase() === "secrets");
46
+ if (secretsIndex === -1)
47
+ return undefined;
48
+ const key = pathParts.slice(secretsIndex + 1).join("/");
49
+ return key || undefined;
50
+ }
37
51
  function initialOpenSection(sections) {
38
52
  const hashSection = typeof window === "undefined"
39
53
  ? null
40
54
  : normalizeSettingsSection(window.location.hash);
41
- return hashSection && sections.includes(hashSection)
42
- ? hashSection
43
- : firstVisibleSection(sections);
55
+ if (hashSection && sections.includes(hashSection))
56
+ return hashSection;
57
+ if (typeof window !== "undefined") {
58
+ const routeParts = settingsPathParts();
59
+ for (let index = routeParts.length - 1; index >= 0; index -= 1) {
60
+ const pathSection = normalizeSettingsSection(routeParts[index]);
61
+ if (pathSection && sections.includes(pathSection))
62
+ return pathSection;
63
+ }
64
+ }
65
+ return firstVisibleSection(sections);
44
66
  }
45
67
  export function useSettingsPanelController({ sections = ALL_SETTINGS_SECTIONS, initialSection, sectionRequestKey, onScrollToSection, } = {}) {
46
68
  const visibleSections = useMemo(() => new Set(sections), [sections]);
@@ -72,23 +94,40 @@ export function useSettingsPanelController({ sections = ALL_SETTINGS_SECTIONS, i
72
94
  useEffect(() => {
73
95
  if (typeof window === "undefined")
74
96
  return;
75
- const handleHashChange = () => {
97
+ const handleLocationChange = () => {
76
98
  const hash = window.location.hash?.replace(/^#/, "") ?? "";
77
- const section = normalizeSettingsSection(hash);
99
+ let section = normalizeSettingsSection(hash);
100
+ const pathParts = settingsPathParts();
101
+ if (!section) {
102
+ for (let index = pathParts.length - 1; index >= 0; index -= 1) {
103
+ const pathSection = normalizeSettingsSection(pathParts[index]);
104
+ if (pathSection) {
105
+ section = pathSection;
106
+ break;
107
+ }
108
+ }
109
+ }
78
110
  if (!section || !isSectionVisible(section))
79
111
  return;
80
112
  if (hash.startsWith("secrets:") || hash === "secrets") {
81
113
  const key = hash.slice("secrets:".length);
82
114
  setFocusSecretKey(key || undefined);
83
115
  }
116
+ else if (section === "secrets") {
117
+ setFocusSecretKey(secretKeyFromPath(pathParts));
118
+ }
84
119
  else {
85
120
  setFocusSecretKey(undefined);
86
121
  }
87
122
  openSettingsSection(section, { scroll: true });
88
123
  };
89
- handleHashChange();
90
- window.addEventListener("hashchange", handleHashChange);
91
- return () => window.removeEventListener("hashchange", handleHashChange);
124
+ handleLocationChange();
125
+ window.addEventListener("hashchange", handleLocationChange);
126
+ window.addEventListener("popstate", handleLocationChange);
127
+ return () => {
128
+ window.removeEventListener("hashchange", handleLocationChange);
129
+ window.removeEventListener("popstate", handleLocationChange);
130
+ };
92
131
  }, [isSectionVisible, openSettingsSection]);
93
132
  return {
94
133
  sections,
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -17,11 +17,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
@@ -15,6 +15,36 @@ export interface WebsiteDesignTokens {
15
15
  spacing: string[];
16
16
  radii: string[];
17
17
  cssVariables: Record<string, string>;
18
+ /**
19
+ * Semantic roles are inferred from visible rendered elements, not from
20
+ * variable names. They are optional so static HTML callers can keep their
21
+ * smaller result without inventing values that were never observed.
22
+ */
23
+ semanticColors?: Partial<Record<"primary" | "secondary" | "accent" | "background" | "surface" | "text" | "textMuted", string>>;
24
+ shadows?: string[];
25
+ backgrounds?: string[];
26
+ components?: Array<{
27
+ role: "heading" | "body" | "button" | "link" | "card" | "input" | "nav" | "hero";
28
+ fontFamily?: string;
29
+ fontSize?: string;
30
+ fontWeight?: string;
31
+ lineHeight?: string;
32
+ letterSpacing?: string;
33
+ color?: string;
34
+ backgroundColor?: string;
35
+ backgroundImage?: string;
36
+ border?: string;
37
+ borderRadius?: string;
38
+ boxShadow?: string;
39
+ padding?: string;
40
+ gap?: string;
41
+ textTransform?: string;
42
+ }>;
43
+ layout?: {
44
+ contentWidth?: string;
45
+ pagePadding?: string;
46
+ sectionGap?: string;
47
+ };
18
48
  }
19
49
  export interface WebsiteExtraction {
20
50
  title: string;
@@ -904,6 +904,11 @@ declare const messages: {
904
904
  addYourOwn: string;
905
905
  noMatches: string;
906
906
  connected: string;
907
+ connectionError: string;
908
+ connectionErrorReason: string;
909
+ reconnect: string;
910
+ reconnecting: string;
911
+ reconnectFailed: string;
907
912
  configure: string;
908
913
  connect: string;
909
914
  connectWithOAuth: string;
@@ -909,6 +909,11 @@ const messages = {
909
909
  addYourOwn: "Add your own",
910
910
  noMatches: "No integrations match that search.",
911
911
  connected: "Connected",
912
+ connectionError: "Connection error",
913
+ connectionErrorReason: "Reason: {{reason}}",
914
+ reconnect: "Reconnect",
915
+ reconnecting: "Reconnecting…",
916
+ reconnectFailed: "Reconnect failed: {{error}}",
912
917
  configure: "Configure",
913
918
  connect: "Connect",
914
919
  connectWithOAuth: "Connect",
@@ -190,7 +190,7 @@ async function handleMcpOAuthCallback(event, options) {
190
190
  }
191
191
  await options.reconfigure();
192
192
  const returnPath = flow.returnUrl ??
193
- `/settings?connected=mcp-${encodeURIComponent(flow.name)}#integrations`;
193
+ `/settings/integrations?connected=mcp-${encodeURIComponent(flow.name)}`;
194
194
  return redirectWithStagedCookies(event, getAppUrl(event, returnPath));
195
195
  }
196
196
  catch {
@@ -9,6 +9,7 @@
9
9
  * POST /_agent-native/mcp/servers add a server
10
10
  * DELETE /_agent-native/mcp/servers/:id remove a server (scope via ?scope=)
11
11
  * POST /_agent-native/mcp/servers/:id/test dry-run connect (no persist)
12
+ * POST /_agent-native/mcp/servers/:id/reconnect retry connect + refresh
12
13
  * POST /_agent-native/mcp/servers/test dry-run a URL before persisting
13
14
  * GET /_agent-native/mcp/builtin list built-in capability toggles
14
15
  * POST /_agent-native/mcp/builtin update built-in capability toggles
@@ -9,6 +9,7 @@
9
9
  * POST /_agent-native/mcp/servers add a server
10
10
  * DELETE /_agent-native/mcp/servers/:id remove a server (scope via ?scope=)
11
11
  * POST /_agent-native/mcp/servers/:id/test dry-run connect (no persist)
12
+ * POST /_agent-native/mcp/servers/:id/reconnect retry connect + refresh
12
13
  * POST /_agent-native/mcp/servers/test dry-run a URL before persisting
13
14
  * GET /_agent-native/mcp/builtin list built-in capability toggles
14
15
  * POST /_agent-native/mcp/builtin update built-in capability toggles
@@ -63,6 +64,15 @@ function projectForClient(stored, scope, ownerId, status) {
63
64
  status,
64
65
  };
65
66
  }
67
+ function reconnectStatusForClient(manager, mergedId) {
68
+ const status = statusFor(manager, mergedId);
69
+ if (status.state !== "error")
70
+ return status;
71
+ return {
72
+ state: "error",
73
+ error: formatMcpConnectError(status.error),
74
+ };
75
+ }
66
76
  function statusFor(manager, mergedId) {
67
77
  const snap = manager.getStatus();
68
78
  if (snap.connectedServers.includes(mergedId)) {
@@ -328,6 +338,11 @@ export function mountMcpServersRoutes(nitroApp, manager, options = {}) {
328
338
  if (parts.length === 2 && parts[1] === "test" && method === "POST") {
329
339
  return handleTestExisting(event, manager, id);
330
340
  }
341
+ if (parts.length === 2 &&
342
+ parts[1] === "reconnect" &&
343
+ method === "POST") {
344
+ return handleReconnectExisting(event, manager, id);
345
+ }
331
346
  if (parts.length === 1 && method === "DELETE") {
332
347
  return handleDelete(event, manager, id);
333
348
  }
@@ -803,6 +818,40 @@ async function handleTestExisting(event, _manager, id) {
803
818
  }
804
819
  return { ok: true, toolCount: result.toolCount, tools: result.tools };
805
820
  }
821
+ async function handleReconnectExisting(event, manager, id) {
822
+ const scope = getQuery(event).scope;
823
+ const parsedScope = scope === "org" ? "org" : scope === "user" ? "user" : null;
824
+ if (!parsedScope) {
825
+ setResponseStatus(event, 400);
826
+ return { error: 'scope query param must be "user" or "org"' };
827
+ }
828
+ const { email, orgId } = await resolveContextForRequest(event);
829
+ let scopeId = null;
830
+ if (parsedScope === "user") {
831
+ scopeId = email;
832
+ }
833
+ else {
834
+ scopeId = orgId;
835
+ }
836
+ if (!scopeId) {
837
+ setResponseStatus(event, 401);
838
+ return { error: "Authentication required" };
839
+ }
840
+ const list = await listRemoteServers(parsedScope, scopeId);
841
+ const server = list.find((s) => s.id === id);
842
+ if (!server) {
843
+ setResponseStatus(event, 404);
844
+ return { error: "Server not found" };
845
+ }
846
+ await reconfigureManager(manager);
847
+ const mergedId = mergedConfigKey(parsedScope, server, scopeId);
848
+ const status = reconnectStatusForClient(manager, mergedId);
849
+ const projected = projectForClient(server, parsedScope, scopeId, status);
850
+ return {
851
+ ok: true,
852
+ server: projected,
853
+ };
854
+ }
806
855
  async function tryConnect(url, headers) {
807
856
  try {
808
857
  const { Client, StreamableHTTPClientTransport } = await import("@modelcontextprotocol/client");
@@ -22,12 +22,22 @@ function normalizeLeadingPath(path) {
22
22
  return `/${trimmed.replace(/^\/+/, "").replace(/\/+$/, "")}`;
23
23
  }
24
24
  function normalizeTabId(tab) {
25
- return tab
25
+ const normalized = tab
26
26
  .trim()
27
27
  .replace(/^#/, "")
28
28
  .toLowerCase()
29
29
  .replace(/['"]/g, "")
30
30
  .replace(/[\s_]+/g, "-");
31
+ if (normalized === "connections")
32
+ return "integrations";
33
+ if (normalized === "team" || normalized === "org")
34
+ return "organization";
35
+ if (normalized === "changelog" ||
36
+ normalized === "what-s-new" ||
37
+ normalized === "updates") {
38
+ return "whats-new";
39
+ }
40
+ return normalized;
31
41
  }
32
42
  function pathSegment(value) {
33
43
  return encodeURIComponent(value.trim().replace(/^\/+|\/+$/g, ""));
@@ -40,10 +50,11 @@ function resolveOpenPathRoute(route, params) {
40
50
  export function buildSettingsRoute(tab, basePath = STANDARD_APP_ROUTES.settings) {
41
51
  const path = normalizeLeadingPath(basePath);
42
52
  const normalizedTab = tab ? normalizeTabId(tab) : null;
43
- if (!normalizedTab || normalizedTab === STANDARD_SETTINGS_TABS.general) {
44
- return path;
45
- }
46
- return `${path}#${encodeURIComponent(normalizedTab)}`;
53
+ const segments = (normalizedTab || STANDARD_SETTINGS_TABS.general)
54
+ .split(":")
55
+ .map((segment) => pathSegment(segment))
56
+ .filter(Boolean);
57
+ return `${path}/${segments.join("/")}`;
47
58
  }
48
59
  export function buildTeamRoute(options = {}) {
49
60
  return options.teamInSettings
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
- ok?: undefined;
46
44
  summary: import("./types.js").TraceSummary;
47
45
  spans: import("./types.js").TraceSpan[];
48
46
  id?: undefined;
49
- } | {
50
47
  error?: undefined;
51
48
  ok?: undefined;
49
+ } | {
52
50
  summary?: undefined;
53
51
  spans?: undefined;
54
52
  id: string;
55
- } | {
53
+ error?: undefined;
56
54
  ok?: undefined;
55
+ } | {
57
56
  summary?: undefined;
58
57
  spans?: undefined;
59
58
  id?: undefined;
60
59
  error: any;
60
+ ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;