@agent-native/core 0.119.1 → 0.119.2
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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +15 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +4 -0
- package/corpus/core/src/agent/production-agent.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +11 -50
- package/corpus/core/src/client/ErrorBoundary.tsx +25 -19
- package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +1 -1
- package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +23 -0
- package/corpus/core/src/client/components/ui/message-scroller.tsx +1 -9
- package/corpus/core/src/client/resources/ResourceTree.tsx +3 -3
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +64 -60
- package/corpus/core/src/client/settings/AccountSettingsCard.tsx +228 -0
- package/corpus/core/src/client/settings/SecretsSection.tsx +7 -5
- package/corpus/core/src/client/settings/SettingsPanel.tsx +67 -244
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +88 -21
- package/corpus/core/src/client/settings/agent-settings-search.ts +0 -2
- package/corpus/core/src/client/settings/index.ts +7 -0
- package/corpus/core/src/client/vite-dev-recovery-script.ts +18 -1
- package/corpus/core/src/db/client.ts +65 -15
- package/corpus/core/src/db/index.ts +2 -0
- package/corpus/core/src/localization/default-messages.ts +1 -0
- package/corpus/core/src/server/email.ts +33 -1
- package/corpus/core/src/styles/agent-native.css +23 -0
- package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/core/src/templates/default/app/routes/settings.tsx +2 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/core/src/vite/client.ts +76 -8
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +3 -1
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +9 -13
- package/corpus/templates/analytics/app/components/layout/layout-route-policy.ts +2 -2
- package/corpus/templates/analytics/app/global.css +0 -5
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +0 -13
- package/corpus/templates/analytics/app/lib/sql-query.ts +15 -2
- package/corpus/templates/analytics/app/pages/Settings.tsx +2 -24
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
- package/corpus/templates/analytics/app/pages/settings/settings-search.ts +1 -1
- package/corpus/templates/analytics/changelog/2026-07-23-ask-analytics-is-better-centered-with-a-quieter-chat-rail-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-23-daily-dashboard-emails-load-read-heavy-panels-reliably.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +2 -2
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +39 -5
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +186 -62
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +3 -0
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +18 -2
- package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +3 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -4
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/assets/app/global.css +0 -5
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +0 -22
- package/corpus/templates/assets/app/routes/settings.tsx +2 -0
- package/corpus/templates/assets/changelog/2026-07-23-create-and-chat-surfaces-are-better-centered-with-quieter-ch.md +6 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/brain/app/global.css +0 -9
- package/corpus/templates/brain/app/hooks/use-navigation-state.ts +0 -12
- package/corpus/templates/brain/app/i18n-data.ts +1 -0
- package/corpus/templates/brain/app/lib/settings-navigation.ts +1 -1
- package/corpus/templates/brain/app/routes/settings.tsx +21 -22
- package/corpus/templates/brain/changelog/2026-07-23-ask-brain-is-better-centered-with-quieter-chat-history-and-a.md +6 -0
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +2 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +0 -15
- package/corpus/templates/chat/app/routes/settings.tsx +2 -0
- package/corpus/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +2 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/content/app/routes/_app.settings.tsx +2 -0
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/design/app/routes/settings.tsx +2 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/dispatch/app/routes/settings.tsx +2 -0
- package/corpus/templates/dispatch/changelog/2026-07-23-quieter-progressive-disclosure.md +6 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/forms/app/global.css +0 -5
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +0 -7
- package/corpus/templates/forms/app/root.tsx +1 -7
- package/corpus/templates/forms/app/routes/_app.settings.tsx +2 -0
- package/corpus/templates/forms/changelog/2026-07-23-ask-forms-is-better-centered-with-quieter-chat-history-and-a.md +6 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/macros/app/routes/settings.tsx +2 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +3 -1
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/plan/app/components/layout/Layout.tsx +2 -2
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +1 -13
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +0 -4
- package/corpus/templates/plan/app/routes/settings.tsx +2 -0
- package/corpus/templates/plan/changelog/2026-07-23-ask-plan-is-now-a-clean-full-page-chat-surface-with-better-c.md +6 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/templates/slides/app/routes/settings.tsx +2 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +28 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/chat-history.css +2 -2
- package/corpus/toolkit/src/composer/PromptComposer.tsx +0 -31
- package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +7 -2
- package/corpus/toolkit/src/styles.css +183 -36
- package/dist/a2a/client.d.ts +2 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -0
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +1 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +11 -42
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +3 -2
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.js +1 -1
- package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.js +13 -1
- package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
- package/dist/client/components/ui/message-scroller.d.ts.map +1 -1
- package/dist/client/components/ui/message-scroller.js +2 -2
- package/dist/client/components/ui/message-scroller.js.map +1 -1
- package/dist/client/resources/ResourceTree.js +2 -2
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +11 -11
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/AccountSettingsCard.d.ts +9 -0
- package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -0
- package/dist/client/settings/AccountSettingsCard.js +78 -0
- package/dist/client/settings/AccountSettingsCard.js.map +1 -0
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +2 -2
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts +3 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +25 -77
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +5 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +35 -9
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
- package/dist/client/settings/agent-settings-search.js +0 -2
- package/dist/client/settings/agent-settings-search.js.map +1 -1
- package/dist/client/settings/index.d.ts +2 -1
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +2 -1
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/vite-dev-recovery-script.d.ts.map +1 -1
- package/dist/client/vite-dev-recovery-script.js +18 -1
- package/dist/client/vite-dev-recovery-script.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +18 -8
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +34 -11
- package/dist/db/client.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +1 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/email.d.ts +1 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +29 -1
- package/dist/server/email.js.map +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/styles/agent-native.css +23 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +0 -15
- package/dist/templates/chat/app/routes/settings.tsx +2 -0
- package/dist/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
- package/dist/templates/default/app/routes/settings.tsx +2 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +68 -6
- package/dist/vite/client.js.map +1 -1
- package/package.json +2 -2
- package/src/a2a/client.ts +4 -0
- package/src/agent/production-agent.ts +1 -0
- package/src/client/AssistantChat.tsx +11 -50
- package/src/client/ErrorBoundary.tsx +25 -19
- package/src/client/agent-page/AgentTabFrame.tsx +1 -1
- package/src/client/agent-page/AgentTabsPage.tsx +23 -0
- package/src/client/components/ui/message-scroller.tsx +1 -9
- package/src/client/resources/ResourceTree.tsx +3 -3
- package/src/client/resources/ResourcesPanel.tsx +64 -60
- package/src/client/settings/AccountSettingsCard.tsx +228 -0
- package/src/client/settings/SecretsSection.tsx +7 -5
- package/src/client/settings/SettingsPanel.tsx +67 -244
- package/src/client/settings/SettingsTabsPage.tsx +88 -21
- package/src/client/settings/agent-settings-search.ts +0 -2
- package/src/client/settings/index.ts +7 -0
- package/src/client/vite-dev-recovery-script.ts +18 -1
- package/src/db/client.ts +65 -15
- package/src/db/index.ts +2 -0
- package/src/localization/default-messages.ts +1 -0
- package/src/server/email.ts +33 -1
- package/src/styles/agent-native.css +23 -0
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/src/templates/chat/app/components/layout/Sidebar.tsx +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +0 -15
- package/src/templates/chat/app/routes/settings.tsx +2 -0
- package/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
- package/src/templates/default/app/routes/settings.tsx +2 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
- package/src/vite/client.ts +76 -8
|
@@ -31,6 +31,8 @@ export interface SettingsTabItem {
|
|
|
31
31
|
label: string;
|
|
32
32
|
icon?: SettingsTabIcon;
|
|
33
33
|
content: ReactNode;
|
|
34
|
+
/** Optional route for settings that live on a canonical page elsewhere. */
|
|
35
|
+
href?: string;
|
|
34
36
|
/** Whether a parent surface may expose a personal/organization scope for this tab. */
|
|
35
37
|
scopeAware?: boolean;
|
|
36
38
|
/**
|
|
@@ -46,10 +48,12 @@ export interface SettingsTabItem {
|
|
|
46
48
|
}
|
|
47
49
|
export interface SettingsTabsPageProps {
|
|
48
50
|
general: ReactNode;
|
|
51
|
+
account?: ReactNode;
|
|
49
52
|
team?: ReactNode;
|
|
50
53
|
whatsNew?: ReactNode;
|
|
51
54
|
extraTabs?: SettingsTabItem[];
|
|
52
55
|
generalLabel?: string;
|
|
56
|
+
accountLabel?: string;
|
|
53
57
|
teamLabel?: string;
|
|
54
58
|
whatsNewLabel?: string;
|
|
55
59
|
ariaLabel?: string;
|
|
@@ -79,6 +83,6 @@ export interface SettingsTabsPageProps {
|
|
|
79
83
|
*/
|
|
80
84
|
onValueChange?: (tabId: string) => void;
|
|
81
85
|
}
|
|
82
|
-
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;
|
|
86
|
+
export declare function SettingsTabsPage({ general, account, team, whatsNew, extraTabs, generalLabel, accountLabel, teamLabel, whatsNewLabel, ariaLabel, defaultTab, className, navClassName, contentClassName, enableSearch, searchPlaceholder, searchEntries, generalSearchEntries, value, onValueChange, }: SettingsTabsPageProps): import("react").JSX.Element;
|
|
83
87
|
export {};
|
|
84
88
|
//# sourceMappingURL=SettingsTabsPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsTabsPage.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SettingsTabsPage.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"AASA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,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,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,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,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,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,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;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAkFD,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAc,EACd,YAAwB,EACxB,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,+BAsdvB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
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 { IconHistory, IconSearch, IconSettings, IconUsers, IconX, } from "@tabler/icons-react";
|
|
3
|
+
import { IconHistory, IconSearch, IconSettings, IconUserCircle, IconUsers, IconX, } from "@tabler/icons-react";
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
5
|
+
import { Link } from "react-router";
|
|
5
6
|
import { cn } from "../utils.js";
|
|
6
7
|
function normalizeTabId(value) {
|
|
7
8
|
const normalized = value
|
|
@@ -64,7 +65,7 @@ function isEditableElement(element) {
|
|
|
64
65
|
tagName === "select" ||
|
|
65
66
|
element.isContentEditable);
|
|
66
67
|
}
|
|
67
|
-
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, }) {
|
|
68
|
+
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, }) {
|
|
68
69
|
const rootRef = useRef(null);
|
|
69
70
|
const searchInputRef = useRef(null);
|
|
70
71
|
const autoFocusedSearchRef = useRef(false);
|
|
@@ -80,6 +81,15 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
|
|
|
80
81
|
searchEntries: generalSearchEntries,
|
|
81
82
|
},
|
|
82
83
|
];
|
|
84
|
+
if (account) {
|
|
85
|
+
next.push({
|
|
86
|
+
id: "account",
|
|
87
|
+
label: accountLabel,
|
|
88
|
+
icon: IconUserCircle,
|
|
89
|
+
content: account,
|
|
90
|
+
keywords: "profile photo avatar identity signed in email name",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
83
93
|
next.push(...extraTabs);
|
|
84
94
|
if (team && !hasOrganizationTab) {
|
|
85
95
|
next.push({
|
|
@@ -101,6 +111,8 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
|
|
|
101
111
|
}
|
|
102
112
|
return next;
|
|
103
113
|
}, [
|
|
114
|
+
account,
|
|
115
|
+
accountLabel,
|
|
104
116
|
extraTabs,
|
|
105
117
|
general,
|
|
106
118
|
generalLabel,
|
|
@@ -132,7 +144,8 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
|
|
|
132
144
|
const activeTab = isControlled ? value : internalTab;
|
|
133
145
|
const [query, setQuery] = useState("");
|
|
134
146
|
const designSystem = useDesignSystem();
|
|
135
|
-
const
|
|
147
|
+
const hasLinkedTabs = tabs.some((tab) => Boolean(tab.href));
|
|
148
|
+
const hasCustomTabs = Boolean(designSystem?.components?.Tabs) && !hasLinkedTabs;
|
|
136
149
|
const changeTab = useCallback((tabId) => {
|
|
137
150
|
if (!isControlled)
|
|
138
151
|
setInternalTab(tabId);
|
|
@@ -293,7 +306,14 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
|
|
|
293
306
|
}
|
|
294
307
|
}, 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) => {
|
|
295
308
|
const Icon = entry.icon;
|
|
296
|
-
|
|
309
|
+
const tab = tabs.find((candidate) => candidate.id === entry.tabId);
|
|
310
|
+
const resultHref = tab?.href
|
|
311
|
+
? entry.hash
|
|
312
|
+
? `${tab.href.split("#", 1)[0]}#${entry.hash.replace(/^#/, "")}`
|
|
313
|
+
: tab.href
|
|
314
|
+
: null;
|
|
315
|
+
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 })] })] }));
|
|
316
|
+
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));
|
|
297
317
|
})) })) : hasCustomTabs ? (_jsx(Tabs, { items: tabs.map((tab) => ({
|
|
298
318
|
value: tab.id,
|
|
299
319
|
label: tab.label,
|
|
@@ -310,15 +330,21 @@ export function SettingsTabsPage({ general, team, whatsNew, extraTabs = [], gene
|
|
|
310
330
|
"sm:mt-2 sm:border-t sm:border-border/60 sm:pt-2"), children: _jsx("div", { className: "contents sm:flex sm:flex-col sm:gap-1", children: group.tabs.map((tab) => {
|
|
311
331
|
const Icon = tab.icon;
|
|
312
332
|
const selected = tab.id === selectedTab?.id;
|
|
313
|
-
|
|
333
|
+
const tabContent = (_jsxs(_Fragment, { children: [Icon ? (_jsx(Icon, { className: cn("size-4 shrink-0", selected
|
|
334
|
+
? "text-foreground"
|
|
335
|
+
: "text-muted-foreground") })) : null, _jsx("span", { className: "truncate", children: tab.label })] }));
|
|
336
|
+
if (tab.href) {
|
|
337
|
+
return (_jsx(Link, { role: "tab", "aria-selected": selected, to: tab.href, 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
|
|
338
|
+
? "bg-accent text-foreground"
|
|
339
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: tabContent }, tab.id));
|
|
340
|
+
}
|
|
341
|
+
return (_jsx("button", { type: "button", role: "tab", "aria-selected": selected, "aria-controls": `settings-tabpanel-${tab.id}`, id: `settings-tab-${tab.id}`, onClick: () => {
|
|
314
342
|
changeTab(tab.id);
|
|
315
343
|
if (!isControlled)
|
|
316
344
|
updateHashForTab(tab.id);
|
|
317
345
|
}, 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
|
|
318
346
|
? "bg-accent text-foreground"
|
|
319
|
-
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children:
|
|
320
|
-
? "text-foreground"
|
|
321
|
-
: "text-muted-foreground") })) : null, _jsx("span", { className: "truncate", children: tab.label })] }, tab.id));
|
|
347
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: tabContent }, tab.id));
|
|
322
348
|
}) }) }, group.id))) }))] }), _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 })] }));
|
|
323
349
|
}
|
|
324
350
|
//# 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 { Tabs, useDesignSystem } from \"@agent-native/toolkit/design-system\";\nimport {\n IconHistory,\n IconSearch,\n IconSettings,\n IconUsers,\n IconX,\n} from \"@tabler/icons-react\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\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 /** Whether a parent surface may expose a personal/organization scope for this tab. */\n scopeAware?: boolean;\n /**\n * Optional visual navigation group. Adjacent tabs with the same group render\n * together; a quiet divider separates each group on desktop while mobile\n * keeps the compact horizontal tab scroller unchanged.\n */\n group?: string;\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). Recognized top-level tab hashes still\n * report through `onValueChange`, so shared links such as\n * `/settings#organization` can select the matching controlled Team tab.\n * Leave undefined for the default uncontrolled, hash-driven 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 return normalized;\n}\n\nfunction resolveTabId(\n tabs: SettingsTabItem[],\n value?: string | null,\n): string | null {\n const normalized = normalizeTabId(value);\n if (!normalized) return null;\n if (tabs.some((tab) => tab.id === normalized)) return normalized;\n const section = normalized.split(\":\", 1)[0];\n const owner = tabs.find((tab) =>\n tab.searchEntries?.some(\n (entry) => normalizeTabId(entry.hash ?? entry.id) === section,\n ),\n );\n if (owner) return owner.id;\n if (\n normalized === \"organization\" ||\n normalized === \"org\" ||\n normalized === \"team\"\n ) {\n if (tabs.some((tab) => tab.id === \"organization\")) return \"organization\";\n if (tabs.some((tab) => tab.id === \"team\")) return \"team\";\n }\n return null;\n}\n\nfunction activeTabFromHash(\n tabs: SettingsTabItem[],\n defaultTab: string,\n): string {\n if (typeof window === \"undefined\") return defaultTab;\n return resolveTabId(tabs, window.location.hash) ?? 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\nfunction isEditableElement(element: Element | null): boolean {\n if (!(element instanceof HTMLElement)) return false;\n const tagName = element.tagName.toLowerCase();\n return (\n tagName === \"input\" ||\n tagName === \"textarea\" ||\n tagName === \"select\" ||\n element.isContentEditable\n );\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 rootRef = useRef<HTMLDivElement | null>(null);\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n const autoFocusedSearchRef = useRef(false);\n const controlledHashRef = useRef<string | null>(null);\n const tabs = useMemo<SettingsTabItem[]>(() => {\n const hasOrganizationTab = extraTabs.some(\n (tab) => tab.id === \"organization\",\n );\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 && !hasOrganizationTab) {\n next.push({\n id: \"team\",\n label: teamLabel,\n icon: IconUsers,\n group: \"workspace\",\n content: team,\n });\n }\n if (whatsNew) {\n next.push({\n id: \"whats-new\",\n label: whatsNewLabel,\n icon: IconHistory,\n group: \"updates\",\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 tabGroups = useMemo(() => {\n const groups: Array<{ id: string; tabs: SettingsTabItem[] }> = [];\n for (const tab of tabs) {\n const groupId = tab.group ?? \"app\";\n const previousGroup = groups.at(-1);\n if (previousGroup?.id === groupId) {\n previousGroup.tabs.push(tab);\n } else {\n groups.push({ id: groupId, tabs: [tab] });\n }\n }\n return groups;\n }, [tabs]);\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 const designSystem = useDesignSystem();\n const hasCustomTabs = Boolean(designSystem?.components?.Tabs);\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 = resolveTabId(tabs, window.location.hash);\n if (fromHash) {\n setInternalTab(fromHash);\n }\n };\n window.addEventListener(\"hashchange\", handleHashChange);\n return () => window.removeEventListener(\"hashchange\", handleHashChange);\n }, [isControlled, tabs]);\n\n useEffect(() => {\n // Controlled pages retain ownership of their active state, but shared\n // organization navigation uses a hash deep link. Report only recognized\n // top-level tab hashes; section hashes remain available to inner panels.\n if (!isControlled) return;\n const syncControlledHash = () => {\n const hash = window.location.hash;\n const fromHash = resolveTabId(tabs, hash);\n if (!fromHash || controlledHashRef.current === hash) return;\n controlledHashRef.current = hash;\n onValueChange?.(fromHash);\n };\n syncControlledHash();\n window.addEventListener(\"hashchange\", syncControlledHash);\n return () => window.removeEventListener(\"hashchange\", syncControlledHash);\n }, [isControlled, onValueChange, tabs, value]);\n\n useEffect(() => {\n if (!enableSearch || autoFocusedSearchRef.current) return;\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return;\n }\n if (window.matchMedia(\"(max-width: 767px)\").matches) return;\n\n const frame = window.requestAnimationFrame(() => {\n autoFocusedSearchRef.current = true;\n const input = searchInputRef.current;\n if (!input) return;\n\n const activeElement = document.activeElement;\n const activeInsideSettings =\n !!activeElement && rootRef.current?.contains(activeElement);\n if (\n activeElement !== input &&\n (isEditableElement(activeElement) || activeInsideSettings)\n ) {\n return;\n }\n\n input.focus({ preventScroll: true });\n });\n\n return () => window.cancelAnimationFrame(frame);\n }, [enableSearch]);\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 ref={rootRef}\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 bg-background p-2 sm:min-h-0 sm:w-56 sm:overflow-y-auto 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 ref={searchInputRef}\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 ) : hasCustomTabs ? (\n <Tabs\n items={tabs.map((tab) => ({\n value: tab.id,\n label: tab.label,\n icon: tab.icon ? <tab.icon className=\"size-4 shrink-0\" /> : null,\n // The panel stays outside this navigation rail so settings\n // keeps its existing scroll container and deep-link behavior.\n content: null,\n }))}\n value={activeTab}\n onChange={(tabId) => {\n const nextTab = String(tabId);\n changeTab(nextTab);\n if (!isControlled) updateHashForTab(nextTab);\n }}\n orientation=\"vertical\"\n aria-label={ariaLabel}\n className=\"flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible\"\n />\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 {tabGroups.map((group, groupIndex) => (\n <div\n key={group.id}\n data-settings-tab-group={group.id}\n className={cn(\n \"contents sm:block\",\n groupIndex > 0 &&\n \"sm:mt-2 sm:border-t sm:border-border/60 sm:pt-2\",\n )}\n >\n <div className=\"contents sm:flex sm:flex-col sm:gap-1\">\n {group.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\n ? \"text-foreground\"\n : \"text-muted-foreground\",\n )}\n />\n ) : null}\n <span className=\"truncate\">{tab.label}</span>\n </button>\n );\n })}\n </div>\n </div>\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
|
+
{"version":3,"file":"SettingsTabsPage.js","sourceRoot":"","sources":["../../../src/client/settings/SettingsTabsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Tabs, useDesignSystem } from \"@agent-native/toolkit/design-system\";\nimport {\n IconHistory,\n IconSearch,\n IconSettings,\n IconUserCircle,\n IconUsers,\n IconX,\n} from \"@tabler/icons-react\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { Link } from \"react-router\";\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 /** Optional route for settings that live on a canonical page elsewhere. */\n href?: string;\n /** Whether a parent surface may expose a personal/organization scope for this tab. */\n scopeAware?: boolean;\n /**\n * Optional visual navigation group. Adjacent tabs with the same group render\n * together; a quiet divider separates each group on desktop while mobile\n * keeps the compact horizontal tab scroller unchanged.\n */\n group?: string;\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 account?: ReactNode;\n team?: ReactNode;\n whatsNew?: ReactNode;\n extraTabs?: SettingsTabItem[];\n generalLabel?: string;\n accountLabel?: 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). Recognized top-level tab hashes still\n * report through `onValueChange`, so shared links such as\n * `/settings#organization` can select the matching controlled Team tab.\n * Leave undefined for the default uncontrolled, hash-driven 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 return normalized;\n}\n\nfunction resolveTabId(\n tabs: SettingsTabItem[],\n value?: string | null,\n): string | null {\n const normalized = normalizeTabId(value);\n if (!normalized) return null;\n if (tabs.some((tab) => tab.id === normalized)) return normalized;\n const section = normalized.split(\":\", 1)[0];\n const owner = tabs.find((tab) =>\n tab.searchEntries?.some(\n (entry) => normalizeTabId(entry.hash ?? entry.id) === section,\n ),\n );\n if (owner) return owner.id;\n if (\n normalized === \"organization\" ||\n normalized === \"org\" ||\n normalized === \"team\"\n ) {\n if (tabs.some((tab) => tab.id === \"organization\")) return \"organization\";\n if (tabs.some((tab) => tab.id === \"team\")) return \"team\";\n }\n return null;\n}\n\nfunction activeTabFromHash(\n tabs: SettingsTabItem[],\n defaultTab: string,\n): string {\n if (typeof window === \"undefined\") return defaultTab;\n return resolveTabId(tabs, window.location.hash) ?? 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\nfunction isEditableElement(element: Element | null): boolean {\n if (!(element instanceof HTMLElement)) return false;\n const tagName = element.tagName.toLowerCase();\n return (\n tagName === \"input\" ||\n tagName === \"textarea\" ||\n tagName === \"select\" ||\n element.isContentEditable\n );\n}\n\nexport function SettingsTabsPage({\n general,\n account,\n team,\n whatsNew,\n extraTabs = [],\n generalLabel = \"General\",\n accountLabel = \"Account\",\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 rootRef = useRef<HTMLDivElement | null>(null);\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n const autoFocusedSearchRef = useRef(false);\n const controlledHashRef = useRef<string | null>(null);\n const tabs = useMemo<SettingsTabItem[]>(() => {\n const hasOrganizationTab = extraTabs.some(\n (tab) => tab.id === \"organization\",\n );\n const next: SettingsTabItem[] = [\n {\n id: \"general\",\n label: generalLabel,\n icon: IconSettings,\n content: general,\n searchEntries: generalSearchEntries,\n },\n ];\n if (account) {\n next.push({\n id: \"account\",\n label: accountLabel,\n icon: IconUserCircle,\n content: account,\n keywords: \"profile photo avatar identity signed in email name\",\n });\n }\n next.push(...extraTabs);\n if (team && !hasOrganizationTab) {\n next.push({\n id: \"team\",\n label: teamLabel,\n icon: IconUsers,\n group: \"workspace\",\n content: team,\n });\n }\n if (whatsNew) {\n next.push({\n id: \"whats-new\",\n label: whatsNewLabel,\n icon: IconHistory,\n group: \"updates\",\n content: whatsNew,\n });\n }\n return next;\n }, [\n account,\n accountLabel,\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 tabGroups = useMemo(() => {\n const groups: Array<{ id: string; tabs: SettingsTabItem[] }> = [];\n for (const tab of tabs) {\n const groupId = tab.group ?? \"app\";\n const previousGroup = groups.at(-1);\n if (previousGroup?.id === groupId) {\n previousGroup.tabs.push(tab);\n } else {\n groups.push({ id: groupId, tabs: [tab] });\n }\n }\n return groups;\n }, [tabs]);\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 const designSystem = useDesignSystem();\n const hasLinkedTabs = tabs.some((tab) => Boolean(tab.href));\n const hasCustomTabs =\n Boolean(designSystem?.components?.Tabs) && !hasLinkedTabs;\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 = resolveTabId(tabs, window.location.hash);\n if (fromHash) {\n setInternalTab(fromHash);\n }\n };\n window.addEventListener(\"hashchange\", handleHashChange);\n return () => window.removeEventListener(\"hashchange\", handleHashChange);\n }, [isControlled, tabs]);\n\n useEffect(() => {\n // Controlled pages retain ownership of their active state, but shared\n // organization navigation uses a hash deep link. Report only recognized\n // top-level tab hashes; section hashes remain available to inner panels.\n if (!isControlled) return;\n const syncControlledHash = () => {\n const hash = window.location.hash;\n const fromHash = resolveTabId(tabs, hash);\n if (!fromHash || controlledHashRef.current === hash) return;\n controlledHashRef.current = hash;\n onValueChange?.(fromHash);\n };\n syncControlledHash();\n window.addEventListener(\"hashchange\", syncControlledHash);\n return () => window.removeEventListener(\"hashchange\", syncControlledHash);\n }, [isControlled, onValueChange, tabs, value]);\n\n useEffect(() => {\n if (!enableSearch || autoFocusedSearchRef.current) return;\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return;\n }\n if (window.matchMedia(\"(max-width: 767px)\").matches) return;\n\n const frame = window.requestAnimationFrame(() => {\n autoFocusedSearchRef.current = true;\n const input = searchInputRef.current;\n if (!input) return;\n\n const activeElement = document.activeElement;\n const activeInsideSettings =\n !!activeElement && rootRef.current?.contains(activeElement);\n if (\n activeElement !== input &&\n (isEditableElement(activeElement) || activeInsideSettings)\n ) {\n return;\n }\n\n input.focus({ preventScroll: true });\n });\n\n return () => window.cancelAnimationFrame(frame);\n }, [enableSearch]);\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 ref={rootRef}\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 bg-background p-2 sm:min-h-0 sm:w-56 sm:overflow-y-auto 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 ref={searchInputRef}\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 const tab = tabs.find(\n (candidate) => candidate.id === entry.tabId,\n );\n const resultHref = tab?.href\n ? entry.hash\n ? `${tab.href.split(\"#\", 1)[0]}#${entry.hash.replace(/^#/, \"\")}`\n : tab.href\n : null;\n const result = (\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 </>\n );\n return resultHref ? (\n <Link\n key={entry.id}\n to={resultHref}\n role=\"option\"\n aria-selected={false}\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 {result}\n </Link>\n ) : (\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 {result}\n </button>\n );\n })\n )}\n </div>\n ) : hasCustomTabs ? (\n <Tabs\n items={tabs.map((tab) => ({\n value: tab.id,\n label: tab.label,\n icon: tab.icon ? <tab.icon className=\"size-4 shrink-0\" /> : null,\n // The panel stays outside this navigation rail so settings\n // keeps its existing scroll container and deep-link behavior.\n content: null,\n }))}\n value={activeTab}\n onChange={(tabId) => {\n const nextTab = String(tabId);\n changeTab(nextTab);\n if (!isControlled) updateHashForTab(nextTab);\n }}\n orientation=\"vertical\"\n aria-label={ariaLabel}\n className=\"flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible\"\n />\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 {tabGroups.map((group, groupIndex) => (\n <div\n key={group.id}\n data-settings-tab-group={group.id}\n className={cn(\n \"contents sm:block\",\n groupIndex > 0 &&\n \"sm:mt-2 sm:border-t sm:border-border/60 sm:pt-2\",\n )}\n >\n <div className=\"contents sm:flex sm:flex-col sm:gap-1\">\n {group.tabs.map((tab) => {\n const Icon = tab.icon;\n const selected = tab.id === selectedTab?.id;\n const tabContent = (\n <>\n {Icon ? (\n <Icon\n className={cn(\n \"size-4 shrink-0\",\n selected\n ? \"text-foreground\"\n : \"text-muted-foreground\",\n )}\n />\n ) : null}\n <span className=\"truncate\">{tab.label}</span>\n </>\n );\n if (tab.href) {\n return (\n <Link\n key={tab.id}\n role=\"tab\"\n aria-selected={selected}\n to={tab.href}\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 {tabContent}\n </Link>\n );\n }\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 {tabContent}\n </button>\n );\n })}\n </div>\n </div>\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-settings-search.d.ts","sourceRoot":"","sources":["../../../src/client/settings/agent-settings-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,KAAK,GACL,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,WAAW,GACX,aAAa,GACb,SAAS,GACT,SAAS,GACT,UAAU,GACV,SAAS,GACT,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GACZ,cAAc,GACd,OAAO,GACP,KAAK,CAAC;AAEV,eAAO,MAAM,oBAAoB,wBAmB/B,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,SAAS,iBAAiB,
|
|
1
|
+
{"version":3,"file":"agent-settings-search.d.ts","sourceRoot":"","sources":["../../../src/client/settings/agent-settings-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,KAAK,GACL,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,WAAW,GACX,aAAa,GACb,SAAS,GACT,SAAS,GACT,UAAU,GACV,SAAS,GACT,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GACZ,cAAc,GACd,OAAO,GACP,KAAK,CAAC;AAEV,eAAO,MAAM,oBAAoB,wBAmB/B,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,SAAS,iBAAiB,EAkB7D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,SAAS,iBAAiB,EAQ/D,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,SAAS,iBAAiB,EAMpE,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,SAAS,iBAAiB,EAMnE,CAAC;AAiFF,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GACrC,mBAAmB,EAAE,CAWvB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED,wBAAgB,0BAA0B,IAAI,sBAAsB,EAAE,CA2BrE"}
|
|
@@ -19,7 +19,6 @@ export const SETTINGS_SECTION_IDS = new Set([
|
|
|
19
19
|
"a2a",
|
|
20
20
|
]);
|
|
21
21
|
export const ALL_SETTINGS_SECTIONS = [
|
|
22
|
-
"account",
|
|
23
22
|
"llm",
|
|
24
23
|
"app-models",
|
|
25
24
|
"limits",
|
|
@@ -55,7 +54,6 @@ export const CONNECTION_SETTINGS_SECTIONS = [
|
|
|
55
54
|
"usage",
|
|
56
55
|
];
|
|
57
56
|
export const WORKSPACE_SETTINGS_SECTIONS = [
|
|
58
|
-
"account",
|
|
59
57
|
"demo-mode",
|
|
60
58
|
"hosting",
|
|
61
59
|
"database",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-settings-search.js","sourceRoot":"","sources":["../../../src/client/settings/agent-settings-search.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAoB;IAC7D,SAAS;IACT,KAAK;IACL,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,WAAW;IACX,aAAa;IACb,SAAS;IACT,SAAS;IACT,UAAU;IACV,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,YAAY;IACZ,cAAc;IACd,OAAO;IACP,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,
|
|
1
|
+
{"version":3,"file":"agent-settings-search.js","sourceRoot":"","sources":["../../../src/client/settings/agent-settings-search.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAoB;IAC7D,SAAS;IACT,KAAK;IACL,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,WAAW;IACX,aAAa;IACb,SAAS;IACT,SAAS;IACT,UAAU;IACV,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,YAAY;IACZ,cAAc;IACd,OAAO;IACP,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,KAAK;IACL,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,WAAW;IACX,aAAa;IACb,SAAS;IACT,SAAS;IACT,UAAU;IACV,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,YAAY;IACZ,cAAc;IACd,OAAO;IACP,KAAK;CACN,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAiC;IACnE,KAAK;IACL,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,aAAa;IACb,YAAY;IACZ,KAAK;CACN,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAiC;IACxE,SAAS;IACT,cAAc;IACd,OAAO;IACP,SAAS;IACT,OAAO;CACR,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAiC;IACvE,WAAW;IACX,SAAS;IACT,UAAU;IACV,SAAS;IACT,MAAM;CACP,CAAC;AAEF,MAAM,4BAA4B,GAG9B;IACF,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,oDAAoD;KAC/D;IACD,GAAG,EAAE;QACH,KAAK,EAAE,KAAK;QACZ,QAAQ,EACN,yEAAyE;KAC5E;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,mBAAmB;QAC1B,QAAQ,EAAE,8CAA8C;KACzD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,cAAc;QACrB,QAAQ,EAAE,4CAA4C;KACvD;IACD,KAAK,EAAE;QACL,KAAK,EAAE,qBAAqB;QAC5B,QAAQ,EAAE,6CAA6C;KACxD;IACD,WAAW,EAAE;QACX,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE,oDAAoD;KAC/D;IACD,WAAW,EAAE;QACX,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE,qCAAqC;KAChD;IACD,OAAO,EAAE;QACP,KAAK,EAAE,wBAAwB;QAC/B,QAAQ,EAAE,2DAA2D;KACtE;IACD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,gDAAgD;KAC3D;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,wDAAwD;KACnE;IACD,OAAO,EAAE;QACP,KAAK,EAAE,cAAc;QACrB,QAAQ,EAAE,kDAAkD;KAC7D;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,gBAAgB;QACvB,QAAQ,EAAE,yDAAyD;KACpE;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,0DAA0D;KACrE;IACD,OAAO,EAAE;QACP,KAAK,EAAE,oBAAoB;QAC3B,QAAQ,EAAE,yCAAyC;KACpD;IACD,UAAU,EAAE;QACV,KAAK,EAAE,kBAAkB;QACzB,QAAQ,EAAE,gDAAgD;KAC3D;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,cAAc;QACrB,QAAQ,EAAE,mDAAmD;KAC9D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,uCAAuC;KAClD;IACD,GAAG,EAAE;QACH,KAAK,EAAE,wBAAwB;QAC/B,QAAQ,EAAE,sCAAsC;KACjD;CACF,CAAC;AAEF,MAAM,UAAU,yBAAyB,CACvC,QAAsC;IAEtC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,IAAI,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO;YACL,EAAE,EAAE,WAAW,OAAO,EAAE;YACxB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE,OAAO;SACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AASD,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,cAAc;YACrB,QAAQ,EACN,iEAAiE;YACnE,aAAa,EAAE,yBAAyB,CAAC,uBAAuB,CAAC;SAClE;QACD;YACE,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,sDAAsD;YAChE,aAAa,EAAE,yBAAyB,CAAC,4BAA4B,CAAC;SACvE;QACD;YACE,EAAE,EAAE,cAAc;YAClB,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,qDAAqD;SAChE;QACD;YACE,EAAE,EAAE,WAAW;YACf,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,iDAAiD;YAC3D,aAAa,EAAE,yBAAyB,CAAC,2BAA2B,CAAC;SACtE;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { SettingsSearchEntry } from \"./SettingsTabsPage.js\";\n\nexport type SettingsSectionId =\n | \"account\"\n | \"llm\"\n | \"app-models\"\n | \"limits\"\n | \"voice\"\n | \"demo-mode\"\n | \"automations\"\n | \"secrets\"\n | \"hosting\"\n | \"database\"\n | \"uploads\"\n | \"auth\"\n | \"email\"\n | \"browser\"\n | \"background\"\n | \"integrations\"\n | \"usage\"\n | \"a2a\";\n\nexport const SETTINGS_SECTION_IDS = new Set<SettingsSectionId>([\n \"account\",\n \"llm\",\n \"app-models\",\n \"limits\",\n \"voice\",\n \"demo-mode\",\n \"automations\",\n \"secrets\",\n \"hosting\",\n \"database\",\n \"uploads\",\n \"auth\",\n \"email\",\n \"browser\",\n \"background\",\n \"integrations\",\n \"usage\",\n \"a2a\",\n]);\n\nexport const ALL_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [\n \"llm\",\n \"app-models\",\n \"limits\",\n \"voice\",\n \"demo-mode\",\n \"automations\",\n \"secrets\",\n \"hosting\",\n \"database\",\n \"uploads\",\n \"auth\",\n \"email\",\n \"browser\",\n \"background\",\n \"integrations\",\n \"usage\",\n \"a2a\",\n];\n\nexport const AGENT_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [\n \"llm\",\n \"app-models\",\n \"limits\",\n \"voice\",\n \"automations\",\n \"background\",\n \"a2a\",\n];\n\nexport const CONNECTION_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [\n \"secrets\",\n \"integrations\",\n \"email\",\n \"browser\",\n \"usage\",\n];\n\nexport const WORKSPACE_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [\n \"demo-mode\",\n \"hosting\",\n \"database\",\n \"uploads\",\n \"auth\",\n];\n\nconst SETTINGS_SECTION_SEARCH_META: Record<\n SettingsSectionId,\n { label: string; keywords: string; description?: string }\n> = {\n account: {\n label: \"Account\",\n keywords: \"profile photo avatar identity signed in email name\",\n },\n llm: {\n label: \"LLM\",\n keywords:\n \"model claude gpt openai anthropic gemini api key provider ai engine llm\",\n },\n \"app-models\": {\n label: \"App Default Model\",\n keywords: \"default model provider app template composer\",\n },\n limits: {\n label: \"Agent Limits\",\n keywords: \"max iterations budget loop timeout runtime\",\n },\n voice: {\n label: \"Voice Transcription\",\n keywords: \"microphone dictation speech to text whisper\",\n },\n \"demo-mode\": {\n label: \"Demo mode\",\n keywords: \"fake data anonymize redact screenshot privacy mask\",\n },\n automations: {\n label: \"Automations\",\n keywords: \"triggers scheduled events cron jobs\",\n },\n secrets: {\n label: \"API Keys & Connections\",\n keywords: \"secrets credentials tokens api keys environment variables\",\n },\n hosting: {\n label: \"Hosting\",\n keywords: \"deploy netlify vercel cloudflare builder nitro\",\n },\n database: {\n label: \"Database\",\n keywords: \"postgres sqlite neon supabase turso storage sql pglite\",\n },\n uploads: {\n label: \"File uploads\",\n keywords: \"files storage s3 avatars attachments bucket blob\",\n },\n auth: {\n label: \"Authentication\",\n keywords: \"login signup oauth google github better auth access sso\",\n },\n email: {\n label: \"Email\",\n keywords: \"resend sendgrid smtp transactional notifications reports\",\n },\n browser: {\n label: \"Browser Automation\",\n keywords: \"web scraping playwright chrome headless\",\n },\n background: {\n label: \"Background Agent\",\n keywords: \"code changes branches builder production async\",\n },\n integrations: {\n label: \"Integrations\",\n keywords: \"slack telegram whatsapp discord messaging connect\",\n },\n usage: {\n label: \"Usage\",\n keywords: \"tokens cost spend billing consumption\",\n },\n a2a: {\n label: \"Connected Agents (A2A)\",\n keywords: \"remote agents protocol a2a connected\",\n },\n};\n\nexport function buildSectionSearchEntries(\n sections: readonly SettingsSectionId[],\n): SettingsSearchEntry[] {\n return sections.map((section) => {\n const meta = SETTINGS_SECTION_SEARCH_META[section];\n return {\n id: `section:${section}`,\n label: meta.label,\n keywords: meta.keywords,\n description: meta.description,\n hash: section,\n };\n });\n}\n\nexport interface AgentSettingsSearchTab {\n id: string;\n label: string;\n keywords: string;\n searchEntries?: SettingsSearchEntry[];\n}\n\nexport function getAgentSettingsSearchTabs(): AgentSettingsSearchTab[] {\n return [\n {\n id: \"agent\",\n label: \"Manage agent\",\n keywords:\n \"agent workspace manage agent model llm limits voice automations\",\n searchEntries: buildSectionSearchEntries(AGENT_SETTINGS_SECTIONS),\n },\n {\n id: \"connections\",\n label: \"Connections\",\n keywords: \"connections secrets integrations email browser usage\",\n searchEntries: buildSectionSearchEntries(CONNECTION_SETTINGS_SECTIONS),\n },\n {\n id: \"organization\",\n label: \"Organization\",\n keywords: \"organization org team members invites collaborators\",\n },\n {\n id: \"workspace\",\n label: \"Workspace\",\n keywords: \"workspace account hosting database uploads auth\",\n searchEntries: buildSectionSearchEntries(WORKSPACE_SETTINGS_SECTIONS),\n },\n ];\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { SettingsPanel, useAgentSettingsTabs, type SettingsPanelProps, } from "./SettingsPanel.js";
|
|
1
|
+
export { AgentSettingsContent, SettingsPanel, useAgentSettingsTabs, type SettingsPanelProps, } from "./SettingsPanel.js";
|
|
2
2
|
export { getAgentSettingsSearchTabs, type AgentSettingsSearchTab, } from "./agent-settings-search.js";
|
|
3
3
|
export { SettingsTabsPage, type SettingsSearchEntry, type SettingsTabItem, type SettingsTabsPageProps, } from "./SettingsTabsPage.js";
|
|
4
|
+
export { AccountSettingsCard, AccountSettingsForm, type AccountSettingsCardProps, type AccountSettingsFormProps, } from "./AccountSettingsCard.js";
|
|
4
5
|
export { openBuilderConnectPopup, useBuilderConnectFlow, useBuilderStatus, withBuilderConnectTrackingParams, type BuilderConnectFlow, type BuilderConnectFlowOptions, type BuilderConnectStartOptions, type BuilderStatus, type OpenBuilderConnectPopupOptions, } from "./useBuilderStatus.js";
|
|
5
6
|
export { SecretsSection, type SecretsSectionProps } from "./SecretsSection.js";
|
|
6
7
|
export { normalizeSettingsSection, settingsSectionDomId, useSettingsPanelController, type SettingsPanelController, type SettingsPanelControllerOptions, } from "./useSettingsPanelController.js";
|
|
@@ -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,0BAA0B,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,4BAA4B,CAAC;AACpC,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;AAC/E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,GACpC,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,0BAA0B,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,0BAA0B,CAAC;AAClC,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;AAC/E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,GACpC,MAAM,iCAAiC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { SettingsPanel, useAgentSettingsTabs, } from "./SettingsPanel.js";
|
|
1
|
+
export { AgentSettingsContent, SettingsPanel, useAgentSettingsTabs, } from "./SettingsPanel.js";
|
|
2
2
|
export { getAgentSettingsSearchTabs, } from "./agent-settings-search.js";
|
|
3
3
|
export { SettingsTabsPage, } from "./SettingsTabsPage.js";
|
|
4
|
+
export { AccountSettingsCard, AccountSettingsForm, } from "./AccountSettingsCard.js";
|
|
4
5
|
export { openBuilderConnectPopup, useBuilderConnectFlow, useBuilderStatus, withBuilderConnectTrackingParams, } from "./useBuilderStatus.js";
|
|
5
6
|
export { SecretsSection } from "./SecretsSection.js";
|
|
6
7
|
export { normalizeSettingsSection, settingsSectionDomId, useSettingsPanelController, } from "./useSettingsPanelController.js";
|
|
@@ -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,0BAA0B,GAE3B,MAAM,4BAA4B,CAAC;AACpC,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;AAC/E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,iCAAiC,CAAC","sourcesContent":["export {\n SettingsPanel,\n useAgentSettingsTabs,\n type SettingsPanelProps,\n} from \"./SettingsPanel.js\";\nexport {\n getAgentSettingsSearchTabs,\n type AgentSettingsSearchTab,\n} from \"./agent-settings-search.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\";\nexport {\n normalizeSettingsSection,\n settingsSectionDomId,\n useSettingsPanelController,\n type SettingsPanelController,\n type SettingsPanelControllerOptions,\n} from \"./useSettingsPanelController.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,0BAA0B,GAE3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,GAIjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,GAMjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAA4B,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,iCAAiC,CAAC","sourcesContent":["export {\n AgentSettingsContent,\n SettingsPanel,\n useAgentSettingsTabs,\n type SettingsPanelProps,\n} from \"./SettingsPanel.js\";\nexport {\n getAgentSettingsSearchTabs,\n type AgentSettingsSearchTab,\n} from \"./agent-settings-search.js\";\nexport {\n SettingsTabsPage,\n type SettingsSearchEntry,\n type SettingsTabItem,\n type SettingsTabsPageProps,\n} from \"./SettingsTabsPage.js\";\nexport {\n AccountSettingsCard,\n AccountSettingsForm,\n type AccountSettingsCardProps,\n type AccountSettingsFormProps,\n} from \"./AccountSettingsCard.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\";\nexport {\n normalizeSettingsSection,\n settingsSectionDomId,\n useSettingsPanelController,\n type SettingsPanelController,\n type SettingsPanelControllerOptions,\n} from \"./useSettingsPanelController.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-dev-recovery-script.d.ts","sourceRoot":"","sources":["../../src/client/vite-dev-recovery-script.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"vite-dev-recovery-script.d.ts","sourceRoot":"","sources":["../../src/client/vite-dev-recovery-script.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAqNjD;AAED,wBAAgB,iCAAiC,IAAI,OAAO,CAe3D"}
|
|
@@ -17,8 +17,13 @@ export function getViteDevRecoveryScript() {
|
|
|
17
17
|
if (params.has(${embedTokenParam}) || embedded === "1" || embedded === "true") return;
|
|
18
18
|
} catch (e) {}
|
|
19
19
|
|
|
20
|
+
var INSTALL_KEY = "__agentNativeViteDevRecoveryInstalled";
|
|
21
|
+
if (window[INSTALL_KEY]) return;
|
|
22
|
+
window[INSTALL_KEY] = true;
|
|
23
|
+
|
|
20
24
|
var RELOAD_KEY = "__an_optimize_reload";
|
|
21
25
|
var MAX_RELOADS = 3;
|
|
26
|
+
var MIN_RELOAD_INTERVAL_MS = 2000;
|
|
22
27
|
var RESET_AFTER_MS = 8000;
|
|
23
28
|
|
|
24
29
|
var reloadTimer = null;
|
|
@@ -95,9 +100,21 @@ export function getViteDevRecoveryScript() {
|
|
|
95
100
|
if (history.length >= 1) {
|
|
96
101
|
showOverlay("Updating dev server\\u2026", "Reloading the page");
|
|
97
102
|
}
|
|
98
|
-
|
|
103
|
+
var lastReloadAt = history.length ? history[history.length - 1] : 0;
|
|
104
|
+
var delay = Math.max(
|
|
105
|
+
300,
|
|
106
|
+
MIN_RELOAD_INTERVAL_MS - Math.max(0, Date.now() - lastReloadAt),
|
|
107
|
+
);
|
|
108
|
+
reloadTimer = setTimeout(function() { window.location.reload(); }, delay);
|
|
99
109
|
}
|
|
100
110
|
|
|
111
|
+
window.addEventListener("vite:beforeFullReload", function() {
|
|
112
|
+
if (reloadTimer) {
|
|
113
|
+
clearTimeout(reloadTimer);
|
|
114
|
+
reloadTimer = null;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
101
118
|
function looksLikeViteFailureMessage(message) {
|
|
102
119
|
if (!message) return false;
|
|
103
120
|
return message.indexOf("Failed to fetch dynamically imported module") !== -1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-dev-recovery-script.js","sourceRoot":"","sources":["../../src/client/vite-dev-recovery-script.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAEhE,OAAO;;;;gCAIuB,cAAc;qBACzB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA0L9B,CAAC;AACP,CAAC;AAED,MAAM,UAAU,iCAAiC;IAC/C,MAAM,OAAO,GACX,OAAO,IAGR,CAAC,GAAG,CAAC;IACN,IACE,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,YAAY,EACtC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,OAAO,EAAE,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import {\n EMBED_MODE_QUERY_PARAM,\n EMBED_TOKEN_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\n\n/**\n * Synchronous dev-only browser recovery for Vite optimized-dependency races.\n *\n * Keep this script dependency-free and non-module-safe: React Router SSR roots\n * inline it before `<Scripts />`, and the Vite plugin injects it at\n * `head-prepend` for HTML that does pass through transformIndexHtml.\n */\nexport function getViteDevRecoveryScript(): string {\n const embedModeParam = JSON.stringify(EMBED_MODE_QUERY_PARAM);\n const embedTokenParam = JSON.stringify(EMBED_TOKEN_QUERY_PARAM);\n\n return `\n(function() {\n try {\n var params = new URLSearchParams(window.location.search || \"\");\n var embedded = params.get(${embedModeParam});\n if (params.has(${embedTokenParam}) || embedded === \"1\" || embedded === \"true\") return;\n } catch (e) {}\n\n var RELOAD_KEY = \"__an_optimize_reload\";\n var MAX_RELOADS = 3;\n var RESET_AFTER_MS = 8000;\n\n var reloadTimer = null;\n var overlayShown = false;\n\n // Track recent reloads in sessionStorage. If we reload too many times\n // in a short window, stop and show a manual-refresh message instead of\n // looping forever.\n function readReloadHistory() {\n try {\n var raw = sessionStorage.getItem(RELOAD_KEY);\n if (!raw) return [];\n var arr = JSON.parse(raw);\n var cutoff = Date.now() - 30000;\n return Array.isArray(arr) ? arr.filter(function(t) { return t > cutoff; }) : [];\n } catch (e) { return []; }\n }\n function recordReload() {\n try {\n var history = readReloadHistory();\n history.push(Date.now());\n sessionStorage.setItem(RELOAD_KEY, JSON.stringify(history));\n } catch (e) {}\n }\n // Reset the counter after a stable period (page didn't fail again).\n setTimeout(function() {\n try { sessionStorage.removeItem(RELOAD_KEY); } catch (e) {}\n }, RESET_AFTER_MS);\n\n function showOverlay(title, subtitle) {\n if (overlayShown) return;\n overlayShown = true;\n var mount = function() {\n if (!document.body) { setTimeout(mount, 16); return; }\n var el = document.createElement(\"div\");\n el.id = \"__an-reload-overlay\";\n el.style.cssText = [\n \"position:fixed\",\"inset:0\",\"z-index:2147483647\",\n \"display:flex\",\"align-items:center\",\"justify-content:center\",\n \"background:rgba(0,0,0,0.6)\",\"backdrop-filter:blur(8px)\",\n \"-webkit-backdrop-filter:blur(8px)\",\n \"font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif\",\n \"color:#fff\",\"font-size:14px\"\n ].join(\";\");\n el.innerHTML =\n '<div style=\"background:#171717;padding:20px 24px;border-radius:12px;' +\n 'border:1px solid rgba(255,255,255,0.1);max-width:340px;text-align:center;' +\n 'box-shadow:0 20px 60px rgba(0,0,0,0.5)\">' +\n '<div style=\"font-weight:600;margin-bottom:6px\">' + title + '</div>' +\n '<div style=\"font-size:12px;opacity:0.7\">' + subtitle + '</div>' +\n '</div>';\n document.body.appendChild(el);\n };\n mount();\n }\n\n function scheduleReload(reason) {\n if (reloadTimer) return;\n var history = readReloadHistory();\n if (history.length >= MAX_RELOADS) {\n console.warn(\"[agent-native] Dev server keeps re-bundling. Manual refresh needed.\", reason);\n showOverlay(\n \"Dev server out of sync\",\n \"Auto-reload gave up after \" + MAX_RELOADS + \" tries. Refresh the page (\\\\u2318R / Ctrl+R).\"\n );\n return;\n }\n console.log(\"[agent-native] Vite re-bundled deps (\" + reason + \"), reloading\\\\u2026\");\n recordReload();\n // First reload is silent. One refresh almost always fixes it and the\n // overlay flash is more disruptive than the reload itself. Only show\n // the overlay starting on the second attempt, when something is clearly\n // taking longer than expected.\n if (history.length >= 1) {\n showOverlay(\"Updating dev server\\\\u2026\", \"Reloading the page\");\n }\n reloadTimer = setTimeout(function() { window.location.reload(); }, 300);\n }\n\n function looksLikeViteFailureMessage(message) {\n if (!message) return false;\n return message.indexOf(\"Failed to fetch dynamically imported module\") !== -1\n || message.indexOf(\"error loading dynamically imported module\") !== -1\n || message.indexOf(\"Importing a module script failed\") !== -1\n || message.indexOf(\"Outdated Optimize Dep\") !== -1\n || message.indexOf(\"Optimize Deps Processing Error\") !== -1\n || (message.indexOf(\"504\") !== -1 && (\n message.indexOf(\".vite/deps\") !== -1 ||\n message.indexOf(\"/node_modules/.vite/deps/\") !== -1\n ));\n }\n\n function looksLikeViteDep(url) {\n if (!url) return false;\n // Only treat same-origin URLs as Vite deps. Do not reload the page\n // because some third-party CDN script 404'd.\n try {\n var u = new URL(url, window.location.href);\n if (u.origin !== window.location.origin) return false;\n } catch (e) { return false; }\n return url.indexOf(\"/node_modules/.vite/deps/\") !== -1\n || url.indexOf(\"/@fs/\") !== -1\n || url.indexOf(\"/@id/\") !== -1\n || url.indexOf(\"?v=\") !== -1\n || url.indexOf(\"?import\") !== -1\n || /\\\\.(m?js|ts|tsx|jsx)(\\\\?|$)/.test(url);\n }\n\n // 1) <script type=\"module\"> / <link> 504. These fire on the element, not\n // window, so use capture phase to catch resource load errors.\n window.addEventListener(\"error\", function(e) {\n var t = e.target;\n if (!t || t === window) {\n var message = String(e.message || \"\");\n if (looksLikeViteFailureMessage(message)) {\n scheduleReload(\"window error\");\n }\n return;\n }\n var tag = t.tagName;\n if (tag !== \"SCRIPT\" && tag !== \"LINK\") return;\n var url = t.src || t.href || \"\";\n if (looksLikeViteDep(url)) {\n var name = url.split(\"/\").pop();\n scheduleReload(\"script 504: \" + name);\n }\n }, true);\n\n // Vite's documented hook for failed dynamic-import preloads. This mostly\n // targets production chunk skew, but it also fires for some dev optimizer\n // races, so wire it into the same guarded reload path.\n window.addEventListener(\"vite:preloadError\", function(e) {\n var payload = e && e.payload;\n var msg = String((payload && (payload.message || payload)) || \"\");\n if (!msg || looksLikeViteFailureMessage(msg)) {\n if (e.preventDefault) e.preventDefault();\n scheduleReload(\"preload error\");\n }\n });\n\n // 2) Dynamic import failures (React Router code splitting, lazy components).\n window.addEventListener(\"unhandledrejection\", function(e) {\n var msg = String((e.reason && (e.reason.message || e.reason)) || \"\");\n if (looksLikeViteFailureMessage(msg)) {\n scheduleReload(\"dynamic import\");\n }\n });\n\n // Static module-graph fetch failures for child imports don't always surface\n // as element errors or rejections. Chrome exposes the HTTP status via\n // Resource Timing; when available, use it as a final safety net.\n var seenResources = {};\n function checkResourceEntry(entry) {\n var url = entry && entry.name;\n if (!url || seenResources[url]) return;\n seenResources[url] = true;\n if (!looksLikeViteDep(url)) return;\n if (entry.responseStatus === 504) {\n var name = url.split(\"/\").pop();\n scheduleReload(\"resource 504: \" + name);\n }\n }\n function checkExistingResources() {\n try {\n var entries = performance.getEntriesByType(\"resource\") || [];\n for (var i = 0; i < entries.length; i++) checkResourceEntry(entries[i]);\n } catch (e) {}\n }\n if (window.PerformanceObserver) {\n try {\n var observer = new PerformanceObserver(function(list) {\n var entries = list.getEntries();\n for (var i = 0; i < entries.length; i++) checkResourceEntry(entries[i]);\n });\n observer.observe({ type: \"resource\", buffered: true });\n } catch (e) {\n setTimeout(checkExistingResources, 0);\n }\n } else {\n setTimeout(checkExistingResources, 0);\n }\n})();`;\n}\n\nexport function shouldInlineViteDevRecoveryScript(): boolean {\n const viteEnv = (\n import.meta as ImportMeta & {\n env?: { DEV?: boolean; PROD?: boolean };\n }\n ).env;\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"production\"\n ) {\n return false;\n }\n if (viteEnv?.PROD === true) return false;\n if (viteEnv?.DEV === true) return true;\n return true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"vite-dev-recovery-script.js","sourceRoot":"","sources":["../../src/client/vite-dev-recovery-script.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAEhE,OAAO;;;;gCAIuB,cAAc;qBACzB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2M9B,CAAC;AACP,CAAC;AAED,MAAM,UAAU,iCAAiC;IAC/C,MAAM,OAAO,GACX,OAAO,IAGR,CAAC,GAAG,CAAC;IACN,IACE,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,YAAY,EACtC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,OAAO,EAAE,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import {\n EMBED_MODE_QUERY_PARAM,\n EMBED_TOKEN_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\n\n/**\n * Synchronous dev-only browser recovery for Vite optimized-dependency races.\n *\n * Keep this script dependency-free and non-module-safe: React Router SSR roots\n * inline it before `<Scripts />`, and the Vite plugin injects it at\n * `head-prepend` for HTML that does pass through transformIndexHtml.\n */\nexport function getViteDevRecoveryScript(): string {\n const embedModeParam = JSON.stringify(EMBED_MODE_QUERY_PARAM);\n const embedTokenParam = JSON.stringify(EMBED_TOKEN_QUERY_PARAM);\n\n return `\n(function() {\n try {\n var params = new URLSearchParams(window.location.search || \"\");\n var embedded = params.get(${embedModeParam});\n if (params.has(${embedTokenParam}) || embedded === \"1\" || embedded === \"true\") return;\n } catch (e) {}\n\n var INSTALL_KEY = \"__agentNativeViteDevRecoveryInstalled\";\n if (window[INSTALL_KEY]) return;\n window[INSTALL_KEY] = true;\n\n var RELOAD_KEY = \"__an_optimize_reload\";\n var MAX_RELOADS = 3;\n var MIN_RELOAD_INTERVAL_MS = 2000;\n var RESET_AFTER_MS = 8000;\n\n var reloadTimer = null;\n var overlayShown = false;\n\n // Track recent reloads in sessionStorage. If we reload too many times\n // in a short window, stop and show a manual-refresh message instead of\n // looping forever.\n function readReloadHistory() {\n try {\n var raw = sessionStorage.getItem(RELOAD_KEY);\n if (!raw) return [];\n var arr = JSON.parse(raw);\n var cutoff = Date.now() - 30000;\n return Array.isArray(arr) ? arr.filter(function(t) { return t > cutoff; }) : [];\n } catch (e) { return []; }\n }\n function recordReload() {\n try {\n var history = readReloadHistory();\n history.push(Date.now());\n sessionStorage.setItem(RELOAD_KEY, JSON.stringify(history));\n } catch (e) {}\n }\n // Reset the counter after a stable period (page didn't fail again).\n setTimeout(function() {\n try { sessionStorage.removeItem(RELOAD_KEY); } catch (e) {}\n }, RESET_AFTER_MS);\n\n function showOverlay(title, subtitle) {\n if (overlayShown) return;\n overlayShown = true;\n var mount = function() {\n if (!document.body) { setTimeout(mount, 16); return; }\n var el = document.createElement(\"div\");\n el.id = \"__an-reload-overlay\";\n el.style.cssText = [\n \"position:fixed\",\"inset:0\",\"z-index:2147483647\",\n \"display:flex\",\"align-items:center\",\"justify-content:center\",\n \"background:rgba(0,0,0,0.6)\",\"backdrop-filter:blur(8px)\",\n \"-webkit-backdrop-filter:blur(8px)\",\n \"font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif\",\n \"color:#fff\",\"font-size:14px\"\n ].join(\";\");\n el.innerHTML =\n '<div style=\"background:#171717;padding:20px 24px;border-radius:12px;' +\n 'border:1px solid rgba(255,255,255,0.1);max-width:340px;text-align:center;' +\n 'box-shadow:0 20px 60px rgba(0,0,0,0.5)\">' +\n '<div style=\"font-weight:600;margin-bottom:6px\">' + title + '</div>' +\n '<div style=\"font-size:12px;opacity:0.7\">' + subtitle + '</div>' +\n '</div>';\n document.body.appendChild(el);\n };\n mount();\n }\n\n function scheduleReload(reason) {\n if (reloadTimer) return;\n var history = readReloadHistory();\n if (history.length >= MAX_RELOADS) {\n console.warn(\"[agent-native] Dev server keeps re-bundling. Manual refresh needed.\", reason);\n showOverlay(\n \"Dev server out of sync\",\n \"Auto-reload gave up after \" + MAX_RELOADS + \" tries. Refresh the page (\\\\u2318R / Ctrl+R).\"\n );\n return;\n }\n console.log(\"[agent-native] Vite re-bundled deps (\" + reason + \"), reloading\\\\u2026\");\n recordReload();\n // First reload is silent. One refresh almost always fixes it and the\n // overlay flash is more disruptive than the reload itself. Only show\n // the overlay starting on the second attempt, when something is clearly\n // taking longer than expected.\n if (history.length >= 1) {\n showOverlay(\"Updating dev server\\\\u2026\", \"Reloading the page\");\n }\n var lastReloadAt = history.length ? history[history.length - 1] : 0;\n var delay = Math.max(\n 300,\n MIN_RELOAD_INTERVAL_MS - Math.max(0, Date.now() - lastReloadAt),\n );\n reloadTimer = setTimeout(function() { window.location.reload(); }, delay);\n }\n\n window.addEventListener(\"vite:beforeFullReload\", function() {\n if (reloadTimer) {\n clearTimeout(reloadTimer);\n reloadTimer = null;\n }\n });\n\n function looksLikeViteFailureMessage(message) {\n if (!message) return false;\n return message.indexOf(\"Failed to fetch dynamically imported module\") !== -1\n || message.indexOf(\"error loading dynamically imported module\") !== -1\n || message.indexOf(\"Importing a module script failed\") !== -1\n || message.indexOf(\"Outdated Optimize Dep\") !== -1\n || message.indexOf(\"Optimize Deps Processing Error\") !== -1\n || (message.indexOf(\"504\") !== -1 && (\n message.indexOf(\".vite/deps\") !== -1 ||\n message.indexOf(\"/node_modules/.vite/deps/\") !== -1\n ));\n }\n\n function looksLikeViteDep(url) {\n if (!url) return false;\n // Only treat same-origin URLs as Vite deps. Do not reload the page\n // because some third-party CDN script 404'd.\n try {\n var u = new URL(url, window.location.href);\n if (u.origin !== window.location.origin) return false;\n } catch (e) { return false; }\n return url.indexOf(\"/node_modules/.vite/deps/\") !== -1\n || url.indexOf(\"/@fs/\") !== -1\n || url.indexOf(\"/@id/\") !== -1\n || url.indexOf(\"?v=\") !== -1\n || url.indexOf(\"?import\") !== -1\n || /\\\\.(m?js|ts|tsx|jsx)(\\\\?|$)/.test(url);\n }\n\n // 1) <script type=\"module\"> / <link> 504. These fire on the element, not\n // window, so use capture phase to catch resource load errors.\n window.addEventListener(\"error\", function(e) {\n var t = e.target;\n if (!t || t === window) {\n var message = String(e.message || \"\");\n if (looksLikeViteFailureMessage(message)) {\n scheduleReload(\"window error\");\n }\n return;\n }\n var tag = t.tagName;\n if (tag !== \"SCRIPT\" && tag !== \"LINK\") return;\n var url = t.src || t.href || \"\";\n if (looksLikeViteDep(url)) {\n var name = url.split(\"/\").pop();\n scheduleReload(\"script 504: \" + name);\n }\n }, true);\n\n // Vite's documented hook for failed dynamic-import preloads. This mostly\n // targets production chunk skew, but it also fires for some dev optimizer\n // races, so wire it into the same guarded reload path.\n window.addEventListener(\"vite:preloadError\", function(e) {\n var payload = e && e.payload;\n var msg = String((payload && (payload.message || payload)) || \"\");\n if (!msg || looksLikeViteFailureMessage(msg)) {\n if (e.preventDefault) e.preventDefault();\n scheduleReload(\"preload error\");\n }\n });\n\n // 2) Dynamic import failures (React Router code splitting, lazy components).\n window.addEventListener(\"unhandledrejection\", function(e) {\n var msg = String((e.reason && (e.reason.message || e.reason)) || \"\");\n if (looksLikeViteFailureMessage(msg)) {\n scheduleReload(\"dynamic import\");\n }\n });\n\n // Static module-graph fetch failures for child imports don't always surface\n // as element errors or rejections. Chrome exposes the HTTP status via\n // Resource Timing; when available, use it as a final safety net.\n var seenResources = {};\n function checkResourceEntry(entry) {\n var url = entry && entry.name;\n if (!url || seenResources[url]) return;\n seenResources[url] = true;\n if (!looksLikeViteDep(url)) return;\n if (entry.responseStatus === 504) {\n var name = url.split(\"/\").pop();\n scheduleReload(\"resource 504: \" + name);\n }\n }\n function checkExistingResources() {\n try {\n var entries = performance.getEntriesByType(\"resource\") || [];\n for (var i = 0; i < entries.length; i++) checkResourceEntry(entries[i]);\n } catch (e) {}\n }\n if (window.PerformanceObserver) {\n try {\n var observer = new PerformanceObserver(function(list) {\n var entries = list.getEntries();\n for (var i = 0; i < entries.length; i++) checkResourceEntry(entries[i]);\n });\n observer.observe({ type: \"resource\", buffered: true });\n } catch (e) {\n setTimeout(checkExistingResources, 0);\n }\n } else {\n setTimeout(checkExistingResources, 0);\n }\n})();`;\n}\n\nexport function shouldInlineViteDevRecoveryScript(): boolean {\n const viteEnv = (\n import.meta as ImportMeta & {\n env?: { DEV?: boolean; PROD?: boolean };\n }\n ).env;\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"production\"\n ) {\n return false;\n }\n if (viteEnv?.PROD === true) return false;\n if (viteEnv?.DEV === true) return true;\n return true;\n}\n"]}
|
|
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
62
62
|
error: string;
|
|
63
63
|
states?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
states: {
|
|
66
67
|
clientId: number;
|
|
67
68
|
state: string;
|
|
68
69
|
}[];
|
|
69
|
-
error?: undefined;
|
|
70
70
|
}>>;
|
|
71
71
|
/**
|
|
72
72
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -77,10 +77,10 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
77
77
|
error: string;
|
|
78
78
|
users?: undefined;
|
|
79
79
|
} | {
|
|
80
|
+
error?: undefined;
|
|
80
81
|
users: {
|
|
81
82
|
clientId: number;
|
|
82
83
|
lastSeen: number;
|
|
83
84
|
}[];
|
|
84
|
-
error?: undefined;
|
|
85
85
|
}>>;
|
|
86
86
|
//# sourceMappingURL=awareness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgB3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAChC,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,cAAc,GACrB,IAAI,CAgBN;AAoBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAmB,GAC7B,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE1E;AAiBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAkCD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgB3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAChC,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,cAAc,GACrB,IAAI,CAgBN;AAoBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAmB,GAC7B,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE1E;AAiBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAkCD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;kBAwDa,MAAM;eAAS,MAAM;;GAoB1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;kBAYM,MAAM;kBAAY,MAAM;;GAMvD,CAAC"}
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
error: string;
|
|
30
29
|
ok?: undefined;
|
|
30
|
+
error: string;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|