From 812ceedeb29d6931ece7526915ee0436b82d5183 Mon Sep 17 00:00:00 2001 From: GCWing Date: Sat, 25 Jul 2026 00:32:02 +0800 Subject: [PATCH 1/3] ci: remove Linux desktop packages --- .github/workflows/desktop-package.yml | 46 --------------------------- .github/workflows/nightly.yml | 46 --------------------------- 2 files changed, 92 deletions(-) diff --git a/.github/workflows/desktop-package.yml b/.github/workflows/desktop-package.yml index 85f16578..268e5785 100644 --- a/.github/workflows/desktop-package.yml +++ b/.github/workflows/desktop-package.yml @@ -86,14 +86,6 @@ jobs: fail-fast: false matrix: platform: - - os: ubuntu-latest - name: linux-x64 - target: x86_64-unknown-linux-gnu - build_command: pnpm run desktop:build:linux -- --target x86_64-unknown-linux-gnu --bundles deb,rpm,appimage - - os: ubuntu-24.04-arm - name: linux-arm64 - target: aarch64-unknown-linux-gnu - build_command: pnpm run desktop:build:linux -- --target aarch64-unknown-linux-gnu --bundles deb,rpm,appimage - os: macos-15 name: macos-arm64 target: aarch64-apple-darwin @@ -118,41 +110,6 @@ jobs: shell: pwsh run: ./scripts/ci/setup-openssl-windows.ps1 - - name: Install Linux system dependencies (Tauri bundler) - if: runner.os == 'Linux' - shell: bash - run: | - sudo apt-get update - - if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then - WEBKIT_PKG=libwebkit2gtk-4.1-dev - else - WEBKIT_PKG=libwebkit2gtk-4.0-dev - fi - - if apt-cache show libappindicator3-dev >/dev/null 2>&1; then - APPINDICATOR_PKG=libappindicator3-dev - else - APPINDICATOR_PKG=libayatana-appindicator3-dev - fi - - sudo apt-get install -y --no-install-recommends \ - pkg-config \ - xdg-utils \ - libglib2.0-dev \ - libgtk-3-dev \ - libxdo-dev \ - "$WEBKIT_PKG" \ - "$APPINDICATOR_PKG" \ - librsvg2-dev \ - patchelf \ - fakeroot \ - rpm \ - libleptonica-dev \ - libtesseract-dev \ - tesseract-ocr \ - tesseract-ocr-eng - - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -214,9 +171,6 @@ jobs: with: tag_name: ${{ needs.prepare.outputs.release_tag }} files: | - release-assets/**/*.AppImage - release-assets/**/*.deb release-assets/**/*.dmg - release-assets/**/*.rpm release-assets/**/*sparo-installer.exe fail_on_unmatched_files: true diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 83f6b376..5825d753 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -72,14 +72,6 @@ jobs: fail-fast: false matrix: platform: - - os: ubuntu-latest - name: linux-x64 - target: x86_64-unknown-linux-gnu - build_command: pnpm run desktop:build:linux -- --target x86_64-unknown-linux-gnu --bundles deb,rpm,appimage - - os: ubuntu-24.04-arm - name: linux-arm64 - target: aarch64-unknown-linux-gnu - build_command: pnpm run desktop:build:linux -- --target aarch64-unknown-linux-gnu --bundles deb,rpm,appimage - os: macos-15 name: macos-arm64 target: aarch64-apple-darwin @@ -101,41 +93,6 @@ jobs: shell: pwsh run: ./scripts/ci/setup-openssl-windows.ps1 - - name: Install Linux system dependencies (Tauri bundler) - if: runner.os == 'Linux' - shell: bash - run: | - sudo apt-get update - - if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then - WEBKIT_PKG=libwebkit2gtk-4.1-dev - else - WEBKIT_PKG=libwebkit2gtk-4.0-dev - fi - - if apt-cache show libappindicator3-dev >/dev/null 2>&1; then - APPINDICATOR_PKG=libappindicator3-dev - else - APPINDICATOR_PKG=libayatana-appindicator3-dev - fi - - sudo apt-get install -y --no-install-recommends \ - pkg-config \ - xdg-utils \ - libglib2.0-dev \ - libgtk-3-dev \ - libxdo-dev \ - "$WEBKIT_PKG" \ - "$APPINDICATOR_PKG" \ - librsvg2-dev \ - patchelf \ - fakeroot \ - rpm \ - libleptonica-dev \ - libtesseract-dev \ - tesseract-ocr \ - tesseract-ocr-eng - - name: Setup pnpm uses: pnpm/action-setup@v4 @@ -242,8 +199,5 @@ jobs: > **Warning**: Nightly builds are untested and may be unstable. prerelease: true files: | - release-assets/**/*.AppImage - release-assets/**/*.deb release-assets/**/*.dmg - release-assets/**/*.rpm release-assets/**/*sparo-installer.exe From b87a17b8028b56cf7cc27b1e7f498b9c24c8a169 Mon Sep 17 00:00:00 2001 From: GCWing Date: Sat, 25 Jul 2026 00:53:15 +0800 Subject: [PATCH 2/3] refactor: unify auxiliary surfaces and refresh design preview --- .../source/src/vendor/ppt-export.bundle.mjs | 6 +- src/apps/desktop/src/theme.rs | 71 +- .../implementations/generative_ui_tool.rs | 70 +- src/crates/core/src/service/config/catalog.rs | 23 +- src/crates/core/src/service/config/manager.rs | 39 + .../dist-preview/assets/index-C_s2NvXm.js | 2 + .../dist-preview/assets/index-DNunTB6S.js | 1 + .../dist-preview/assets/index-DgcE1LoE.js | 1 + .../dist-preview/assets/preview-CMlHD2Qb.css | 1 + .../dist-preview/assets/preview-DWC_IH0E.js | 1031 +++++++++++++++++ src/web-ui/dist-preview/preview.html | 14 + .../work/navigation/openWork.test.ts | 14 + .../agentic-os/work/navigation/openWork.ts | 9 +- .../AuxiliarySurfaceCoordinator.tsx | 145 +++ .../auxiliarySurface.test.ts | 148 +++ .../auxiliarySurfaceStore.ts | 180 +++ .../src/app/auxiliary-surface/controller.ts | 121 ++ src/web-ui/src/app/auxiliary-surface/host.ts | 27 + src/web-ui/src/app/auxiliary-surface/index.ts | 33 + .../app/auxiliary-surface/navigationSync.ts | 25 + src/web-ui/src/app/auxiliary-surface/types.ts | 24 + .../src/app/components/WorkDock/WorkDock.scss | 2 - .../src/app/components/WorkDock/WorkDock.tsx | 13 +- .../WorkspaceFooterActions.scss | 6 +- .../panels/content-canvas/ContentCanvas.tsx | 15 +- .../panels/content-canvas/hooks/README.md | 28 - .../panels/content-canvas/hooks/index.ts | 1 - .../hooks/usePanelTabCoordinator.ts | 433 ------- .../content-canvas/hooks/useTabLifecycle.ts | 84 +- .../components/panels/content-canvas/index.ts | 1 + .../panels/content-canvas/openCanvasItem.ts | 60 + .../content-canvas/stores/canvasStore.ts | 98 +- .../panels/content-canvas/stores/index.ts | 5 +- .../panels/content-canvas/types/content.ts | 24 +- .../panels/content-canvas/types/index.ts | 4 +- .../components/DailyLetterArrivalDock.tsx | 1 - src/web-ui/src/app/hooks/useApp.ts | 121 -- src/web-ui/src/app/layout/AppLayout.tsx | 7 +- src/web-ui/src/app/layout/WorkspaceBody.tsx | 2 + src/web-ui/src/app/layout/panelConfig.ts | 23 +- .../app/navigation/workspaceSurfaceStore.ts | 10 + .../useProductAppRuntimeBridge.ts | 5 +- .../app/scenes/daily-letter/LetterPaper.scss | 141 +-- .../app/scenes/daily-letter/LetterPaper.tsx | 220 ++-- .../app/scenes/panel-view/PanelViewScene.tsx | 2 +- src/web-ui/src/app/scenes/session/AuxPane.tsx | 175 +-- .../src/app/scenes/session/SessionScene.tsx | 244 ++-- src/web-ui/src/app/scenes/session/index.ts | 1 - src/web-ui/src/app/services/AppManager.ts | 127 +- src/web-ui/src/app/session-profiles/index.ts | 2 +- .../profiles/agenticOsProfile.ts | 10 +- .../profiles/appBuilderProfile.ts | 12 +- .../profiles/bitfunCoderProfile.ts | 10 +- .../profiles/coworkProfile.ts | 8 +- .../profiles/deepResearchProfile.ts | 8 +- .../profiles/designProfile.ts | 8 +- .../profiles/productAppRuntimeProfile.ts | 15 +- .../session-profiles/profiles/runnoProfile.ts | 8 +- .../profiles/settingsProfile.ts | 8 +- .../sidecarActionController.ts | 87 +- src/web-ui/src/app/session-profiles/types.ts | 37 +- src/web-ui/src/app/types/index.ts | 47 - .../design-system/preview/FocusedPreview.css | 262 +++++ .../design-system/preview/FocusedPreview.tsx | 124 ++ .../src/design-system/preview/PreviewApp.tsx | 463 ++++++-- .../preview/PreviewUsageGuide.tsx | 53 +- src/web-ui/src/design-system/preview/main.tsx | 8 +- .../src/design-system/preview/preview.css | 909 ++++++++++----- .../preview/registries/patterns.tsx | 110 +- .../flow_chat/components/CopyOutputButton.tsx | 36 +- .../child-session/ChildSessionPanel.tsx | 1 - .../modern/SessionFileModificationsBar.tsx | 34 +- .../components/modern/SessionFilesBadge.tsx | 35 +- .../modern/useSessionSidecarActions.ts | 4 +- .../domain/composerContextRegistry.ts | 8 +- .../flow_chat/services/childSessionPanels.ts | 37 +- .../ComponentAuthoringToolDisplay.tsx | 9 +- .../CreateProductAppToolDisplay.tsx | 8 +- .../flow_chat/tool-cards/TaskToolDisplay.tsx | 5 +- .../flow_chat/tool-cards/TerminalToolCard.tsx | 2 +- .../src/infrastructure/i18n/constants.ts | 1 + .../theme/core/ThemeService.test.ts | 15 +- .../theme/presets/china-night-theme.ts | 357 ------ .../theme/presets/china-style-theme.ts | 361 ------ .../theme/presets/cyber-theme.ts | 344 ------ .../src/infrastructure/theme/presets/index.ts | 19 - .../theme/presets/slate-theme.ts | 363 ------ .../locales/en-US/design-system/preview.json | 188 +++ .../locales/en-US/settings/appearance.json | 16 - .../locales/zh-CN/design-system/preview.json | 188 +++ .../locales/zh-CN/settings/appearance.json | 16 - src/web-ui/src/shared/constants/app.ts | 2 - .../src/shared/services/FileTabManager.ts | 63 +- .../services/ide-control/PanelController.ts | 114 +- .../src/shared/services/ide-control/api.ts | 26 +- .../src/shared/services/ide-control/types.ts | 1 - .../src/shared/services/pendingTabQueue.ts | 42 - .../services/sceneOpenTargetResolver.test.ts | 4 +- .../services/sceneOpenTargetResolver.ts | 33 +- src/web-ui/src/shared/utils/tabUtils.ts | 81 +- .../design-canvas/DesignArtifactBrowser.tsx | 2 +- .../editor/services/MonacoInitManager.ts | 11 +- 102 files changed, 4367 insertions(+), 4086 deletions(-) create mode 100644 src/web-ui/dist-preview/assets/index-C_s2NvXm.js create mode 100644 src/web-ui/dist-preview/assets/index-DNunTB6S.js create mode 100644 src/web-ui/dist-preview/assets/index-DgcE1LoE.js create mode 100644 src/web-ui/dist-preview/assets/preview-CMlHD2Qb.css create mode 100644 src/web-ui/dist-preview/assets/preview-DWC_IH0E.js create mode 100644 src/web-ui/dist-preview/preview.html create mode 100644 src/web-ui/src/app/auxiliary-surface/AuxiliarySurfaceCoordinator.tsx create mode 100644 src/web-ui/src/app/auxiliary-surface/auxiliarySurface.test.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/auxiliarySurfaceStore.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/controller.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/host.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/index.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/navigationSync.ts create mode 100644 src/web-ui/src/app/auxiliary-surface/types.ts delete mode 100644 src/web-ui/src/app/components/panels/content-canvas/hooks/README.md delete mode 100644 src/web-ui/src/app/components/panels/content-canvas/hooks/usePanelTabCoordinator.ts create mode 100644 src/web-ui/src/app/components/panels/content-canvas/openCanvasItem.ts create mode 100644 src/web-ui/src/design-system/preview/FocusedPreview.css create mode 100644 src/web-ui/src/design-system/preview/FocusedPreview.tsx delete mode 100644 src/web-ui/src/infrastructure/theme/presets/china-night-theme.ts delete mode 100644 src/web-ui/src/infrastructure/theme/presets/china-style-theme.ts delete mode 100644 src/web-ui/src/infrastructure/theme/presets/cyber-theme.ts delete mode 100644 src/web-ui/src/infrastructure/theme/presets/slate-theme.ts create mode 100644 src/web-ui/src/locales/en-US/design-system/preview.json create mode 100644 src/web-ui/src/locales/zh-CN/design-system/preview.json delete mode 100644 src/web-ui/src/shared/services/pendingTabQueue.ts diff --git a/bundles/product-apps/builtin-ppt-live/151.0.10/components/bridges/builtin-ppt-runtime/source/src/vendor/ppt-export.bundle.mjs b/bundles/product-apps/builtin-ppt-live/151.0.10/components/bridges/builtin-ppt-runtime/source/src/vendor/ppt-export.bundle.mjs index dc77014e..e285ee6b 100644 --- a/bundles/product-apps/builtin-ppt-live/151.0.10/components/bridges/builtin-ppt-runtime/source/src/vendor/ppt-export.bundle.mjs +++ b/bundles/product-apps/builtin-ppt-live/151.0.10/components/bridges/builtin-ppt-runtime/source/src/vendor/ppt-export.bundle.mjs @@ -7936,13 +7936,13 @@ export { jszip/dist/jszip.min.js: (*! - + JSZip v3.10.1 - A JavaScript class for generating and reading zip files - + (c) 2009-2016 Stuart Knightley Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. - + JSZip uses the library pako released under the MIT license : https://github.com/nodeca/pako/blob/main/LICENSE *) diff --git a/src/apps/desktop/src/theme.rs b/src/apps/desktop/src/theme.rs index 52680366..c351339f 100644 --- a/src/apps/desktop/src/theme.rs +++ b/src/apps/desktop/src/theme.rs @@ -33,16 +33,6 @@ pub struct ThemeConfig { impl ThemeConfig { pub fn get_builtin_theme(theme_id: &str) -> Option { match theme_id { - "slate" => Some(Self { - id: theme_id.to_string(), - bg_primary: "#14161a".to_string(), - bg_secondary: "#22262c".to_string(), - bg_scene: "#22262c".to_string(), - is_light: false, - text_primary: "#eef0f3".to_string(), - text_muted: "rgba(255, 255, 255, 0.4)".to_string(), - accent_color: "#B7372F".to_string(), - }), "dark" => Some(Self { id: theme_id.to_string(), bg_primary: "#0e0e10".to_string(), @@ -53,26 +43,6 @@ impl ThemeConfig { text_muted: "rgba(255, 255, 255, 0.4)".to_string(), accent_color: "#B7372F".to_string(), }), - "sparo-cyber" => Some(Self { - id: theme_id.to_string(), - bg_primary: "#101010".to_string(), - bg_secondary: "#151515".to_string(), - bg_scene: "#141414".to_string(), - is_light: false, - text_primary: "#e0f2ff".to_string(), - text_muted: "rgba(255, 255, 255, 0.4)".to_string(), - accent_color: "#00e6ff".to_string(), - }), - "sparo-china-night" => Some(Self { - id: theme_id.to_string(), - bg_primary: "#1a1814".to_string(), - bg_secondary: "#141210".to_string(), - bg_scene: "#1e1c17".to_string(), - is_light: false, - text_primary: "#e8e6e1".to_string(), - text_muted: "rgba(255, 255, 255, 0.4)".to_string(), - accent_color: "#c4a35a".to_string(), - }), "light" => Some(Self { id: theme_id.to_string(), bg_primary: "#F8FAFC".to_string(), @@ -83,16 +53,6 @@ impl ThemeConfig { text_muted: "#5B6B8C".to_string(), accent_color: "#B7372F".to_string(), }), - "sparo-china-style" => Some(Self { - id: theme_id.to_string(), - bg_primary: "#faf8f0".to_string(), - bg_secondary: "#f5f3e8".to_string(), - bg_scene: "#fdfcf6".to_string(), - is_light: true, - text_primary: "#1a1a1a".to_string(), - text_muted: "rgba(0, 0, 0, 0.5)".to_string(), - accent_color: "#2e5e8a".to_string(), - }), _ => None, } } @@ -169,13 +129,15 @@ impl ThemeConfig { } fn resolve_builtin_theme_id(theme_id: &str) -> &str { - if theme_id == "system" { - return match dark_light::detect() { + match theme_id { + "system" => match dark_light::detect() { Mode::Dark => "dark", Mode::Light | Mode::Default => "light", - }; + }, + "sparo-china-style" => "light", + "slate" | "sparo-china-night" | "sparo-cyber" => "dark", + _ => theme_id, } - theme_id } fn from_custom_theme(theme: &serde_json::Value) -> Result { @@ -346,6 +308,27 @@ mod tests { assert!(theme.is_light); } + #[test] + fn startup_config_maps_retired_builtin_themes_to_light_or_dark() { + let retired_light = ThemeConfig::from_startup_config_value(&json!({ + "themes": { + "current": "sparo-china-style" + } + })) + .expect("retired light theme should map to light"); + let retired_dark = ThemeConfig::from_startup_config_value(&json!({ + "themes": { + "current": "slate" + } + })) + .expect("retired dark theme should map to dark"); + + assert_eq!(retired_light.id, "light"); + assert!(retired_light.is_light); + assert_eq!(retired_dark.id, "dark"); + assert!(!retired_dark.is_light); + } + #[test] fn startup_config_uses_custom_theme_background() { let theme = ThemeConfig::from_startup_config_value(&json!({ diff --git a/src/crates/core/src/agentic/tools/implementations/generative_ui_tool.rs b/src/crates/core/src/agentic/tools/implementations/generative_ui_tool.rs index b84aed4f..783fcf70 100644 --- a/src/crates/core/src/agentic/tools/implementations/generative_ui_tool.rs +++ b/src/crates/core/src/agentic/tools/implementations/generative_ui_tool.rs @@ -36,7 +36,7 @@ impl GenerativeUITool { } fn sparo_os_design_system_reminder() -> &'static str { - "Sparo OS design-system reminder: when the widget should feel native to Sparo OS, style it with Sparo OS theme tokens instead of hard-coded design values. Prefer CSS variables such as `var(--color-bg-primary)`, `var(--color-bg-secondary)`, `var(--color-bg-scene)`, `var(--color-bg-elevated)`, `var(--color-text-primary)`, `var(--color-text-secondary)`, `var(--color-text-muted)`, `var(--color-accent-500)`, `var(--color-accent-600)`, `var(--border-subtle)`, `var(--border-base)`, `var(--border-medium)`, `var(--element-bg-subtle)`, `var(--element-bg-soft)`, `var(--element-bg-base)`, `var(--element-bg-medium)`, `var(--shadow-*)`, `var(--radius-*)`, `var(--spacing-*)`, `var(--motion-*)`, `var(--easing-*)`, `var(--font-sans)`, and `var(--font-mono)`. Support both `dark` and `light` (and other built-in themes); do not assume dark-only, purple-only, or landing-page styling. Favor compact desktop workbench layouts, panel/card surfaces, strong information hierarchy, and reusable Sparo OS UI patterns. Avoid hard-coded colors, arbitrary spacing, giant hero sections, fake mobile chrome, and full marketing-page shells; prefer understated, premium UI with layered surfaces, restrained contrast, subtle borders, and do not use thick left-accent emphasis blocks." + "Sparo OS design-system reminder: when the widget should feel native to Sparo OS, style it with Sparo OS theme tokens instead of hard-coded design values. Prefer CSS variables such as `var(--color-bg-primary)`, `var(--color-bg-secondary)`, `var(--color-bg-scene)`, `var(--color-bg-elevated)`, `var(--color-text-primary)`, `var(--color-text-secondary)`, `var(--color-text-muted)`, `var(--color-accent-500)`, `var(--color-accent-600)`, `var(--border-subtle)`, `var(--border-base)`, `var(--border-medium)`, `var(--element-bg-subtle)`, `var(--element-bg-soft)`, `var(--element-bg-base)`, `var(--element-bg-medium)`, `var(--shadow-*)`, `var(--radius-*)`, `var(--spacing-*)`, `var(--motion-*)`, `var(--easing-*)`, `var(--font-sans)`, and `var(--font-mono)`. Support both `dark` and `light`; do not assume dark-only, purple-only, or landing-page styling. Favor compact desktop workbench layouts, panel/card surfaces, strong information hierarchy, and reusable Sparo OS UI patterns. Avoid hard-coded colors, arbitrary spacing, giant hero sections, fake mobile chrome, and full marketing-page shells; prefer understated, premium UI with layered surfaces, restrained contrast, subtle borders, and do not use thick left-accent emphasis blocks." } fn sparo_os_widget_scaffold_reminder() -> &'static str { @@ -88,74 +88,6 @@ impl GenerativeUITool { shadow_base: "0 5px 12px rgba(15, 23, 42, 0.08)", style_notes: "light theme — cloud surfaces, ink text, print-red accent, calm contrast", }), - "slate" | "sparo-slate" | "sparo-midnight" => Some(ThemePromptSnapshot { - id: "slate", - theme_type: "dark", - bg_primary: "#14161a", - bg_secondary: "#22262c", - bg_scene: "#22262c", - text_primary: "#eef0f3", - text_muted: "#9ea4ab", - accent_500: "#B7372F", - accent_600: "#9E2F29", - border_base: "rgba(255, 255, 255, 0.18)", - element_base: "rgba(255, 255, 255, 0.095)", - radius_base: "6px", - spacing_4: "16px", - shadow_base: "0 4px 8px rgba(0, 0, 0, 0.75)", - style_notes: "cool gray geometric chrome, crisp edges, Sparo ink-red accent, dense desktop mood", - }), - "sparo-cyber" => Some(ThemePromptSnapshot { - id: "sparo-cyber", - theme_type: "dark", - bg_primary: "#101010", - bg_secondary: "#151515", - bg_scene: "#141414", - text_primary: "#e0f2ff", - text_muted: "#7fadcc", - accent_500: "#00e6ff", - accent_600: "#00ccff", - border_base: "rgba(0, 230, 255, 0.20)", - element_base: "rgba(0, 230, 255, 0.13)", - radius_base: "6px", - spacing_4: "16px", - shadow_base: "0 4px 12px rgba(0, 0, 0, 0.8)", - style_notes: "neon cyber tooling, black surfaces, glowing cyan accents, still compact and workbench-first", - }), - "sparo-china-style" => Some(ThemePromptSnapshot { - id: "sparo-china-style", - theme_type: "light", - bg_primary: "#faf8f0", - bg_secondary: "#f5f3e8", - bg_scene: "#fdfcf6", - text_primary: "#1a1a1a", - text_muted: "#6a6a6a", - accent_500: "#2e5e8a", - accent_600: "#234a6d", - border_base: "rgba(106, 92, 70, 0.20)", - element_base: "rgba(46, 94, 138, 0.10)", - radius_base: "6px", - spacing_4: "16px", - shadow_base: "0 4px 8px rgba(106, 92, 70, 0.1)", - style_notes: "warm rice-paper surfaces, ink-and-blue accenting, elegant and restrained", - }), - "sparo-china-night" => Some(ThemePromptSnapshot { - id: "sparo-china-night", - theme_type: "dark", - bg_primary: "#1a1814", - bg_secondary: "#212019", - bg_scene: "#1e1c17", - text_primary: "#e8e6e1", - text_muted: "#928f89", - accent_500: "#73a5cc", - accent_600: "#5a8bb3", - border_base: "rgba(232, 230, 225, 0.16)", - element_base: "rgba(115, 165, 204, 0.12)", - radius_base: "6px", - spacing_4: "16px", - shadow_base: "0 4px 8px rgba(0, 0, 0, 0.65)", - style_notes: "warm ink-night dark palette, calm contrast, blue-green highlights, elegant not flashy", - }), _ => None, } } diff --git a/src/crates/core/src/service/config/catalog.rs b/src/crates/core/src/service/config/catalog.rs index 9d910bf0..b5ea7737 100644 --- a/src/crates/core/src/service/config/catalog.rs +++ b/src/crates/core/src/service/config/catalog.rs @@ -26,15 +26,8 @@ pub const SETTING_AI_DEFAULT_SPEECH_RECOGNITION: &str = "core.ai.default_models. pub const SETTING_MCP_SERVERS: &str = "core.mcp_servers"; pub const SETTING_DEBUG_INGEST_PORT: &str = "core.product_apps.bitfun_coder.debug.ingest_port"; -pub(crate) const BUILTIN_THEME_OPTIONS: [(&str, &str); 7] = [ - ("system", "System"), - ("light", "Light"), - ("slate", "Slate"), - ("dark", "Dark"), - ("sparo-china-style", "Sparo China Style"), - ("sparo-china-night", "Sparo China Night"), - ("sparo-cyber", "Sparo Cyber"), -]; +pub(crate) const BUILTIN_THEME_OPTIONS: [(&str, &str); 3] = + [("system", "System"), ("light", "Light"), ("dark", "Dark")]; /// Risk assigned by trusted catalog metadata. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -2679,10 +2672,14 @@ mod tests { theme.options_provider, Some(SettingOptionsProvider::AvailableThemes) ); - assert!(theme - .resolved_options - .iter() - .any(|option| option.value == "custom-theme" && option.label == "Custom theme")); + assert_eq!( + theme + .resolved_options + .iter() + .map(|option| option.value.as_str()) + .collect::>(), + vec!["system", "light", "dark", "custom-theme"], + ); let shell = catalog .find("core.terminal.default_shell") diff --git a/src/crates/core/src/service/config/manager.rs b/src/crates/core/src/service/config/manager.rs index af8e5492..6b4fd41e 100644 --- a/src/crates/core/src/service/config/manager.rs +++ b/src/crates/core/src/service/config/manager.rs @@ -93,6 +93,17 @@ enum ConfigLoadOutcome { Loaded, } +fn normalize_retired_theme_selection(config: &mut GlobalConfig) { + let replacement = match config.themes.current.as_str() { + "sparo-china-style" => Some("light"), + "slate" | "sparo-china-night" | "sparo-cyber" => Some("dark"), + _ => None, + }; + if let Some(replacement) = replacement { + config.themes.current = replacement.to_string(); + } +} + /// Configuration manager. pub struct ConfigManager { config_dir: PathBuf, @@ -419,6 +430,7 @@ impl ConfigManager { let mut config: GlobalConfig = serde_json::from_value(config_value).map_err(|error| { CoreError::config(format!("Config does not match the current schema: {error}")) })?; + normalize_retired_theme_selection(&mut config); self.secret_store.resolve(&mut config).await?; Ok(config) } @@ -2048,6 +2060,33 @@ mod transaction_tests { use super::*; use std::sync::Arc; + #[test] + fn normalizes_retired_builtin_theme_selections() { + for (retired, expected) in [ + ("sparo-china-style", "light"), + ("slate", "dark"), + ("sparo-china-night", "dark"), + ("sparo-cyber", "dark"), + ] { + let mut config = GlobalConfig::default(); + config.themes.current = retired.to_string(); + + normalize_retired_theme_selection(&mut config); + + assert_eq!(config.themes.current, expected); + } + } + + #[test] + fn leaves_unknown_theme_selections_for_validation() { + let mut config = GlobalConfig::default(); + config.themes.current = "unknown-theme".to_string(); + + normalize_retired_theme_selection(&mut config); + + assert_eq!(config.themes.current, "unknown-theme"); + } + async fn isolated_manager() -> (tempfile::TempDir, ConfigManager) { let temp = tempfile::tempdir().expect("tempdir"); let path_manager = Arc::new(PathManager::with_user_root_for_tests( diff --git a/src/web-ui/dist-preview/assets/index-C_s2NvXm.js b/src/web-ui/dist-preview/assets/index-C_s2NvXm.js new file mode 100644 index 00000000..3be40337 --- /dev/null +++ b/src/web-ui/dist-preview/assets/index-C_s2NvXm.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/preview-DWC_IH0E.js","assets/preview-CMlHD2Qb.css","assets/index-DNunTB6S.js"])))=>i.map(i=>d[i]); +import{_,c as g}from"./preview-DWC_IH0E.js";var r=(s=>(s.IDLE="idle",s.PROCESSING="processing",s.FINISHING="finishing",s.ERROR="error",s))(r||{}),i=(s=>(s.STARTING="starting",s.COMPACTING="compacting",s.THINKING="thinking",s.STREAMING="streaming",s.FINALIZING="finalizing",s.TOOL_CALLING="tool_calling",s.TOOL_CONFIRMING="tool_confirming",s))(i||{}),n=(s=>(s.START="start",s.COMPACTION_STARTED="compaction_started",s.MODEL_ROUND_START="model_round_start",s.TEXT_CHUNK_RECEIVED="text_chunk_received",s.TOOL_DETECTED="tool_detected",s.TOOL_STARTED="tool_started",s.TOOL_COMPLETED="tool_completed",s.TOOL_CONFIRMATION_NEEDED="tool_confirmation_needed",s.TOOL_CONFIRMED="tool_confirmed",s.TOOL_REJECTED="tool_rejected",s.BACKEND_STREAM_COMPLETED="backend_stream_completed",s.FINISHING_SETTLED="finishing_settled",s.USER_CANCEL="user_cancel",s.ERROR_OCCURRED="error_occurred",s.RESET="reset",s))(n||{});const h={[r.IDLE]:{[n.START]:r.PROCESSING},[r.PROCESSING]:{[n.USER_CANCEL]:r.IDLE,[n.FINISHING_SETTLED]:r.IDLE,[n.ERROR_OCCURRED]:r.ERROR,[n.BACKEND_STREAM_COMPLETED]:r.FINISHING,[n.COMPACTION_STARTED]:r.PROCESSING,[n.MODEL_ROUND_START]:r.PROCESSING,[n.TEXT_CHUNK_RECEIVED]:r.PROCESSING,[n.TOOL_DETECTED]:r.PROCESSING,[n.TOOL_STARTED]:r.PROCESSING,[n.TOOL_COMPLETED]:r.PROCESSING,[n.TOOL_CONFIRMATION_NEEDED]:r.PROCESSING,[n.TOOL_CONFIRMED]:r.PROCESSING,[n.TOOL_REJECTED]:r.IDLE},[r.FINISHING]:{[n.USER_CANCEL]:r.IDLE,[n.ERROR_OCCURRED]:r.ERROR,[n.FINISHING_SETTLED]:r.IDLE,[n.COMPACTION_STARTED]:r.FINISHING,[n.MODEL_ROUND_START]:r.FINISHING,[n.TEXT_CHUNK_RECEIVED]:r.FINISHING,[n.TOOL_DETECTED]:r.FINISHING,[n.TOOL_STARTED]:r.FINISHING,[n.TOOL_COMPLETED]:r.FINISHING,[n.TOOL_CONFIRMATION_NEEDED]:r.FINISHING,[n.TOOL_CONFIRMED]:r.FINISHING,[n.TOOL_REJECTED]:r.IDLE},[r.ERROR]:{[n.RESET]:r.IDLE,[n.START]:r.PROCESSING}},L={[n.START]:i.STARTING,[n.COMPACTION_STARTED]:i.COMPACTING,[n.MODEL_ROUND_START]:i.THINKING,[n.TEXT_CHUNK_RECEIVED]:i.STREAMING,[n.TOOL_DETECTED]:i.TOOL_CALLING,[n.TOOL_STARTED]:i.TOOL_CALLING,[n.TOOL_COMPLETED]:null,[n.TOOL_CONFIRMATION_NEEDED]:i.TOOL_CONFIRMING,[n.TOOL_CONFIRMED]:i.TOOL_CALLING,[n.TOOL_REJECTED]:null,[n.BACKEND_STREAM_COMPLETED]:i.FINALIZING,[n.FINISHING_SETTLED]:null,[n.USER_CANCEL]:null,[n.ERROR_OCCURRED]:null,[n.RESET]:null};function b(s,t){return h[s]?.[t]!==void 0}function D(s,t){return h[s]?.[t]||null}function k(s){const t=h[s];return t?Object.keys(t):[]}const T=g("SessionStateMachine");function C(){return{taskId:null,currentDialogTurnId:null,currentModelRoundId:null,pendingToolConfirmations:new Set,errorMessage:null,queuedInput:null,processingPhase:null,planner:null,stats:{startTime:null,textCharsGenerated:0,toolsExecuted:0},version:0,lastUpdateTime:Date.now(),backendSyncedAt:null,errorRecovery:{errorCount:0,lastErrorTime:null,errorType:null,recoverable:!0}}}class N{static MAX_HISTORY_LENGTH=100;sessionId;currentState;context;transitionHistory=[];listeners=new Set;constructor(t){this.sessionId=t,this.currentState=r.IDLE,this.context=C()}getSnapshot(){const{pendingToolConfirmations:t,...e}=this.context,o=structuredClone(e);return{sessionId:this.sessionId,currentState:this.currentState,context:{...o,pendingToolConfirmations:new Set(t)},transitionHistory:this.transitionHistory.slice(-N.MAX_HISTORY_LENGTH)}}getCurrentState(){return this.currentState}getContext(){return this.context}async transition(t,e){const o=this.currentState,a=D(o,t);if(!a)return T.warn("Invalid transition",{sessionId:this.sessionId,fromState:o,event:t}),this.transitionHistory.push({from:o,event:t,to:o,timestamp:Date.now(),payload:e,success:!1}),!1;[n.TOOL_DETECTED,n.TOOL_STARTED,n.TOOL_COMPLETED,n.TOOL_CONFIRMATION_NEEDED,n.TOOL_CONFIRMED,n.TOOL_REJECTED,n.USER_CANCEL,n.START].includes(t)&&T.debug("State transition",{sessionId:this.sessionId,fromState:o,event:t,toState:a,payload:e}),this.currentState=a,this.context.version+=1,this.context.lastUpdateTime=Date.now();const l=this.context.processingPhase;this.updateContext(t,e);const I=this.context.processingPhase;return this.transitionHistory.length>N.MAX_HISTORY_LENGTH*2&&(this.transitionHistory=this.transitionHistory.slice(-N.MAX_HISTORY_LENGTH)),this.transitionHistory.push({from:o,event:t,to:a,timestamp:Date.now(),payload:e,success:!0}),await this.runSideEffects(t,e),t!==n.TEXT_CHUNK_RECEIVED?this.notifyListeners():l!==I&&this.notifyListeners(),!0}updateContext(t,e){if(this.currentState===r.PROCESSING||this.currentState===r.FINISHING){const o=L[t];(this.currentState===r.PROCESSING||t===n.BACKEND_STREAM_COMPLETED)&&o!==void 0&&(this.context.processingPhase=o)}else this.context.processingPhase=null;switch(t){case n.START:this.context.taskId=e?.taskId||null,this.context.currentDialogTurnId=e?.dialogTurnId||null,this.context.processingPhase=L[t],this.context.stats.startTime=Date.now(),this.context.stats.textCharsGenerated=0,this.context.stats.toolsExecuted=0;break;case n.MODEL_ROUND_START:this.context.currentModelRoundId=e?.modelRoundId||null;break;case n.TEXT_CHUNK_RECEIVED:e?.content&&(this.context.stats.textCharsGenerated+=e.content.length);break;case n.TOOL_CONFIRMATION_NEEDED:e?.toolUseId&&this.context.pendingToolConfirmations.add(e.toolUseId);break;case n.TOOL_CONFIRMED:case n.TOOL_REJECTED:e?.toolUseId&&this.context.pendingToolConfirmations.delete(e.toolUseId);break;case n.TOOL_COMPLETED:this.context.stats.toolsExecuted++;break;case n.ERROR_OCCURRED:this.context.errorMessage=e?.error||"Unknown error",this.context.processingPhase=null,this.context.errorRecovery.errorCount+=1,this.context.errorRecovery.lastErrorTime=Date.now(),this.context.errorRecovery.errorType=e?.errorType||"unknown",this.context.errorRecovery.recoverable=e?.recoverable!==!1;break;case n.BACKEND_STREAM_COMPLETED:this.context.processingPhase=i.FINALIZING;break;case n.USER_CANCEL:case n.FINISHING_SETTLED:case n.RESET:if(this.currentState===r.IDLE){const o=this.context.queuedInput,a=this.context.taskId,c=this.context.currentDialogTurnId;this.context=C(),this.context.queuedInput=o,t===n.USER_CANCEL&&(a&&(this.context.taskId=a),c&&(this.context.currentDialogTurnId=c))}break}}async runSideEffects(t,e){const o=this.currentState;if(t===n.USER_CANCEL){const{flowChatStore:a}=await _(async()=>{const{flowChatStore:u}=await import("./preview-DWC_IH0E.js").then(O=>O.F);return{flowChatStore:u}},__vite__mapDeps([0,1]));a.cancelSessionTask(this.sessionId);const c=this.context.taskId||this.sessionId,l=this.context.currentDialogTurnId,{agentAPI:I}=await _(async()=>{const{agentAPI:u}=await import("./index-DNunTB6S.js");return{agentAPI:u}},__vite__mapDeps([2,0,1]));try{l?(await I.cancelDialogTurn(c,l),T.debug("Backend cancellation completed",{sessionId:c,dialogTurnId:l})):(await I.cancelSession(c),T.debug("Backend session cancellation completed",{sessionId:c}))}catch(u){T.error("Backend cancellation failed",{sessionId:c,dialogTurnId:l,error:u})}}o===r.IDLE&&this.context.planner?.isActive&&(this.context.planner.isActive=!1)}updatePlanner(t,e){this.context.planner={todos:t,isActive:e},this.notifyListeners()}setQueuedInput(t){this.context.queuedInput=t,this.notifyListeners()}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notifyListeners(){const t=this.getSnapshot();this.listeners.forEach(e=>{try{e(t)}catch(o){T.error("Listener error",o)}})}reset(){this.currentState=r.IDLE,this.context=C(),this.transitionHistory=[],this.notifyListeners()}}const A=g("SessionStateMachineManager");class E{static instance;machines=new Map;globalListeners=new Set;constructor(){}static getInstance(){return E.instance||(E.instance=new E),E.instance}getOrCreate(t){let e=this.machines.get(t);return e||(e=new N(t),this.machines.set(t,e),e.subscribe(o=>{this.notifyGlobalListeners(t,o)})),e}get(t){return this.machines.get(t)||null}async transition(t,e,o){return this.getOrCreate(t).transition(e,o)}getCurrentState(t){const e=this.machines.get(t);return e?e.getCurrentState():r.IDLE}getSnapshot(t){const e=this.machines.get(t);return e?e.getSnapshot():null}delete(t){this.machines.delete(t)}reset(t){const e=this.machines.get(t);e&&e.reset()}subscribeGlobal(t){return this.globalListeners.add(t),()=>{this.globalListeners.delete(t)}}notifyGlobalListeners(t,e){this.globalListeners.forEach(o=>{try{o(t,e)}catch(a){A.error("Global listener error",{sessionId:t,error:a})}})}getAllSessionIds(){return Array.from(this.machines.keys())}clear(){this.machines.clear()}}const U=E.getInstance();function p(s,t){const{currentState:e,context:o}=s,a=e===r.PROCESSING||e===r.FINISHING||e===r.ERROR?t?.processingInputDraftTrimmed?.trim()??"":"",c=(o.queuedInput?.trim()?.length??0)>0||a.length>0,l=o.pendingToolConfirmations.size>0,I=e===r.PROCESSING||e===r.FINISHING;return{canSend:e===r.IDLE||e===r.ERROR,canCancel:I&&!l,sendButtonMode:G(e,o.processingPhase,c,l),inputDisabled:!1,needsAttention:l?"tool_confirm":!1,progressLabel:m(o.processingPhase)}}function G(s,t,e,o){return s===r.ERROR?e?"split":"retry":o||t===i.TOOL_CONFIRMING?"confirm":s===r.FINISHING||s===r.PROCESSING?e?"split":"cancel":"send"}function m(s){switch(s){case i.COMPACTING:return"Compressing session context...";case i.STARTING:return"Connecting to AI...";case i.THINKING:return"Thinking...";case i.FINALIZING:return"Finalizing response...";case i.TOOL_CALLING:return"Executing tools...";case i.TOOL_CONFIRMING:return"Waiting for tool confirmation...";default:return}}function y(s,t){const{currentState:e,context:o}=s,{processingPhase:a}=o,c=e===r.PROCESSING||e===r.FINISHING||e===r.ERROR?t?.processingInputDraftTrimmed?.trim()??"":"",l=o.planner?.todos?{completed:o.planner.todos.filter(d=>d.status==="completed").length,inProgress:o.planner.todos.filter(d=>d.status==="in_progress").length,pending:o.planner.todos.filter(d=>d.status==="pending").length}:null,I=l?l.completed/o.planner.todos.length*100:0,u=e===r.PROCESSING||e===r.FINISHING,O=e===r.ERROR,f=e===r.IDLE,R=p(s,{processingInputDraftTrimmed:c}),S=R.canCancel;return{isInputDisabled:R.inputDisabled,showSendButton:R.canSend,showCancelButton:S,sendButtonMode:R.sendButtonMode,inputPlaceholder:"How can I help you...",showPlanner:u&&o.planner!==null&&o.planner.isActive&&o.planner.todos.length>0,plannerProgress:I,plannerStats:l,showProgressBar:u,progressBarMode:M(a),progressBarValue:P(a,o),progressBarLabel:H(a,o),progressBarColor:F(a),isProcessing:u,canCancel:S,canSendNewMessage:f||O,hasQueuedInput:(o.queuedInput?.trim()?.length??0)>0||(e===r.PROCESSING||e===r.FINISHING||e===r.ERROR)&&c.length>0,queuedInput:o.queuedInput??null,hasError:O,errorType:o.errorMessage?x(o.errorMessage):null,canRetry:O}}function M(s){switch(s){case i.COMPACTING:return"indeterminate";case i.TOOL_CALLING:return"segmented";case i.STREAMING:return"determinate";case i.FINALIZING:return"indeterminate";default:return"indeterminate"}}function P(s,t){if(s===i.STREAMING){const o=t.stats.textCharsGenerated;return Math.min(o/500*100,90)}if(s===i.TOOL_CALLING&&t.planner){const{completed:e,inProgress:o,pending:a}=t.planner.todos.reduce((l,I)=>(l[I.status]++,l),{completed:0,inProgress:0,pending:0}),c=e+o+a;return c>0?e/c*100:0}return 0}function H(s,t){switch(s){case i.COMPACTING:return"Compressing session context...";case i.STARTING:return"Connecting to AI...";case i.THINKING:return"Thinking...";case i.STREAMING:{const e=t.stats.textCharsGenerated,o=t.stats.startTime?((Date.now()-t.stats.startTime)/1e3).toFixed(1):"0";return`Generating response (${e} chars) · ${o}s`}case i.FINALIZING:return"Finalizing response...";case i.TOOL_CALLING:return`Executing tools... (${t.stats.toolsExecuted} completed)`;case i.TOOL_CONFIRMING:return"Waiting for tool confirmation...";default:return""}}function F(s){switch(s){case i.COMPACTING:return"var(--ds-tool-family-planning-fg)";case i.STARTING:return"var(--ds-status-surface-info-fg)";case i.THINKING:return"var(--ds-status-surface-info-fg)";case i.STREAMING:return"linear-gradient(90deg, var(--ds-status-surface-info-fg), var(--ds-tool-family-agent-fg))";case i.TOOL_CALLING:return"var(--ds-tool-family-agent-fg)";case i.TOOL_CONFIRMING:return"var(--ds-status-surface-warning-fg)";default:return"var(--ds-status-surface-info-fg)"}}function x(s){const t=s.toLowerCase();return t.includes("network")||t.includes("timeout")?"network":t.includes("model")||t.includes("overload")?"model":t.includes("permission")||t.includes("api key")||t.includes("401")||t.includes("403")?"permission":"unknown"}export{L as PHASE_TRANSITIONS,i as ProcessingPhase,h as STATE_TRANSITIONS,n as SessionExecutionEvent,r as SessionExecutionState,N as SessionStateMachineImpl,E as SessionStateMachineManager,b as canTransition,y as deriveSessionState,D as getNextState,k as getPossibleEvents,U as stateMachineManager}; diff --git a/src/web-ui/dist-preview/assets/index-DNunTB6S.js b/src/web-ui/dist-preview/assets/index-DNunTB6S.js new file mode 100644 index 00000000..42f17484 --- /dev/null +++ b/src/web-ui/dist-preview/assets/index-DNunTB6S.js @@ -0,0 +1 @@ +import{a as r,b as a,s as p,d as w,t as y,e as k,w as m}from"./preview-DWC_IH0E.js";import{A as Se,f as Ae,g as Ce,h as Pe}from"./preview-DWC_IH0E.js";class g{async listModels(){try{return await r.invoke("list_ai_models",{request:{}})}catch(e){throw a("list_ai_models",e)}}async getModelInfo(e){try{return await r.invoke("get_model_info",{request:{modelId:e}})}catch(t){throw a("get_model_info",t,{modelId:e})}}async testConnection(e){try{return await r.invoke("test_ai_connection",{request:e})}catch(t){throw a("test_ai_connection",t,{config:e})}}async testConfigConnection(e){try{return await r.invoke("test_ai_config_connection",{request:{config:e}})}catch(t){throw a("test_ai_config_connection",t,{config:e})}}async sendMessage(e){try{return await r.invoke("send_ai_message",{request:e})}catch(t){throw a("send_ai_message",t,e)}}async initializeAI(){try{await r.invoke("initialize_ai")}catch(e){throw a("initialize_ai",e)}}async testSavedModelConnection(e){try{return await r.invoke("test_saved_ai_model_connection",{request:{modelId:e}})}catch(t){throw a("test_saved_ai_model_connection",t,{modelId:e})}}async testAIConfigConnection(e){try{return await r.invoke("test_ai_config_connection",{request:{config:e}})}catch(t){throw a("test_ai_config_connection",t,{config:e})}}async listModelsByConfig(e){try{return await r.invoke("list_ai_models_by_config",{request:{config:e}})}catch(t){throw a("list_ai_models_by_config",t,{config:e})}}async createAISession(e){try{return await r.invoke("create_ai_session",{request:e})}catch(t){throw a("create_ai_session",t,{config:e})}}async invokeAICommand(e,t,o){try{const n={config:t,...o};return await r.invoke(e,n)}catch(n){throw a(e,n,{config:t,additionalArgs:o})}}async discoverCliCredentials(){try{return await r.invoke("discover_cli_credentials",{})}catch(e){throw a("discover_cli_credentials",e)}}async refreshCliCredential(e){try{return await r.invoke("refresh_cli_credential",{request:{kind:e}})}catch(t){throw a("refresh_cli_credential",t,{kind:e})}}async fixMermaidCode(e){try{return await r.invoke("fix_mermaid_code",{request:e})}catch(t){throw a("fix_mermaid_code",t,e)}}}const v=new g;class f{async listJobs(e={}){try{return await r.invoke("list_cron_jobs",{request:e})}catch(t){throw a("list_cron_jobs",t,e)}}async createJob(e){try{return await r.invoke("create_cron_job",{request:e})}catch(t){throw a("create_cron_job",t,e)}}async updateJob(e,t){try{return await r.invoke("update_cron_job",{request:{jobId:e,...t}})}catch(o){throw a("update_cron_job",o,{jobId:e,...t})}}async deleteJob(e){try{return await r.invoke("delete_cron_job",{request:{jobId:e}})}catch(t){throw a("delete_cron_job",t,{jobId:e})}}}const S=new f;class A{async listDrives(){try{return await r.invoke("system_fs_list_drives")}catch(e){throw a("system_fs_list_drives",e)}}async listQuickFolders(){try{return await r.invoke("system_fs_list_quick_folders")}catch(e){throw a("system_fs_list_quick_folders",e)}}async listDir(e){try{return await r.invoke("system_fs_list_dir",{request:{path:e}})}catch(t){throw a("system_fs_list_dir",t,{path:e})}}async stat(e){try{return await r.invoke("system_fs_stat",{request:{path:e}})}catch(t){throw a("system_fs_stat",t,{path:e})}}async createFile(e,t={kind:"system",allowed:"auto"}){try{return await r.invoke("system_fs_create_file",{request:{path:e,scope:t}})}catch(o){throw a("system_fs_create_file",o,{path:e})}}async createDir(e,t={kind:"system",allowed:"auto"}){try{return await r.invoke("system_fs_create_dir",{request:{path:e,scope:t}})}catch(o){throw a("system_fs_create_dir",o,{path:e})}}async rename(e,t,o={kind:"system",allowed:"auto"}){try{return await r.invoke("system_fs_rename",{request:{oldPath:e,newPath:t,scope:o}})}catch(n){throw a("system_fs_rename",n,{oldPath:e,newPath:t})}}async delete(e,t=!0,o={kind:"system",allowed:"auto"}){try{return await r.invoke("system_fs_delete",{request:{path:e,recursive:t,scope:o}})}catch(n){throw a("system_fs_delete",n,{path:e,recursive:t})}}async revealInOs(e){try{await r.invoke("system_fs_reveal_in_os",{request:{path:e}})}catch(t){throw a("system_fs_reveal_in_os",t,{path:e})}}async openWithDefault(e){try{await r.invoke("system_fs_open_with_default",{request:{path:e}})}catch(t){throw a("system_fs_open_with_default",t,{path:e})}}}class C{async list(){try{return await r.invoke("pinned_list")}catch(e){throw a("pinned_list",e)}}async add(e,t){try{return await r.invoke("pinned_add",{request:{path:e,label:t}})}catch(o){throw a("pinned_add",o,{path:e,label:t})}}async remove(e){try{await r.invoke("pinned_remove",{request:{id:e}})}catch(t){throw a("pinned_remove",t,{id:e})}}async reorder(e){try{return await r.invoke("pinned_reorder",{request:{ids:e}})}catch(t){throw a("pinned_reorder",t,{ids:e})}}}class P{async stash(e,t){try{await r.invoke("stash_files_context",{request:{sessionId:e,context:t}})}catch(o){throw a("stash_files_context",o,{sessionId:e,context:t})}}}class b{async planOperations(e){try{return await r.invoke("file_workbench_plan_operations",{request:e})}catch(t){throw a("file_workbench_plan_operations",t,e)}}async executePlan(e){try{return await r.invoke("file_workbench_execute_plan",{request:e})}catch(t){throw a("file_workbench_execute_plan",t,{planId:e.plan.id})}}async restoreAuditItem(e){try{return await r.invoke("file_workbench_restore_audit_item",{request:e})}catch(t){throw a("file_workbench_restore_audit_item",t,{planId:e.planId,itemId:e.itemId})}}}const q=new A,x=new C,D=new P,T=new b;class I{async getTokenUsage(e){try{return await r.invoke("get_token_usage",{request:e})}catch(t){throw a("get_token_usage",t,e)}}async clearTokenUsage(){try{await r.invoke("clear_token_usage")}catch(e){throw a("clear_token_usage",e)}}}const E=new I;class R{async getStorageStatistics(){try{return await r.invoke("get_storage_statistics",{})}catch(e){throw a("get_storage_statistics",e)}}async resetApplicationData(e){try{return await r.invoke("reset_application_data",{request:e})}catch(t){throw a("reset_application_data",t,{mode:e.mode,createBackup:e.createBackup,includeLogs:e.includeLogs,includeSecrets:e.includeSecrets,includeBrowserProfiles:e.includeBrowserProfiles,includeProjectLocalSparoDirs:e.includeProjectLocalSparoDirs.length})}}}const M=new R;class H{async submitSessionGoal(e){try{return await r.invoke("submit_session_goal",{request:e})}catch(t){throw a("submit_session_goal",t,e)}}async getSessionGoal(e,t){try{return await r.invoke("get_session_goal",{request:{sessionId:e,workspacePath:t}})}catch(o){throw a("get_session_goal",o,{sessionId:e,workspacePath:t})}}async controlSessionGoal(e){try{return await r.invoke("control_session_goal",{request:e})}catch(t){throw a("control_session_goal",t,e)}}async updateSessionGoal(e){try{return await r.invoke("update_session_goal",{request:e})}catch(t){throw a("update_session_goal",t,e)}}onGoalEvent(e){return r.listen("agentic://goal-event",e)}}const L=new H;class G{async exportHtml(e){try{return await r.invoke("export_markdown_html",{request:e})}catch(t){throw a("export_markdown_html",t,{destinationPath:e.destinationPath,html:"[redacted]"})}}async exportPdf(e){try{return await r.invoke("export_markdown_pdf",{request:e})}catch(t){throw a("export_markdown_pdf",t,{destinationPath:e.destinationPath,html:"[redacted]",options:e.options})}}}const j=new G;class W{pendingResolutions=new Map;resolutionKey(e){return JSON.stringify([e.locator,e.slotId,e.appId,e.productAppSurfaceId??null,e.surfaceId??null])}async resolveProductAppRuntimeInstance(e){const t=this.resolutionKey(e),o=this.pendingResolutions.get(t);if(o)return o;const n=r.invoke("resolve_product_app_runtime_instance",{request:e}).catch(i=>{throw a("resolve_product_app_runtime_instance",i,{locator:e.locator,slotId:e.slotId,appId:e.appId})});this.pendingResolutions.set(t,n);try{return await n}finally{this.pendingResolutions.get(t)===n&&this.pendingResolutions.delete(t)}}async prepareProductAppWork(e){try{return await r.invoke("prepare_product_app_work",{request:{locator:e}})}catch(t){throw a("prepare_product_app_work",t,{locator:e})}}}const O=new W,U=3e4,F=4;class Q{hostSurfaceCache=new Map;pendingHostSurfaces=new Map;hostSurfaceGenerations=new Map;hostSurfaceGeneration=0;hostSurfaceKey(e,t,o){return[e,t??"dark",o?.trim()??""].join("")}rememberHostSurface(e,t){for(this.hostSurfaceCache.delete(e),this.hostSurfaceCache.set(e,{surface:t,expiresAt:Date.now()+U});this.hostSurfaceCache.size>F;){const o=this.hostSurfaceCache.keys().next().value;if(!o)break;this.hostSurfaceCache.delete(o)}}invalidateHostSurface(e){if(!e){this.hostSurfaceGeneration+=1,this.hostSurfaceCache.clear(),this.pendingHostSurfaces.clear(),this.hostSurfaceGenerations.clear();return}const t=`${e}`;for(const o of this.hostSurfaceCache.keys())o.startsWith(t)&&this.hostSurfaceCache.delete(o);for(const o of this.pendingHostSurfaces.keys())o.startsWith(t)&&this.pendingHostSurfaces.delete(o);this.hostSurfaceGenerations.set(e,(this.hostSurfaceGenerations.get(e)??0)+1)}async listHostSurfaces(){try{return await r.invoke("product_app_runtime_list_host_surfaces",{})}catch(e){throw a("product_app_runtime_list_host_surfaces",e)}}async listRecentHostSurfaces(){try{return await r.invoke("product_app_runtime_list_recent_host_surfaces",{})}catch(e){throw a("product_app_runtime_list_recent_host_surfaces",e)}}async recordRecentHostSurface(e){try{return await r.invoke("product_app_runtime_record_recent_host_surface",{request:{appId:e}})}catch(t){throw a("product_app_runtime_record_recent_host_surface",t,{appId:e})}}async getHostSurface(e,t,o){const n=this.hostSurfaceKey(e,t,o),i=this.hostSurfaceCache.get(n);if(i&&i.expiresAt>Date.now())return this.hostSurfaceCache.delete(n),this.hostSurfaceCache.set(n,i),i.surface;i&&this.hostSurfaceCache.delete(n);const c=this.pendingHostSurfaces.get(n);if(c)return c;const d=this.hostSurfaceGeneration,h=this.hostSurfaceGenerations.get(e)??0;let _;_=r.invoke("product_app_runtime_get_host_surface",{request:{appId:e,theme:t??void 0,workspacePath:o}}).then(async u=>this.hostSurfaceGeneration===d&&(this.hostSurfaceGenerations.get(e)??0)===h?(this.rememberHostSurface(n,u),u):(this.pendingHostSurfaces.get(n)===_&&this.pendingHostSurfaces.delete(n),this.getHostSurface(e,t,o))).catch(u=>{throw a("product_app_runtime_get_host_surface",u,{appId:e,workspacePath:o})}),this.pendingHostSurfaces.set(n,_);try{return await _}finally{this.pendingHostSurfaces.get(n)===_&&this.pendingHostSurfaces.delete(n)}}async hostRuntimeStatus(){try{return await r.invoke("product_app_runtime_host_runtime_status",{})}catch(e){throw a("product_app_runtime_host_runtime_status",e)}}async listRunningWorkers(){try{return await r.invoke("product_app_runtime_list_running_workers",{})}catch(e){throw a("product_app_runtime_list_running_workers",e)}}async stopWorker(e){try{await r.invoke("product_app_runtime_stop_worker",{appId:e}),this.invalidateHostSurface(e)}catch(t){throw a("product_app_runtime_stop_worker",t,{appId:e})}}async installDependencies(e){try{const t=await r.invoke("product_app_runtime_install_dependencies",{appId:e});return this.invalidateHostSurface(e),t}catch(t){throw a("product_app_runtime_install_dependencies",t,{appId:e})}}async recompileHostSurface(e,t,o){this.invalidateHostSurface(e);try{const n=await r.invoke("product_app_runtime_recompile_host_surface",{request:{appId:e,theme:t??void 0,workspacePath:o}});return this.invalidateHostSurface(e),n}catch(n){throw a("product_app_runtime_recompile_host_surface",n,{appId:e,workspacePath:o})}}async clearRuntimeIssues(e){try{await r.invoke("product_app_runtime_clear_runtime_issues",{request:{appId:e}})}catch(t){throw a("product_app_runtime_clear_runtime_issues",t,{appId:e})}}async reportRuntimeIssue(e){try{await r.invoke("product_app_runtime_report_runtime_issue",{request:e})}catch(t){throw a("product_app_runtime_report_runtime_issue",t,{appId:e.appId})}}async reportRuntimeLog(e){try{await r.invoke("product_app_runtime_report_runtime_log",{request:e})}catch(t){throw a("product_app_runtime_report_runtime_log",t,{appId:e.appId})}}async workerCall(e,t,o,n,i){try{return await r.invoke("product_app_runtime_worker_call",{request:{appId:e,method:t,params:o,runtimeContext:n,workspacePath:i}})}catch(c){throw a("product_app_runtime_worker_call",c,{appId:e,method:t,workspacePath:i})}}async probeRuntimeStorage(e,t,o){try{const n=await r.invoke("product_app_runtime_worker_call",{request:{appId:e,method:"storage.probe",params:{},runtimeContext:t,workspacePath:o}});return l(n)?{available:n.available===!0?!0:void 0,scope:typeof n.scope=="string"?n.scope:void 0}:{}}catch(n){throw a("product_app_runtime_worker_call",n,{appId:e,method:"storage.probe",workspacePath:o})}}async probeRuntimeDataLifecycle(e,t,o){try{const n=await r.invoke("product_app_runtime_worker_call",{request:{appId:e,method:"storage.readinessProbe",params:{},runtimeContext:t,workspacePath:o}});return l(n)?{available:n.available===!0?!0:void 0,scope:typeof n.scope=="string"?n.scope:void 0,probeKey:typeof n.probeKey=="string"?n.probeKey:void 0,writeVerified:n.writeVerified===!0,readVerified:n.readVerified===!0,deleteVerified:n.deleteVerified===!0,preservedPreviousValue:n.preservedPreviousValue===!0}:{}}catch(n){throw a("product_app_runtime_worker_call",n,{appId:e,method:"storage.readinessProbe",workspacePath:o})}}async aiComplete(e,t,o,n){try{return await r.invoke("product_app_runtime_ai_complete",{request:{appId:e,runtimeContext:o,prompt:t,systemPrompt:n?.systemPrompt,model:n?.model,maxTokens:n?.maxTokens,temperature:n?.temperature}})}catch(i){throw a("product_app_runtime_ai_complete",i,{appId:e})}}async aiChat(e,t,o,n,i){try{return await r.invoke("product_app_runtime_ai_chat",{request:{appId:e,runtimeContext:n,messages:t,streamId:o,systemPrompt:i?.systemPrompt,model:i?.model,maxTokens:i?.maxTokens,temperature:i?.temperature}})}catch(c){throw a("product_app_runtime_ai_chat",c,{appId:e,streamId:o})}}async aiCancel(e,t,o){try{await r.invoke("product_app_runtime_ai_cancel",{request:{appId:e,runtimeContext:o,streamId:t}})}catch(n){throw a("product_app_runtime_ai_cancel",n,{appId:e,streamId:t})}}async aiListModels(e,t){try{return await r.invoke("product_app_runtime_ai_list_models",{request:{appId:e,runtimeContext:t}})}catch(o){throw a("product_app_runtime_ai_list_models",o,{appId:e})}}async backendCall(e,t,o,n){try{return await r.invoke("product_app_runtime_backend_call",{request:{appId:e,target:t,input:o,runtimeContext:n.runtimeContext,entityId:n.entityId,idempotencyKey:n.idempotencyKey,workspacePath:n.workspacePath,sessionId:n.sessionId}})}catch(i){throw a("product_app_runtime_backend_call",i,{appId:e,target:t})}}async backendStatus(e,t,o){try{return await r.invoke("product_app_runtime_backend_status",{request:{appId:e,actionRunId:t,runtimeContext:o.runtimeContext,sessionId:o.sessionId,turnId:o.turnId}})}catch(n){throw a("product_app_runtime_backend_status",n,{appId:e,actionRunId:t})}}async backendCancelRun(e,t,o){try{return await r.invoke("product_app_runtime_backend_cancel_run",{request:{appId:e,actionRunId:t,runtimeContext:o.runtimeContext,sessionId:o.sessionId,turnId:o.turnId}})}catch(n){throw a("product_app_runtime_backend_cancel_run",n,{appId:e,actionRunId:t})}}}const V=new Q;function l(s){return!!s&&typeof s=="object"&&!Array.isArray(s)}class z{async open(e){try{return await r.invoke("open_product_app_session",{request:e})}catch(t){throw a("open_product_app_session",t,{workLocator:e.workLocator,appId:e.appId,channelId:e.channelId,entityId:e.entityId})}}}const K=new z,we="sensevoice-small-int8",ye="local:sensevoice-small-int8",ke=16e3,me=60,N="speech://model-download-progress",B="speech://model-status-changed";class J{async listModels(){try{return await r.invoke("speech_list_models",{})}catch(e){throw a("speech_list_models",e)}}async downloadModel(e){try{return await r.invoke("speech_download_model",{request:{modelId:e}},{timeout:6e5})}catch(t){throw a("speech_download_model",t,{modelId:e})}}async cancelModelDownload(e){try{return await r.invoke("speech_cancel_model_download",{request:{modelId:e}})}catch(t){throw a("speech_cancel_model_download",t,{modelId:e})}}async deleteModel(e){try{return await r.invoke("speech_delete_model",{request:{modelId:e}})}catch(t){throw a("speech_delete_model",t,{modelId:e})}}async verifyModel(e){try{return await r.invoke("speech_verify_model",{request:{modelId:e}})}catch(t){throw a("speech_verify_model",t,{modelId:e})}}async startInputSession(e={}){try{return await r.invoke("speech_start_input_session",{request:e})}catch(t){throw a("speech_start_input_session",t,e)}}async appendAudioChunk(e,t){try{return await r.invoke("speech_append_audio_chunk",{request:{sessionId:e,pcm16Base64:t}})}catch(o){throw a("speech_append_audio_chunk",o,{sessionId:e})}}async finishInputSession(e){try{return await r.invoke("speech_finish_input_session",{request:{sessionId:e}},{timeout:12e4})}catch(t){throw a("speech_finish_input_session",t,{sessionId:e})}}async cancelInputSession(e){try{await r.invoke("speech_cancel_input_session",{request:{sessionId:e}})}catch(t){throw a("speech_cancel_input_session",t,{sessionId:e})}}onModelProgress(e){return r.listen(N,e)}onModelStatusChanged(e){return r.listen(B,e)}}const $=new J;class X{async createSession(e){try{return await r.invoke("create_session",{request:e})}catch(t){throw a("create_session",t,e)}}async startDialogTurn(e){try{return await r.invoke("start_dialog_turn",{request:e})}catch(t){throw a("start_dialog_turn",t,e)}}async listQueuedDialogTurns(e){try{return await r.invoke("list_queued_dialog_turns",{request:{sessionId:e}})}catch(t){throw a("list_queued_dialog_turns",t,{sessionId:e})}}async updateQueuedDialogTurn(e){try{return await r.invoke("update_queued_dialog_turn",{request:e})}catch(t){throw a("update_queued_dialog_turn",t,e)}}async deleteQueuedDialogTurn(e,t){try{return await r.invoke("delete_queued_dialog_turn",{request:{sessionId:e,turnId:t}})}catch(o){throw a("delete_queued_dialog_turn",o,{sessionId:e,turnId:t})}}async guideQueuedDialogTurn(e,t){try{return await r.invoke("guide_queued_dialog_turn",{request:{sessionId:e,turnId:t}})}catch(o){throw a("guide_queued_dialog_turn",o,{sessionId:e,turnId:t})}}async resumeQueuedDialogTurns(e){try{return await r.invoke("resume_queued_dialog_turns",{request:{sessionId:e}})}catch(t){throw a("resume_queued_dialog_turns",t,{sessionId:e})}}async compactSession(e){try{return await r.invoke("compact_session",{request:e})}catch(t){throw a("compact_session",t,e)}}async cancelDialogTurn(e,t){try{await r.invoke("cancel_dialog_turn",{request:{sessionId:e,dialogTurnId:t}})}catch(o){throw a("cancel_dialog_turn",o,{sessionId:e,dialogTurnId:t})}}async deleteSession(e){try{await r.invoke("delete_session",{request:{locator:e}})}catch(t){throw a("delete_session",t,{locator:e})}}async restoreSession(e){try{return await r.invoke("restore_session",{request:{locator:e}})}catch(t){throw a("restore_session",t,{locator:e})}}async ensureCoordinatorSession(e){try{await r.invoke("ensure_coordinator_session",{request:e})}catch(t){throw a("ensure_coordinator_session",t,e)}}async updateSessionModel(e){try{await r.invoke("update_session_model",{request:e})}catch(t){throw a("update_session_model",t,e)}}async updateSessionTitle(e){try{return await r.invoke("update_session_title",{request:e})}catch(t){throw a("update_session_title",t,e)}}async updateSessionWorkspace(e){try{await r.invoke("update_session_workspace",{request:e})}catch(t){throw a("update_session_workspace",t,e)}}async listSessions(e){try{return await r.invoke("list_sessions",{request:{domain:e}})}catch(t){throw a("list_sessions",t,{domain:e})}}async confirmToolExecution(e,t){try{await r.invoke("confirm_tool_execution",{request:{sessionId:e,toolId:t}})}catch(o){throw a("confirm_tool_execution",o,{sessionId:e,toolId:t})}}async rejectToolExecution(e,t,o){try{await r.invoke("reject_tool_execution",{request:{sessionId:e,toolId:t,reason:o}})}catch(n){throw a("reject_tool_execution",n,{sessionId:e,toolId:t,reason:o})}}onSessionCreated(e){return r.listen("agentic://session-created",e)}onSessionDeleted(e){return r.listen("agentic://session-deleted",e)}onSessionStateChanged(e){return r.listen("agentic://session-state-changed",e)}onSessionModelAutoMigrated(e){return r.listen("agentic://session-model-auto-migrated",e)}onDialogTurnStarted(e){return r.listen("agentic://dialog-turn-started",e)}onModelRoundStarted(e){return r.listen("agentic://model-round-started",e)}onTextChunk(e){return r.listen("agentic://text-chunk",e)}onToolEvent(e){return r.listen("agentic://tool-event",e)}onDialogTurnCompleted(e){return r.listen("agentic://dialog-turn-completed",e)}onDialogTurnFailed(e){return r.listen("agentic://dialog-turn-failed",e)}onDialogTurnCancelled(e){return r.listen("agentic://dialog-turn-cancelled",e)}onDialogTurnQueued(e){return r.listen("agentic://dialog-turn-queued",e)}onDialogTurnQueueUpdated(e){return r.listen("agentic://dialog-turn-queue-updated",e)}onDialogTurnQueueDeleted(e){return r.listen("agentic://dialog-turn-queue-deleted",e)}onDialogTurnQueueDispatching(e){return r.listen("agentic://dialog-turn-queue-dispatching",e)}onDialogTurnQueuePaused(e){return r.listen("agentic://dialog-turn-queue-paused",e)}onDialogTurnQueueResumed(e){return r.listen("agentic://dialog-turn-queue-resumed",e)}onDialogTurnGuidanceRequested(e){return r.listen("agentic://dialog-turn-guidance-requested",e)}onDialogTurnGuidanceApplied(e){return r.listen("agentic://dialog-turn-guidance-applied",e)}onDialogTurnGuidanceFailed(e){return r.listen("agentic://dialog-turn-guidance-failed",e)}onTokenUsageUpdated(e){return r.listen("agentic://token-usage-updated",e)}onContextBudgetUpdated(e){return r.listen("agentic://context-budget-updated",e)}onContextCompressionStarted(e){return r.listen("agentic://context-compression-started",e)}onContextCompressionCompleted(e){return r.listen("agentic://context-compression-completed",e)}onContextCompressionFailed(e){return r.listen("agentic://context-compression-failed",e)}onImageAnalysisStarted(e){return r.listen("agentic://image-analysis-started",e)}onImageAnalysisCompleted(e){return r.listen("agentic://image-analysis-completed",e)}async getAvailableTools(){try{return await r.invoke("get_available_tools")}catch(e){throw a("get_available_tools",e)}}async generateSessionTitle(e,t,o){try{return await r.invoke("generate_session_title",{request:{sessionId:e,userMessage:t,maxLength:o||20}})}catch(n){throw a("generate_session_title",n,{sessionId:e,userMessage:t,maxLength:o})}}onSessionTitleGenerated(e){return r.listen("session_title_generated",e)}async cancelSession(e){try{await r.invoke("cancel_session",{request:{sessionId:e}})}catch(t){throw a("cancel_session",t,{sessionId:e})}}async getAgentInfo(e){return{id:e,name:e,description:`${e} agent`,isReadonly:!1,toolCount:0,enabled:!0,agent_type:e,when_to_use:`Use ${e} for related tasks`,tools:"all",location:"builtin"}}async listAgents(){try{return await r.invoke("list_agents")}catch(e){throw a("list_agents",e)}}}const Y=new X;class Z{async analyzeProject(e,t){try{return await r.invoke("analyze_project",{request:{path:e,options:t}})}catch(o){throw a("analyze_project",o,{path:e,options:t})}}async getProjectStructure(e){try{return await r.invoke("get_project_structure",{request:{path:e}})}catch(t){throw a("get_project_structure",t,{path:e})}}async getDependencyGraph(e){try{return await r.invoke("get_dependency_graph",{request:{path:e}})}catch(t){throw a("get_dependency_graph",t,{path:e})}}async searchCode(e,t){try{return await r.invoke("search_code",{request:{query:e,options:t}})}catch(o){throw a("search_code",o,{query:e,options:t})}}async clearProjectCache(e){try{await r.invoke("clear_project_cache",{request:{workspacePath:e}})}catch(t){throw a("clear_project_cache",t,{workspacePath:e})}}}const ee=new Z;class te{async computeDiff(e,t,o){try{return await r.invoke("compute_diff",{request:{oldContent:e,newContent:t,options:o}})}catch(n){throw a("compute_diff",n,{oldContent:e,newContent:t,options:o})}}async applyPatch(e,t){try{return await r.invoke("apply_patch",{request:{content:e,patch:t}})}catch(o){throw a("apply_patch",o,{content:e,patch:t})}}async saveMergedDiffContent(e,t){try{await r.invoke("save_merged_diff_content",{request:{filePath:e,content:t}})}catch(o){throw a("save_merged_diff_content",o,{filePath:e,content:t})}}}const re=new te;class ae{async initializeGlobalState(){try{return await r.invoke("initialize_global_state",{request:{}})}catch(e){throw a("initialize_global_state",e)}}async getAppState(){try{return await r.invoke("get_app_state",{request:{}})}catch(e){throw a("get_app_state",e)}}async updateAppStatus(e){try{await r.invoke("update_app_status",{request:{status:e}})}catch(t){throw a("update_app_status",t,{status:e})}}async openWorkspace(e){try{return await r.invoke("open_workspace",{request:{path:e}})}catch(t){throw a("open_workspace",t,{path:e})}}async closeWorkspace(e){try{await r.invoke("close_workspace",{request:{workspaceId:e}})}catch(t){throw a("close_workspace",t,{workspaceId:e})}}async rememberWorkspace(e){try{return await r.invoke("remember_workspace",{request:{workspaceId:e}})}catch(t){throw a("remember_workspace",t,{workspaceId:e})}}async reorderOpenedWorkspaces(e){try{await r.invoke("reorder_opened_workspaces",{request:{workspaceIds:e}})}catch(t){throw a("reorder_opened_workspaces",t,{workspaceIds:e})}}async getLastUsedWorkspace(){try{return await r.invoke("get_last_used_workspace",{request:{}})}catch(e){throw a("get_last_used_workspace",e)}}async getRecentWorkspaces(){try{return await r.invoke("get_recent_workspaces",{request:{}})}catch(e){throw a("get_recent_workspaces",e)}}async removeRecentWorkspace(e){try{await r.invoke("remove_recent_workspace",{request:{workspaceId:e}})}catch(t){throw a("remove_recent_workspace",t,{workspaceId:e})}}async cleanupInvalidWorkspaces(){try{return await r.invoke("cleanup_invalid_workspaces")}catch(e){throw a("cleanup_invalid_workspaces",e)}}async getOpenedWorkspaces(){try{return await r.invoke("get_opened_workspaces",{request:{}})}catch(e){throw a("get_opened_workspaces",e)}}async scanWorkspaceInfo(e){try{return await r.invoke("scan_workspace_info",{request:{workspacePath:e}})}catch(t){throw a("scan_workspace_info",t,{workspacePath:e})}}async getLastUsedWorkspacePath(){try{return(await this.getLastUsedWorkspace())?.rootPath}catch(e){throw a("get_last_used_workspace",e)}}}const oe=new ae;class ne{async compressContext(){try{return await r.invoke("compress_context",{request:{}})}catch(e){throw a("compress_context",e)}}async getContextStats(){try{return await r.invoke("get_context_stats",{request:{}})}catch(e){throw a("get_context_stats",e)}}async clearContext(){try{return await r.invoke("clear_context",{request:{}})}catch(e){throw a("clear_context",e)}}async saveSessionData(e){try{return await r.invoke("save_session_data",{request:{sessionData:e}})}catch(t){throw a("save_session_data",t,{sessionData:e})}}async loadSessionData(e){try{return await r.invoke("load_session_data",{request:{sessionId:e}})}catch(t){throw a("load_session_data",t,{sessionId:e})}}async listSessions(e=!1){try{return await r.invoke("list_sessions",{request:{includeArchived:e}})}catch(t){throw a("list_sessions",t,{includeArchived:e})}}async searchSessions(e,t){try{return await r.invoke("search_sessions",{request:{query:e,tags:t}})}catch(o){throw a("search_sessions",o,{query:e,tags:t})}}async deleteSession(e){try{return await r.invoke("delete_session",{request:{sessionId:e}})}catch(t){throw a("delete_session",t,{sessionId:e})}}async archiveSession(e){try{return await r.invoke("archive_session",{request:{sessionId:e}})}catch(t){throw a("archive_session",t,{sessionId:e})}}async exportSession(e,t){try{return await r.invoke("export_session",{request:{sessionId:e,exportPath:t}})}catch(o){throw a("export_session",o,{sessionId:e,exportPath:t})}}async importSession(e){try{return await r.invoke("import_session",{request:{importPath:e}})}catch(t){throw a("import_session",t,{importPath:e})}}async getStorageStats(){try{return await r.invoke("get_storage_stats",{request:{}})}catch(e){throw a("get_storage_stats",e)}}}const se=new ne;class ie{async getContextBudget(e,t,o,n){try{return await r.invoke("get_context_budget",{request:{locator:e,agent_type:t,workspace_path:o,model_id:n}})}catch(i){throw a("get_context_budget",i,{locator:e,agentType:t,workspacePath:o,modelId:n})}}async forkSession(e,t){try{return await r.invoke("fork_session",{request:{source:e,source_turn_id:t}})}catch(o){throw a("fork_session",o,{source:e,sourceTurnId:t})}}async listSessions(e){try{return await r.invoke("list_persisted_sessions",{request:{domain:e}})}catch(t){throw a("list_persisted_sessions",t,{domain:e})}}async loadSessionTurns(e,t){try{const o={locator:e};return t!==void 0&&(o.limit=t),await r.invoke("load_session_turns",{request:o})}catch(o){throw a("load_session_turns",o,{locator:e,limit:t})}}async saveSessionTurn(e,t){try{await r.invoke("save_session_turn",{request:{turn_data:e,domain:t}})}catch(o){throw a("save_session_turn",o,{turnData:e,domain:t})}}async saveSessionMetadata(e){try{await r.invoke("save_session_metadata",{request:{metadata:e}})}catch(t){throw a("save_session_metadata",t,{metadata:e})}}async deleteSession(e){try{await r.invoke("delete_persisted_session",{request:{locator:e}})}catch(t){throw a("delete_persisted_session",t,{locator:e})}}async touchSessionActivity(e){try{await r.invoke("touch_session_activity",{request:{locator:e}})}catch(t){throw a("touch_session_activity",t,{locator:e})}}async loadSessionMetadata(e){try{return await r.invoke("load_persisted_session_metadata",{request:{locator:e}})}catch(t){throw a("load_persisted_session_metadata",t,{locator:e})}}}const ce=new ie;class _e{async askStream(e){try{return await r.invoke("btw_ask_stream",{request:e})}catch(t){throw a("btw_ask_stream",t,e)}}async cancel(e){try{await r.invoke("btw_cancel",{request:e})}catch(t){throw a("btw_cancel",t,e)}}}const ue=new _e;class le{async cancel(e){try{await r.invoke("markdown_ai_cancel",{request:e})}catch(t){throw a("markdown_ai_cancel",t,e)}}async proposeEdits(e){try{return await r.invoke("markdown_ai_propose_edits",{request:e})}catch(t){throw a("markdown_ai_propose_edits",t,{...e,documentMarkdown:"[redacted]",profile:e.profile?"[redacted]":void 0})}}onError(e){return r.listen("markdown-ai://error",e)}onProposalChunk(e){return r.listen("markdown-ai://proposal-chunk",e)}onProposalChunkReady(e){return r.listenReady("markdown-ai://proposal-chunk",e)}onProposalCompleted(e){return r.listen("markdown-ai://proposal-completed",e)}onProposalCompletedReady(e){return r.listenReady("markdown-ai://proposal-completed",e)}onErrorReady(e){return r.listenReady("markdown-ai://error",e)}}const de=new le,ge={workspace:m,systemFs:q,pinned:x,filesContext:D,fileWorkbench:T,config:k,ai:v,tool:y,agent:Y,system:w,project:ee,diff:re,snapshot:p,global:oe,context:se,cron:S,session:ce,btw:ue,markdownAi:de,markdownExport:j,tokenUsage:E,storage:M,goal:L,productAppRuntime:O,productAppRuntimeHost:V,productAppSession:K,speech:$};export{g as AIApi,Se as ApiClient,f as CronAPI,me as DEFAULT_MAX_RECORDING_SECONDS,ke as DEFAULT_SPEECH_SAMPLE_RATE,we as LOCAL_SENSEVOICE_SMALL_INT8_MODEL_ID,ye as LOCAL_SENSEVOICE_SMALL_INT8_MODEL_REF,G as MarkdownExportAPI,W as ProductAppRuntimeAPI,Q as ProductAppRuntimeHostAPI,z as ProductAppSessionAPI,N as SPEECH_MODEL_PROGRESS_EVENT,B as SPEECH_MODEL_STATUS_CHANGED_EVENT,J as SpeechAPI,R as StorageAPI,I as TokenUsageAPI,Y as agentAPI,v as aiApi,r as api,Ae as apiClient,ue as btwAPI,k as configAPI,se as contextAPI,Ce as createLoggingMiddleware,Pe as createRetryMiddleware,S as cronAPI,ge as default,re as diffAPI,T as fileWorkbenchAPI,D as filesContextAPI,oe as globalAPI,L as goalAPI,de as markdownAiAPI,j as markdownExportAPI,x as pinnedAPI,O as productAppRuntimeAPI,V as productAppRuntimeHostAPI,K as productAppSessionAPI,ee as projectAPI,ce as sessionAPI,p as snapshotAPI,ge as sparoAPI,$ as speechAPI,M as storageAPI,w as systemAPI,q as systemFsAPI,E as tokenUsageAPI,y as toolAPI,m as workspaceAPI}; diff --git a/src/web-ui/dist-preview/assets/index-DgcE1LoE.js b/src/web-ui/dist-preview/assets/index-DgcE1LoE.js new file mode 100644 index 00000000..47352829 --- /dev/null +++ b/src/web-ui/dist-preview/assets/index-DgcE1LoE.js @@ -0,0 +1 @@ +import{i as d,j as c}from"./preview-DWC_IH0E.js";const m={status:"preparing",activity:"idle",latestLabel:"Preparing subagent",updatedAt:0};function g(e,t){return`${e}:${t}`}function I(e){const t=e.split(/\r?\n/).map(s=>s.trim()).filter(Boolean);return t.length===0?void 0:[...t].reverse().find(s=>/^#{1,6}\s+/.test(s))||t[t.length-1]}function y(e){const t=c(e),n=N(t.lifecycle),s=P(e),i=t.partialInput||t.input||e.toolCall?.input||{},r=e._streamingFileStats?.filePath||i.file_path||i.path||i.target_file,a=typeof r=="string"&&r.trim()?r.trim():void 0;return{status:n,activity:s,latestLabel:n==="completed"?`${e.toolName} completed`:`${e.toolName} ${s==="receiving_tool_input"?"receiving input":n}`,latestDetail:a,latestToolName:e.toolName,updatedAt:Date.now()}}function T(e){const t=e.type==="text"?I(e.content):void 0,n=e.isStreaming&&e.status!=="completed"&&e.status!=="cancelled"&&e.status!=="error";return{status:n?"running":e.status==="error"?"error":e.status==="cancelled"?"cancelled":"completed",activity:n?e.type==="thinking"?"thinking":"streaming_text":"idle",latestLabel:t||(e.type==="thinking"?"Thinking":"Streaming response"),latestDetail:e.type==="thinking"?"Reasoning in progress":void 0,latestMarkdownLine:t,updatedAt:Date.now()}}function _(e){const t=e.items[e.items.length-1];return t?t.type==="tool"?y(t):t.type==="text"||t.type==="thinking"?T(t):e.summary:e.summary}function x(e){switch(e.event_type){case"EarlyDetected":return"preparing";case"ParamsPartial":return"streaming";case"Started":return"running";case"Progress":case"Streaming":case"StreamChunk":return"running";case"ConfirmationNeeded":return"pending_confirmation";case"Confirmed":return"confirmed";case"Completed":return"completed";case"Failed":return"error";case"Cancelled":return"cancelled";case"Queued":case"Waiting":return"pending";case"Rejected":return"cancelled";default:return"running"}}function N(e){return e==="completed"||e==="cancelled"||e==="error"?e:e==="draining"?"draining":e==="waiting_confirmation"?"waiting_confirmation":e==="pending"||e==="preparing"||e==="ready"?"preparing":"running"}function P(e){const t=c(e);return d(t.lifecycle)?"idle":t.inputPhase==="streaming"?"receiving_tool_input":t.lifecycle==="running"?"running_tool":"idle"}function p(e){return e.nodeState?d(e.nodeState.status):d(e.summary.status)}function b(e,t){return t?.status==="draining"?"draining":d(e.status)?"running":e.status}function k(e,t){const n=Date.now(),s=e||{id:t.tool_id,type:"tool",toolName:t.tool_name,toolCall:{input:{},id:t.tool_id},timestamp:n,status:"preparing",requiresConfirmation:!1,startTime:n},i={...s,toolName:t.tool_name||s.toolName,status:x(t)},r=c(s),a=o=>{i.runtime={...r,...o}};if(t.event_type==="ParamsPartial"){const o=`${i._paramsBuffer||""}${t.params||""}`;i._paramsBuffer=o;const u=r.partialInput&&typeof r.partialInput=="object"?r.partialInput:{};i.toolCall={input:u,id:t.tool_id},a({lifecycle:"preparing",inputPhase:"streaming",partialInput:u})}else t.event_type==="Started"?(i.toolCall={input:t.params,id:t.tool_id},a({lifecycle:"running",inputPhase:"parsed",input:t.params,partialInput:void 0,startedAt:i.startTime||n}),i.startTime=i.startTime||n):t.event_type==="Progress"?(i._progressMessage=t.message,i._progressPercentage=t.percentage):t.event_type==="ConfirmationNeeded"?(i.requiresConfirmation=!0,i.toolCall={input:t.params,id:t.tool_id},a({lifecycle:"waiting_confirmation",inputPhase:"parsed",confirmation:"required",input:t.params,partialInput:void 0})):t.event_type==="Completed"?(i.toolResult={result:t.result,success:!0,resultForAssistant:t.result_for_assistant,duration_ms:t.duration_ms},a({lifecycle:"completed",inputPhase:r.inputPhase==="streaming"?"parsed":r.inputPhase,partialInput:void 0,result:t.result,endedAt:n}),i.endTime=n):t.event_type==="Failed"?(i.toolResult={result:null,success:!1,error:t.error},a({lifecycle:"error",inputPhase:r.inputPhase==="streaming"?"parsed":r.inputPhase,partialInput:void 0,result:null,error:t.error,endedAt:n}),i.endTime=n):t.event_type==="Cancelled"&&(i.toolResult={result:null,success:!1,error:t.reason},a({lifecycle:"cancelled",inputPhase:r.inputPhase==="streaming"?"parsed":r.inputPhase,partialInput:void 0,result:null,error:t.reason,endedAt:n}),i.endTime=n);return i}function f(e,t,n){let s=!1;const i=e.map(r=>r.id===n||r.type!=="text"&&r.type!=="thinking"||!r.isStreaming||h(r.status)?r:(s=!0,r.type==="thinking"?{...r,isStreaming:!1,isCollapsed:!0,status:"completed",timestamp:r.timestamp||t}:{...r,isStreaming:!1,status:"completed",timestamp:r.timestamp||t}));return s?i:e}class w{nodes=new Map;listeners=new Set;getNode(t,n){return!t||!n?null:this.nodes.get(g(t,n))||null}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}hydrateNode(t){const n={...t,nodeState:t.nodeState??{status:t.summary.status,activity:t.summary.activity??"idle"}};return this.nodes.set(t.id,n),this.listeners.forEach(s=>s()),n}ingestText(t,n){const s=this.ensureNode(t);if(p(s))return s;const i=n.contentType==="thinking",r=`${i?"subagent-thinking":"subagent-text"}-${t.parentToolId}-${t.childSessionId}-${n.roundId}`,a=s.items.findIndex(l=>l.id===r),o=Date.now();let u=f(s.items,o,r);if(a>=0){const l=u[a],S={...l,content:l.content+n.text,timestamp:o,...i&&n.isThinkingEnd?{isStreaming:!1,isCollapsed:!0,status:"completed"}:{}};u=[...u],u[a]=S}else if(i){const l={id:r,type:"thinking",content:n.text,timestamp:o,isStreaming:!n.isThinkingEnd,isCollapsed:!!n.isThinkingEnd,status:n.isThinkingEnd?"completed":"streaming"};u=[...u,l]}else{const l={id:r,type:"text",content:n.text,timestamp:o,isStreaming:!0,status:"streaming",isMarkdown:!0};u=[...u,l]}return this.commitNode({...s,items:u,updatedAt:o})}ingestToolEvent(t,n){const s=this.ensureNode(t);if(p(s))return s;const i=s.items.findIndex(l=>l.type==="tool"&&l.id===n.tool_id),r=i>=0?s.items[i]:void 0,a=k(r,n),o=Date.now(),u=[...f(s.items,o)];return i>=0?u[i]=a:u.push(a),this.commitNode({...s,items:u,updatedAt:o})}beginNodeDrain(t,n){const s=this.ensureNode(t);if(p(s))return s;const i=Date.now();return this.commitNode({...s,parentTurnId:t.parentTurnId??s.parentTurnId,childSessionId:t.childSessionId||s.childSessionId,summary:{...s.summary,status:"draining",activity:"idle",updatedAt:i},nodeState:{status:"draining",activity:"idle",terminalReason:n},updatedAt:i},{status:"draining",activity:"idle"})}finalizeNodeByParent(t,n){const s=this.ensureNode(t),i=Date.now(),r=s.items.map(o=>C(o,n,i)),a=s.items.length===0||!s.summary.latestLabel||s.summary.latestLabel===m.latestLabel;return this.commitNode({...s,parentTurnId:t.parentTurnId??s.parentTurnId,childSessionId:t.childSessionId||s.childSessionId,items:r,summary:{...s.summary,status:n,activity:"idle",latestLabel:a?A(n):s.summary.latestLabel,updatedAt:i},nodeState:{status:n,activity:"idle",terminalReason:n},updatedAt:i},{status:n})}ensureNode(t){const n=t.nodeId||g(t.parentSessionId,t.parentToolId),s=this.nodes.get(n);if(s){const a={...s,parentTurnId:t.parentTurnId??s.parentTurnId,childSessionId:t.childSessionId||s.childSessionId};return this.nodes.set(n,a),a}const i=Date.now(),r={id:n,kind:"subagentRun",edgeKind:"delegates",parentSessionId:t.parentSessionId,parentTurnId:t.parentTurnId,parentToolId:t.parentToolId,childSessionId:t.childSessionId,items:[],summary:{...m,updatedAt:i},nodeState:{status:"preparing",activity:"idle"},createdAt:i,updatedAt:i};return this.nodes.set(n,r),r}commitNode(t,n){const s=_(t),i=n?.status??b(s,t.nodeState),r={...s,...n,status:i},a={...t,summary:r,nodeState:{status:i,activity:r.activity??"idle",terminalReason:t.nodeState?.terminalReason,error:t.nodeState?.error}};return this.nodes.set(t.id,a),this.listeners.forEach(o=>o()),a}}function A(e){switch(e){case"completed":return"Subagent completed";case"error":return"Subagent failed";case"cancelled":return"Subagent cancelled";default:return"Subagent finished"}}function C(e,t,n){const s=h(e.status)?e.status:t;if(e.type==="text")return{...e,isStreaming:!1,status:s,timestamp:e.timestamp||n};if(e.type==="thinking")return{...e,isStreaming:!1,isCollapsed:!0,status:s,timestamp:e.timestamp||n};if(e.type==="tool"){const i=c(e);return{...e,runtime:{...i,lifecycle:s,inputPhase:i.inputPhase==="streaming"?"parsed":i.inputPhase,partialInput:void 0,endedAt:e.endTime??n},status:s,endTime:e.endTime??n}}return{...e,status:s}}function h(e){return d(e)}function R(){return new w}const L=R();export{L as executionGraphStore}; diff --git a/src/web-ui/dist-preview/assets/preview-CMlHD2Qb.css b/src/web-ui/dist-preview/assets/preview-CMlHD2Qb.css new file mode 100644 index 00000000..b2f0460b --- /dev/null +++ b/src/web-ui/dist-preview/assets/preview-CMlHD2Qb.css @@ -0,0 +1 @@ +@charset "UTF-8";.ds-spinner{align-items:center;color:var(--ds-color-text-muted, var(--color-text-muted));display:inline-flex;gap:var(--ds-space-2, 8px)}.ds-spinner__label{font-size:var(--ds-font-size-sm, 14px);line-height:var(--ds-line-height-tight, 1.25)}.dot-matrix-loader{flex-shrink:0;display:grid;grid-template-columns:repeat(3,var(--dm-cell, 4px));grid-template-rows:repeat(3,var(--dm-cell, 4px));gap:var(--dm-gap, 2px);width:calc(3 * var(--dm-cell, 4px) + 2 * var(--dm-gap, 2px));height:calc(3 * var(--dm-cell, 4px) + 2 * var(--dm-gap, 2px));color:var(--ds-color-accent-500)}.dot-matrix-loader--tiny{--dm-cell: 3px;--dm-gap: 2px}.dot-matrix-loader--small{--dm-cell: 4px;--dm-gap: 2px}.dot-matrix-loader--medium{--dm-cell: 6px;--dm-gap: 3px}.dot-matrix-loader--large{--dm-cell: 8px;--dm-gap: 4px}.dot-matrix-loader__dot{width:var(--dm-cell, 4px);height:var(--dm-cell, 4px);border-radius:50%;background-color:currentColor;animation:dot-matrix-loader-pulse 1.8s ease-in-out infinite;will-change:opacity}.dot-matrix-loader__dot:nth-child(1){animation-delay:0s}.dot-matrix-loader__dot:nth-child(2){animation-delay:.12s}.dot-matrix-loader__dot:nth-child(3){animation-delay:.24s}.dot-matrix-loader__dot:nth-child(4){animation-delay:.12s}.dot-matrix-loader__dot:nth-child(5){animation-delay:.24s}.dot-matrix-loader__dot:nth-child(6){animation-delay:.36s}.dot-matrix-loader__dot:nth-child(7){animation-delay:.24s}.dot-matrix-loader__dot:nth-child(8){animation-delay:.36s}.dot-matrix-loader__dot:nth-child(9){animation-delay:.48s}@keyframes dot-matrix-loader-pulse{0%,to{opacity:.25;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){.dot-matrix-loader__dot{animation:none;opacity:.75;transform:none}}.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--size-gap-2, 8px);font-weight:var(--font-weight-medium, 500);font-family:var(--font-family-sans, inherit);text-decoration:none;cursor:pointer;position:relative;outline:none;-webkit-user-select:none;user-select:none;background:var(--element-bg-base, rgba(255, 255, 255, .08));color:var(--color-text-secondary, #e5e5e5);border:none;border-radius:var(--size-radius-sm, 6px);transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.btn:focus-visible{outline:2px solid rgba(96,165,250,.5);outline-offset:1px}.btn-sm{height:var(--button-height-sm, 32px);padding:0 var(--size-gap-3, 12px);font-size:var(--font-size-sm, 14px)}.btn-base{height:var(--button-height-base, 40px);padding:0 var(--size-gap-4, 16px);font-size:var(--font-size-base, 15px)}.btn-lg{height:var(--button-height-lg, 48px);padding:0 var(--size-gap-6, 24px);font-size:var(--font-size-lg, 16px)}.btn-pill{border-radius:var(--ds-radius-full, 999px)}.btn:hover:not(:disabled){background:var(--element-bg-medium, rgba(255, 255, 255, .14));color:var(--color-text-primary, #ffffff)}.btn:active:not(:disabled){background:var(--element-bg-soft, rgba(255, 255, 255, .1))}.btn:disabled,.btn-disabled{opacity:.45;cursor:default;pointer-events:none}.btn-primary{background:var(--btn-primary-bg, var(--color-accent-200, rgba(96, 165, 250, .2)));color:var(--btn-primary-color, var(--color-accent-600, #3b82f6));box-shadow:var(--btn-primary-shadow, none)}.btn-primary:hover:not(:disabled){background:var(--btn-primary-hover-bg, var(--color-accent-300, rgba(96, 165, 250, .3)));color:var(--btn-primary-hover-color, var(--color-text-primary, #ffffff));box-shadow:var(--btn-primary-hover-shadow, none)}.btn-primary:active:not(:disabled){background:var(--btn-primary-active-bg, var(--color-accent-200, rgba(96, 165, 250, .24)));color:var(--btn-primary-active-color, var(--color-text-primary, #ffffff));box-shadow:var(--btn-primary-active-shadow, none)}.btn-primary:focus-visible{outline-color:color-mix(in srgb,var(--btn-primary-color, var(--color-accent-500, #60a5fa)) 55%,transparent)}.btn-secondary{background:var(--element-bg-base, rgba(255, 255, 255, .08));color:var(--color-text-secondary, #e5e5e5)}.btn-secondary:hover:not(:disabled){background:var(--element-bg-medium, rgba(255, 255, 255, .14));color:var(--color-text-primary, #ffffff)}.btn-secondary:active:not(:disabled){background:var(--element-bg-soft, rgba(255, 255, 255, .1))}.btn-ghost{background:transparent;color:var(--color-text-secondary, #e5e5e5)}.btn-ghost:hover:not(:disabled){background:var(--element-bg-soft, rgba(255, 255, 255, .08));color:var(--color-text-primary, #ffffff)}.btn-ghost:active:not(:disabled){background:var(--element-bg-base, rgba(255, 255, 255, .1))}.btn-dashed{background:transparent;color:var(--color-text-secondary, #e5e5e5);border:1px dashed var(--border-base, rgba(255, 255, 255, .16))}.btn-dashed:hover:not(:disabled){background:var(--element-bg-subtle, rgba(255, 255, 255, .08));color:var(--color-text-primary, #ffffff);border-style:solid;border-color:var(--border-medium, rgba(255, 255, 255, .24))}.btn-dashed:active:not(:disabled){background:var(--element-bg-base, rgba(255, 255, 255, .1));border-color:var(--border-strong, rgba(255, 255, 255, .32))}.btn-icon-only{padding:0;width:var(--button-height-base, 40px);aspect-ratio:1}.btn-icon-only.btn-sm{width:var(--button-height-sm, 32px)}.btn-icon-only.btn-lg{width:var(--button-height-lg, 48px)}.btn-loading{cursor:wait;pointer-events:none}.btn-loading-icon{color:currentColor}.btn-loading-text{position:relative;z-index:var(--ds-z-raised, 2)}.btn-action{display:inline-flex;align-items:center;gap:var(--size-gap-2, 8px);padding:12px var(--size-gap-4, 16px);font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-medium, 500);font-family:var(--font-family-sans, inherit);cursor:pointer;position:relative;outline:none;border:none;border-radius:var(--size-radius-sm, 6px);transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));background:var(--element-bg-base, rgba(255, 255, 255, .08));color:var(--color-text-secondary, #e5e5e5)}.btn-action:hover{background:var(--element-bg-medium, rgba(255, 255, 255, .14));color:var(--color-text-primary, #ffffff)}.btn-action-ai{background:#8b5cf62e;color:#8b5cf6}.btn-action-ai:hover{background:#8b5cf647;color:#fff}.btn-action-ai:hover svg{color:#8b5cf6}.btn-action-ai:active{background:#8b5cf638}.btn-action-danger{background:#c770702e;color:var(--color-text-primary, #ffffff)}.btn-action-danger:hover{background:#c770705c;color:var(--color-text-primary, #ffffff)}.btn-action-danger:active{background:#c7707047}.btn-action-success{background:#6eb88c2e;color:var(--color-success, #6eb88c)}.btn-action-success:hover{background:#6eb88c47;color:#fff}.btn-action-success:active{background:#6eb88c38}.btn-action:disabled{opacity:.45;cursor:default;pointer-events:none}.btn.btn-action-danger:hover:not(:disabled){background:#c770705c;color:var(--color-text-primary, #ffffff)}.btn.btn-action-danger:active:not(:disabled){background:#c7707047}.ds-dialog-overlay{position:fixed;inset:0;z-index:var(--ds-z-dialog, var(--ds-z-modal, 240));display:flex;align-items:center;justify-content:center;padding:var(--ds-space-6, 24px);background:color-mix(in srgb,var(--ds-color-bg-scene, #050506) 58%,transparent);animation:ds-dialog-overlay-fade .16s ease}.ds-dialog-overlay--bottom-left{align-items:flex-end;justify-content:flex-start;padding:0 0 var(--ds-space-5, 20px) var(--ds-space-5, 20px)}.ds-dialog-overlay--bottom-left .ds-dialog{animation-name:ds-dialog-enter-bottom}.ds-dialog-overlay--bottom-right{align-items:flex-end;justify-content:flex-end;padding:0 var(--ds-space-5, 20px) var(--ds-space-5, 20px) 0}.ds-dialog-overlay--bottom-right .ds-dialog{animation-name:ds-dialog-enter-bottom}.ds-dialog{background:var(--ds-color-bg-elevated, var(--color-bg-elevated, #18181a));border:1px solid var(--ds-color-border-base, var(--border-base, rgba(255, 255, 255, .14)));position:relative;display:flex;flex-direction:column;width:100%;max-height:calc(100vh - 48px);overflow:hidden;color:var(--ds-color-text-secondary, var(--color-text-secondary));border-radius:var(--ds-radius-lg, 8px);box-shadow:var(--ds-shadow-modal, 0 16px 40px rgba(0, 0, 0, .45));animation:ds-dialog-enter .18s cubic-bezier(.16,1,.3,1)}.ds-dialog:focus{outline:none}.ds-dialog--small{max-width:420px}.ds-dialog--medium{max-width:560px}.ds-dialog--large{max-width:640px}.ds-dialog--xlarge{max-width:min(760px,100%)}.ds-dialog__header-shell{position:relative;flex-shrink:0}.ds-dialog__header-shell--close-only{min-height:34px}.ds-dialog__header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;gap:var(--ds-space-2, 8px);min-height:34px;padding:var(--ds-space-2, 8px) var(--ds-space-3, 12px);border-bottom:1px solid var(--ds-color-border-subtle, var(--border-subtle))}.ds-dialog--with-close .ds-dialog__header{padding-inline-end:calc(var(--ds-space-3, 12px) + 30px)}.ds-dialog--without-dividers .ds-dialog__header,.ds-dialog--without-dividers .ds-dialog__footer{border:0}.ds-dialog__title-group{display:flex;min-width:0;align-items:center;gap:var(--ds-space-2, 8px)}.ds-dialog__title{min-width:0;margin:0;overflow:hidden;color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 13px);font-weight:600;line-height:1.35;text-overflow:ellipsis;white-space:nowrap}.ds-dialog__title-extra{display:inline-flex;flex-shrink:0;align-items:center}.ds-dialog__close{position:absolute;inset-block-start:6px;inset-inline-end:var(--ds-space-2, 8px);z-index:var(--ds-z-local, 1);display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;color:var(--ds-color-text-muted, var(--color-text-muted));cursor:pointer;background:transparent;border:1px solid transparent;border-radius:var(--ds-radius-sm, 6px)}.ds-dialog__close:hover{color:var(--ds-color-text-primary, var(--color-text-primary));background:var(--ds-color-bg-subtle, var(--element-bg-subtle));border-color:var(--ds-color-border-subtle, var(--border-subtle))}.ds-dialog__close:focus-visible{outline:2px solid var(--ds-focus-ring, var(--ds-color-border-focus, var(--color-accent-400, rgba(96, 165, 250, .4))));outline-offset:2px}.ds-dialog__body{overflow:auto;flex:1;min-height:0;padding:0}.ds-dialog__body--inset,.ds-dialog--content-inset .ds-dialog__body{padding-inline:var(--ds-space-7, 28px)}.ds-dialog__body--fill-flex{display:flex;flex-direction:column;overflow:hidden}.ds-dialog__footer{display:flex;flex-shrink:0;align-items:center;justify-content:flex-end;gap:var(--ds-space-2, 8px);padding:var(--ds-space-3, 12px);border-top:1px solid var(--ds-color-border-subtle, var(--border-subtle))}@keyframes ds-dialog-overlay-fade{0%{opacity:0}to{opacity:1}}@keyframes ds-dialog-enter{0%{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes ds-dialog-enter-bottom{0%{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@media(max-width:480px){.ds-dialog-overlay{padding:var(--ds-space-4, 16px)}.ds-dialog-overlay--bottom-left,.ds-dialog-overlay--bottom-right{align-items:flex-end;justify-content:center;padding:var(--ds-space-4, 16px)}.ds-dialog{max-height:calc(100vh - 32px)}.ds-dialog--small,.ds-dialog--medium{max-width:100%}.ds-dialog__title{font-size:var(--ds-font-size-md, 14px)}.ds-dialog__body--inset,.ds-dialog--content-inset .ds-dialog__body{padding-inline:var(--ds-space-4, 16px)}}.ds-tooltip{position:fixed;opacity:0;pointer-events:none;z-index:var(--ds-z-tooltip, 360);transform:scale(.98);transition:opacity .12s ease-out,transform .12s ease-out}.ds-tooltip--visible{opacity:1;pointer-events:none;transform:scale(1)}.ds-tooltip--interactive.ds-tooltip--visible{pointer-events:auto}.ds-tooltip__content{padding:6px 10px;font-family:var(--font-family-sans);font-size:var(--font-size-xs, 12px);font-weight:var(--font-weight-normal, 400);line-height:1.4;color:var(--color-text-primary);background:var(--color-bg-tooltip);border:1px solid var(--border-base);border-radius:var(--size-radius-sm, 6px);backdrop-filter:blur(8px) saturate(1.1);-webkit-backdrop-filter:blur(8px) saturate(1.1);box-shadow:var(--shadow-sm);max-width:280px;word-wrap:break-word;-webkit-user-select:text;user-select:text}.ds-tooltip--top.ds-tooltip--visible{animation:ds-tooltip-fade-in-top .12s ease-out}.ds-tooltip--bottom.ds-tooltip--visible{animation:ds-tooltip-fade-in-bottom .12s ease-out}.ds-tooltip--left.ds-tooltip--visible{animation:ds-tooltip-fade-in-left .12s ease-out}.ds-tooltip--right.ds-tooltip--visible{animation:ds-tooltip-fade-in-right .12s ease-out}@keyframes ds-tooltip-fade-in-top{0%{opacity:0;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}@keyframes ds-tooltip-fade-in-bottom{0%{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:translateY(0)}}@keyframes ds-tooltip-fade-in-left{0%{opacity:0;transform:translate(3px)}to{opacity:1;transform:translate(0)}}@keyframes ds-tooltip-fade-in-right{0%{opacity:0;transform:translate(-3px)}to{opacity:1;transform:translate(0)}}@media(prefers-contrast:high){.ds-tooltip__content{border-width:1px;border-color:#fff6;box-shadow:0 2px 8px #00000040}}@media(prefers-reduced-motion:reduce){.ds-tooltip{transition:opacity .08s ease;transform:none}.ds-tooltip--visible{transform:none;animation:none}}.icon-btn{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:var(--size-radius-sm, 6px);cursor:pointer;position:relative;outline:none;-webkit-user-select:none;user-select:none;flex-shrink:0;transform:scale(1);transform-origin:center;transition:transform var(--motion-fast, .15s) var(--easing-standard, ease),background var(--motion-fast, .15s) var(--easing-standard, ease),color var(--motion-fast, .15s) var(--easing-standard, ease);background:transparent;color:var(--color-text-secondary, #a0a0a0)}.icon-btn:hover:not(:disabled){transform:scale(1.06);background:#ffffff14;color:var(--color-accent-500, #60a5fa)}.icon-btn:active:not(:disabled){transform:scale(1.02);background:#ffffff0f}.icon-btn svg{display:block;flex-shrink:0;transition:color var(--motion-fast, .15s) var(--easing-standard, ease)}.icon-btn--xs{width:24px;height:24px}.icon-btn--xs svg{width:14px;height:14px}.icon-btn--small{width:28px;height:28px}.icon-btn--small svg{width:16px;height:16px}.icon-btn--medium{width:32px;height:32px}.icon-btn--medium svg{width:16px;height:16px}.icon-btn--large{width:40px;height:40px}.icon-btn--large svg{width:20px;height:20px}.icon-btn--circle{border-radius:50%}.icon-btn--ghost{background:transparent;color:var(--ds-color-text-secondary, var(--color-text-secondary, #a0a0a0))}.icon-btn--ghost:hover:not(:disabled){background:var(--ds-color-element-soft, rgba(255, 255, 255, .08));color:var(--ds-color-accent-500, var(--color-accent-500, #60a5fa))}.icon-btn--ghost:active:not(:disabled){background:var(--ds-color-element-medium, rgba(255, 255, 255, .06));color:var(--ds-color-accent-500, var(--color-accent-500, #60a5fa))}.icon-btn--accent{background:var(--ds-color-accent-500, var(--color-accent-500, #60a5fa));color:#fff;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 72%,#ffffff 8%)}.icon-btn--accent:hover:not(:disabled){background:color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 82%,var(--ds-color-bg-app, #0f172a));color:#fff;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 68%,#ffffff 10%)}.icon-btn--accent:active:not(:disabled){background:color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 74%,var(--ds-color-bg-app, #0f172a));color:#fff}.icon-btn--primary{background:var(--btn-primary-bg, var(--color-accent-200, rgba(96, 165, 250, .2)));color:var(--btn-primary-color, var(--color-accent-600, #3b82f6));box-shadow:var(--btn-primary-shadow, none)}.icon-btn--primary:hover:not(:disabled){background:var(--btn-primary-hover-bg, var(--color-accent-300, rgba(96, 165, 250, .3)));color:var(--btn-primary-hover-color, var(--color-text-primary, #ffffff));box-shadow:var(--btn-primary-hover-shadow, none)}.icon-btn--primary:active:not(:disabled){background:var(--btn-primary-active-bg, var(--color-accent-200, rgba(96, 165, 250, .24)));color:var(--btn-primary-active-color, var(--color-text-primary, #ffffff));box-shadow:var(--btn-primary-active-shadow, none)}.icon-btn--primary:focus-visible{outline-color:color-mix(in srgb,var(--btn-primary-bg, var(--color-accent-500, #60a5fa)) 55%,transparent)}.icon-btn--danger{background:transparent;color:var(--color-text-secondary, #a0a0a0)}.icon-btn--danger:hover:not(:disabled){background:#c7707047;color:var(--color-error, #c77070)}.icon-btn--danger:active:not(:disabled){background:#c7707038;color:var(--color-error, #c77070)}.icon-btn--success{background:#6eb88c2e;color:var(--color-success, #6eb88c)}.icon-btn--success:hover:not(:disabled){background:#6eb88c47;color:#fff}.icon-btn--success:active:not(:disabled){background:#6eb88c38}.icon-btn--warning{background:#c9944d2e;color:var(--color-warning, #c9944d)}.icon-btn--warning:hover:not(:disabled){background:#c9944d47;color:#fff}.icon-btn--warning:active:not(:disabled){background:#c9944d38}.icon-btn--ai{background:#8b5cf62e;color:#8b5cf6}.icon-btn--ai:hover:not(:disabled){background:#8b5cf647;color:#fff}.icon-btn--ai:active:not(:disabled){background:#8b5cf638}.icon-btn--brand{background:var(--color-error);color:#fff}.icon-btn--brand:hover:not(:disabled){background:color-mix(in srgb,var(--color-error) 86%,var(--color-text-primary));color:#fff}.icon-btn--brand:active:not(:disabled){background:color-mix(in srgb,var(--color-error) 78%,var(--color-text-primary));color:#fff}.icon-btn:focus-visible{outline:2px solid rgba(96,165,250,.5);outline-offset:1px}.icon-btn:disabled{opacity:.45;cursor:default;pointer-events:none}.icon-btn--loading{cursor:wait;pointer-events:none}.icon-btn--loading svg{animation:icon-btn-spin 1s linear infinite}@keyframes icon-btn-spin{to{transform:rotate(360deg)}}.ds-date-range-dialog__content{min-width:min(100%,300px);padding-block:var(--ds-space-6, 24px)}.ds-date-range-dialog{display:flex;flex-direction:column;gap:var(--ds-space-3, 12px)}.ds-date-range-dialog__summary{margin:0;padding:var(--ds-space-2, 8px) var(--ds-space-3, 12px);color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 13px);font-variant-numeric:tabular-nums;text-align:center;background:color-mix(in srgb,var(--ds-color-bg-subtle, var(--ds-color-element-subtle)) 75%,transparent);border:1px solid color-mix(in srgb,var(--ds-color-border-strong, var(--ds-color-border-subtle)) 88%,transparent);border-radius:var(--ds-radius-md, 8px)}.ds-date-range-dialog__calendar{display:flex;flex-direction:column;gap:var(--ds-space-2, 8px);-webkit-user-select:none;user-select:none}.ds-date-range-dialog__calendar-nav{display:flex;align-items:center;justify-content:space-between;gap:var(--ds-space-2, 8px)}.ds-date-range-dialog__calendar-title{flex:1;color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 13px);font-weight:600;text-align:center}.ds-date-range-dialog__dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.ds-date-range-dialog__dow{color:var(--ds-color-text-secondary, var(--color-text-secondary));font-size:var(--ds-font-size-2xs, 10px);font-weight:500;line-height:1.2;opacity:.85}.ds-date-range-dialog__grid{display:grid;grid-template-columns:repeat(7,1fr);column-gap:0;row-gap:6px}.ds-date-range-dialog__cell{position:relative;display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:100%;height:auto;max-height:38px;aspect-ratio:1;padding:0;color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-xs, 12px);font-variant-numeric:tabular-nums;cursor:pointer;background:transparent;border:none;border-radius:8px;transition:background var(--ds-motion-base, .18s) var(--ds-easing-standard, ease),color var(--ds-motion-base, .18s) var(--ds-easing-standard, ease),border-radius var(--ds-motion-base, .18s) var(--ds-easing-standard, ease)}.ds-date-range-dialog__cell:hover:not(:disabled):not(.ds-date-range-dialog__cell--empty):not(.ds-date-range-dialog__cell--in-range):not(.ds-date-range-dialog__cell--edge-start):not(.ds-date-range-dialog__cell--edge-end):not(.ds-date-range-dialog__cell--single){background:color-mix(in srgb,var(--ds-color-bg-subtle, var(--ds-color-element-subtle)) 92%,transparent)}.ds-date-range-dialog__cell:focus-visible{z-index:var(--ds-z-local, 1);outline:2px solid color-mix(in srgb,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 55%,transparent);outline-offset:2px}.ds-date-range-dialog__cell--empty{visibility:hidden;pointer-events:none}.ds-date-range-dialog__cell--disabled{cursor:not-allowed;opacity:.28}.ds-date-range-dialog__cell--today:not(.ds-date-range-dialog__cell--in-range):not(.ds-date-range-dialog__cell--edge-start):not(.ds-date-range-dialog__cell--edge-end):not(.ds-date-range-dialog__cell--single){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 45%,var(--ds-color-border-strong, var(--ds-color-border-subtle)))}.ds-date-range-dialog__cell--in-range{color:var(--ds-color-text-primary, var(--color-text-primary));font-weight:600;background:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 55%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 45%);background-color:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 55%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 45%);border-radius:8px}.ds-date-range-dialog__cell--edge-start,.ds-date-range-dialog__cell--edge-end{color:var(--ds-color-text-primary, var(--color-text-primary));font-weight:700;background:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 38%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 62%);background-color:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 38%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 62%);border-radius:8px}.ds-date-range-dialog__cell--single{color:var(--ds-color-text-primary, var(--color-text-primary));font-weight:700;background:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 30%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 70%);background-color:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 30%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 70%);border-radius:8px}.ds-date-range-dialog__cell--bridge-left:not(.ds-date-range-dialog__cell--single){border-top-left-radius:0;border-bottom-left-radius:0}.ds-date-range-dialog__cell--bridge-right:not(.ds-date-range-dialog__cell--single){border-top-right-radius:0;border-bottom-right-radius:0}.ds-date-range-dialog__cell--in-range:hover:not(:disabled){background:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 48%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 52%);background-color:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 48%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 52%)}.ds-date-range-dialog__cell--edge-start:hover:not(:disabled),.ds-date-range-dialog__cell--edge-end:hover:not(:disabled),.ds-date-range-dialog__cell--single:hover:not(:disabled){background:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 28%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 72%);background-color:color-mix(in srgb,var(--ds-color-bg-elevated, var(--ds-color-bg-surface)) 28%,var(--ds-color-accent, var(--ds-color-accent-500, var(--color-accent-500))) 72%)}.ds-date-range-dialog__error{margin:0;color:var(--ds-color-danger, var(--color-error));font-size:var(--ds-font-size-xs, 12px)}.ds-date-range-dialog__actions{display:flex;justify-content:flex-end;gap:var(--ds-space-2, 8px);padding-top:var(--ds-space-1, 4px);border-top:1px solid color-mix(in srgb,var(--ds-color-border-strong, var(--ds-color-border-subtle)) 70%,transparent)}.select{position:relative;width:100%;min-width:0}.select__label{display:block;margin-bottom:var(--size-gap-2, 8px);font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-medium, 500);color:var(--color-text-secondary, #e5e5e5);letter-spacing:.2px}.select__trigger{display:flex;align-items:center;gap:var(--size-gap-3, 12px);padding:6px 12px;background:transparent;border:1px solid var(--border-base, rgba(255, 255, 255, .14));border-radius:var(--size-radius-sm, 6px);cursor:pointer;transition:all var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));min-height:36px;position:relative;min-width:0;overflow:hidden}.select__trigger:hover:not(.select--disabled .select__trigger){background:var(--element-bg-subtle, rgba(255, 255, 255, .05));border-color:var(--border-strong, rgba(255, 255, 255, .26))}.select__trigger:focus-visible{outline:none;background:transparent;border-color:var(--color-accent-500, #60a5fa)}.select--open .select__trigger{background:var(--color-bg-secondary, #18181a);border-style:solid;border-color:var(--border-medium, rgba(255, 255, 255, .2));border-bottom-color:transparent;border-radius:var(--size-radius-sm, 6px) var(--size-radius-sm, 6px) 0 0}.select--open.select--placement-top .select__trigger{border-bottom-color:var(--border-medium, rgba(255, 255, 255, .2));border-top-color:transparent;border-radius:0 0 var(--size-radius-sm, 6px) var(--size-radius-sm, 6px)}.select--shape-pill .select__trigger{min-height:34px;padding-block:5px;border-color:transparent;border-radius:var(--ds-radius-full, 999px);background:var(--ds-color-element-subtle, var(--element-bg-subtle));box-shadow:none}.select--shape-pill .select__trigger:hover:not(.select--disabled .select){border-color:transparent;background:var(--ds-color-element-soft, var(--element-bg-soft))}.select--shape-pill .select__trigger:focus-visible{border-color:transparent;background:var(--ds-color-element-medium, var(--element-bg-medium))}.select--shape-pill.select--open .select__trigger,.select--shape-pill.select--open.select--placement-top .select__trigger{border-color:transparent;border-radius:var(--ds-radius-full, 999px);background:var(--ds-color-element-medium, var(--element-bg-medium))}.select--shape-pill .select__dropdown{border:0;border-radius:var(--ds-radius-lg, 12px)}.select--shape-pill .select__dropdown:before{content:none}.select--shape-pill .select__dropdown--bottom{top:calc(100% + var(--ds-space-1, 4px))}.select--shape-pill .select__dropdown--top{bottom:calc(100% + var(--ds-space-1, 4px));border:0;border-radius:var(--ds-radius-lg, 12px)}.select--disabled{opacity:var(--opacity-disabled, .6);cursor:default}.select--disabled .select__trigger{cursor:default}.select--error .select__trigger{border-color:var(--color-error-border, rgba(199, 112, 112, .3))}.select--error .select__trigger:hover:not(.select--disabled .select--error .select__trigger){border-color:var(--color-error, #c77070)}.select__value,.select__placeholder{flex:1;font-size:var(--font-size-sm, 14px);line-height:var(--line-height-base, 1.5);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:var(--size-gap-2, 8px)}.select__value{color:var(--color-text-primary, #e8e8e8)}.select__placeholder{color:var(--color-text-muted, #a0a0a0)}.select__value-icon,.select__option-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0}.select__tags{flex:1;display:flex;flex-wrap:wrap;gap:6px;max-width:100%}.select__tag{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;background:transparent;border:1px solid var(--border-accent-soft, rgba(59, 130, 246, .3));border-radius:var(--size-radius-sm, 6px);font-size:var(--font-size-xs, 12px);color:var(--color-accent-500, #60a5fa);max-width:150px;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.select__tag:hover{background:var(--color-accent-100, rgba(96, 165, 250, .08));border-color:var(--border-accent, rgba(59, 130, 246, .4))}.select__tag--more{background:transparent;border:1px solid var(--border-base, rgba(255, 255, 255, .14));color:var(--color-text-secondary, #e5e5e5);cursor:default}.select__tag--more:hover{background:transparent}.select__tag-icon{display:flex;align-items:center;flex-shrink:0}.select__tag-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select__tag-remove{display:flex;align-items:center;justify-content:center;width:14px;height:14px;padding:0;border:0;border-radius:50%;background:transparent;cursor:pointer;font-size:14px;font-family:inherit;line-height:1;color:var(--color-text-muted, #a0a0a0);transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));margin-left:2px}.select__tag-remove:hover{background:var(--color-error-bg, rgba(199, 112, 112, .1));color:var(--color-error, #c77070)}.select__suffix{display:flex;align-items:center;gap:var(--size-gap-2, 8px);flex-shrink:0}.select__clear{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--color-text-muted, #a0a0a0);cursor:pointer;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));font-size:16px;font-family:inherit;line-height:1}.select__clear:hover{background:var(--color-error-bg, rgba(199, 112, 112, .1));color:var(--color-error, #c77070)}.select__loading{display:flex;align-items:center}.select__loading-spinner{color:var(--ds-color-accent-500)}.select__arrow{display:flex;align-items:center;justify-content:center;color:var(--color-text-muted, #a0a0a0);transition:all var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.select__arrow--open{transform:rotate(180deg);color:var(--color-accent-500, #60a5fa)}.select__dropdown{position:absolute;left:0;right:0;max-height:240px;background:var(--color-bg-secondary, #18181a);border:1px solid var(--border-medium, rgba(255, 255, 255, .2));border-top:none;border-radius:0 0 var(--size-radius-sm, 6px) var(--size-radius-sm, 6px);box-shadow:0 4px 12px #0006;z-index:60;animation:select-dropdown-appear var(--motion-fast, .15s) var(--easing-decelerate, cubic-bezier(0, 0, .2, 1));overflow:hidden;display:flex;flex-direction:column}.select__dropdown:before{content:"";position:absolute;top:0;left:8px;right:8px;height:1px;background:var(--border-subtle, rgba(255, 255, 255, .1))}.select__dropdown--bottom{top:100%}.select__dropdown--top{bottom:100%;border-top:1px solid var(--border-medium, rgba(255, 255, 255, .2));border-bottom:none;border-radius:var(--size-radius-sm, 6px) var(--size-radius-sm, 6px) 0 0;box-shadow:0 -4px 12px #0006}.select__dropdown--top:before{top:auto;bottom:0}.select__search{padding:6px 8px;border-bottom:1px solid var(--border-subtle, rgba(255, 255, 255, .08));position:relative;display:flex;align-items:center}.select__search-clear{position:absolute;right:16px;display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--color-text-muted, #a0a0a0);cursor:pointer;font-size:14px;font-family:inherit;line-height:1;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));flex-shrink:0}.select__search-clear:hover{background:var(--color-error-bg, rgba(199, 112, 112, .1));color:var(--color-error, #c77070)}.select__search-input{width:100%;padding:6px 28px 6px 10px;background:var(--element-bg-subtle, rgba(255, 255, 255, .05));border:none;border-radius:3px;color:var(--color-text-primary, #e8e8e8);font-size:var(--font-size-sm, 14px);font-family:inherit;outline:none!important;box-shadow:none!important;appearance:none;-webkit-appearance:none;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.select__search-input::placeholder{color:var(--color-text-muted, #a0a0a0)}.select__search-input:hover{background:var(--element-bg-soft, rgba(255, 255, 255, .08))}.select__search-input:focus,.select__search-input:focus-visible{background:var(--element-bg-soft, rgba(255, 255, 255, .08));outline:none!important;box-shadow:none!important}.select__select-all{display:flex;align-items:center;gap:8px;width:calc(100% - 8px);padding:6px 10px 8px;margin:4px 4px 0;border:0;cursor:pointer;font-size:var(--font-size-sm, 14px);font-family:inherit;color:var(--color-accent-500, #60a5fa);font-weight:var(--font-weight-medium, 500);border-bottom:1px solid var(--border-subtle, rgba(255, 255, 255, .08));background:transparent;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));border-radius:var(--ds-radius-sm, var(--size-radius-sm, 6px))}.select__select-all:hover{background:var(--element-bg-subtle, rgba(255, 255, 255, .05))}.select__options{flex:1;overflow-y:auto;padding:4px}.select__option{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));font-size:var(--font-size-sm, 14px);color:var(--color-text-secondary, #e5e5e5);border-radius:var(--ds-radius-sm, var(--size-radius-sm, 6px));margin-bottom:1px;position:relative;background:transparent}.select__option:last-child{margin-bottom:0}.select__option:hover:not(.select__option--disabled){background:var(--element-bg-subtle, rgba(255, 255, 255, .05));color:var(--color-text-primary, #e8e8e8)}.select__option--highlighted:not(.select__option--disabled){background:var(--element-bg-subtle, rgba(255, 255, 255, .05));color:var(--color-text-primary, #e8e8e8)}.select__option--selected{background:var(--color-accent-100, rgba(96, 165, 250, .08));color:var(--color-accent-500, #60a5fa);font-weight:var(--font-weight-medium, 500)}.select__option--selected:hover{background:var(--color-accent-200, rgba(96, 165, 250, .15))}.select__option--disabled{opacity:var(--opacity-disabled, .6);cursor:default;color:var(--color-text-disabled, #666666)}.select__option-content{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.select__option-text{flex:1;min-width:0}.select__option-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select__option-description{font-size:var(--font-size-xs, 12px);color:var(--color-text-muted, #a0a0a0);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select__checkbox{width:16px;height:16px;border:1px solid var(--border-medium, rgba(255, 255, 255, .2));border-radius:3px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:11px;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));background:transparent;color:transparent}.select__checkbox--checked{background:var(--color-accent-500, #60a5fa);border-color:var(--color-accent-500, #60a5fa);color:#fff}.select__group:not(:first-child){margin-top:var(--size-gap-2, 8px);padding-top:var(--size-gap-2, 8px);border-top:1px solid var(--border-subtle, rgba(255, 255, 255, .1))}.select__group-label{padding:6px 12px;font-size:var(--font-size-xs, 12px);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-muted, #a0a0a0);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.select__empty{padding:24px 16px;text-align:center;color:var(--color-text-muted, #a0a0a0);font-size:var(--font-size-sm, 14px)}.select__empty--loading{display:flex;align-items:center;justify-content:center;gap:8px}.select__custom-value-hint{display:flex;align-items:center;justify-content:space-between;width:calc(100% - 8px);gap:8px;padding:8px 12px;cursor:pointer;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));font-size:var(--font-size-sm, 14px);color:var(--color-accent-500, #60a5fa);border-radius:var(--ds-radius-sm, var(--size-radius-sm, 6px));margin:4px;background:var(--color-accent-100, rgba(96, 165, 250, .08));border:1px dashed var(--border-accent-soft, rgba(59, 130, 246, .3))}.select__custom-value-hint:hover{background:var(--color-accent-200, rgba(96, 165, 250, .15));border-color:var(--border-accent, rgba(59, 130, 246, .4))}.select__custom-value-text{font-weight:var(--font-weight-medium, 500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select__custom-value-action{font-size:var(--font-size-xs, 12px);color:var(--color-text-muted, #a0a0a0);white-space:nowrap;flex-shrink:0}.select__value-label--custom{color:var(--color-accent-500, #60a5fa);font-style:italic}.select__error-message{margin-top:6px;font-size:var(--font-size-xs, 12px);color:var(--color-error, #c77070);display:flex;align-items:center;gap:4px}.select--small .select__trigger{padding:4px 10px;min-height:28px}.select--small .select__label{font-size:13px;margin-bottom:6px}.select--small .select__value,.select--small .select__placeholder{font-size:13px}.select--small .select__option{padding:5px 8px;font-size:13px}.select--small .select__tag{padding:2px 6px;font-size:12px}.select--small .select__checkbox{width:14px;height:14px;font-size:10px}.select--large .select__trigger{padding:10px 14px;min-height:44px}.select--large .select__label{font-size:15px;margin-bottom:10px}.select--large .select__value,.select--large .select__placeholder{font-size:15px}.select--large .select__option{padding:8px 12px;font-size:15px}.select--large .select__tag{padding:4px 10px;font-size:13px}.select--large .select__checkbox{width:18px;height:18px;font-size:12px}@keyframes select-dropdown-appear{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.ds-checkbox{display:inline-flex;align-items:flex-start;gap:12px;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.ds-checkbox--disabled{opacity:.6;cursor:default}.ds-checkbox__wrapper{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px}.ds-checkbox__input{position:absolute;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;z-index:var(--ds-z-local, 1)}.ds-checkbox__input:disabled{cursor:default}.ds-checkbox__box{position:relative;display:flex;align-items:center;justify-content:center;width:18px;height:18px;background:transparent;border:1px solid var(--border-subtle);border-radius:6px;transition:all .2s ease;pointer-events:none}.ds-checkbox__icon{width:11px;height:11px;color:#fff;opacity:0;transform:scale(.5);transition:all .2s ease}.ds-checkbox__content{display:flex;flex-direction:column;gap:3px;flex:1}.ds-checkbox__label{font-size:var(--font-size-sm);font-weight:500;color:#e8e8e8;line-height:1.5}.ds-checkbox__description{font-size:var(--font-size-xs);color:#a0a0a0;line-height:1.5}.ds-checkbox__input:checked+.ds-checkbox__box{background:#6366f11a;border-color:var(--color-accent-500)}.ds-checkbox__input:checked+.ds-checkbox__box .ds-checkbox__icon{opacity:1;transform:scale(1);color:var(--color-accent-500)}.ds-checkbox__input:indeterminate+.ds-checkbox__box{background:#6366f11a;border-color:var(--color-accent-500)}.ds-checkbox__input:indeterminate+.ds-checkbox__box .ds-checkbox__icon{opacity:1;transform:scale(1);color:var(--color-accent-500)}.ds-checkbox__input:focus-visible+.ds-checkbox__box{outline:2px solid rgba(96,165,250,.4);outline-offset:2px}.ds-checkbox:hover:not(.ds-checkbox--disabled) .ds-checkbox__box{border-color:var(--border-base);background:var(--element-bg-subtle)}.ds-checkbox:hover:not(.ds-checkbox--disabled) .ds-checkbox__input:checked+.ds-checkbox__box,.ds-checkbox:hover:not(.ds-checkbox--disabled) .ds-checkbox__input:indeterminate+.ds-checkbox__box{background:#6366f126;border-color:var(--color-accent-400)}.ds-checkbox:hover:not(.ds-checkbox--disabled) .ds-checkbox__input:checked+.ds-checkbox__box .ds-checkbox__icon,.ds-checkbox:hover:not(.ds-checkbox--disabled) .ds-checkbox__input:indeterminate+.ds-checkbox__box .ds-checkbox__icon{color:var(--color-accent-400)}.ds-checkbox__input:active:not(:disabled)+.ds-checkbox__box{transform:scale(.95)}.ds-checkbox--error .ds-checkbox__box{border-color:#ef444499}.ds-checkbox--error .ds-checkbox__input:checked+.ds-checkbox__box{background:#ef44441a;border-color:#ef4444cc}.ds-checkbox--error .ds-checkbox__input:checked+.ds-checkbox__box .ds-checkbox__icon{color:#ef4444}.ds-checkbox--small{gap:8px}.ds-checkbox--small .ds-checkbox__wrapper{margin-top:1px}.ds-checkbox--small .ds-checkbox__box{width:16px;height:16px;border-radius:4px}.ds-checkbox--small .ds-checkbox__icon{width:9px;height:9px}.ds-checkbox--small .ds-checkbox__label{font-size:var(--font-size-xs)}.ds-checkbox--small .ds-checkbox__description{font-size:11px}.ds-checkbox--large{gap:16px}.ds-checkbox--large .ds-checkbox__wrapper{margin-top:3px}.ds-checkbox--large .ds-checkbox__box{width:20px;height:20px;border-radius:6px}.ds-checkbox--large .ds-checkbox__icon{width:13px;height:13px}.ds-checkbox--large .ds-checkbox__label{font-size:var(--font-size-base)}.ds-checkbox--large .ds-checkbox__description{font-size:var(--font-size-xs)}.ds-radio{display:inline-flex;align-items:flex-start;gap:12px;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.ds-radio--disabled{opacity:.6;cursor:default}.ds-radio__wrapper{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px}.ds-radio__input{position:absolute;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;z-index:var(--ds-z-local, 1)}.ds-radio__input:disabled{cursor:default}.ds-radio__mark{position:relative;display:flex;align-items:center;justify-content:center;width:18px;height:18px;background:transparent;border:1px solid var(--border-subtle);border-radius:999px;transition:all .2s ease;pointer-events:none}.ds-radio__mark:after{content:"";width:8px;height:8px;border-radius:999px;background:var(--color-accent-500);opacity:0;transform:scale(.4);transition:all .2s ease}.ds-radio__content{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}.ds-radio__label{font-size:var(--font-size-sm);font-weight:500;color:#e8e8e8;line-height:1.5}.ds-radio__description{font-size:var(--font-size-xs);color:#a0a0a0;line-height:1.5}.ds-radio__input:checked+.ds-radio__mark{background:color-mix(in srgb,var(--color-accent-500) 10%,transparent);border-color:var(--color-accent-500)}.ds-radio__input:checked+.ds-radio__mark:after{opacity:1;transform:scale(1)}.ds-radio__input:focus-visible+.ds-radio__mark{outline:2px solid rgba(96,165,250,.4);outline-offset:2px}.ds-radio:hover:not(.ds-radio--disabled) .ds-radio__mark{border-color:var(--border-base);background:var(--element-bg-subtle)}.ds-radio:hover:not(.ds-radio--disabled) .ds-radio__input:checked+.ds-radio__mark{background:color-mix(in srgb,var(--color-accent-400) 14%,transparent);border-color:var(--color-accent-400)}.ds-radio__input:active:not(:disabled)+.ds-radio__mark{transform:scale(.95)}.ds-radio--error .ds-radio__mark{border-color:var(--ds-color-danger-border)}.ds-radio--error .ds-radio__input:checked+.ds-radio__mark{background:var(--ds-color-danger-bg);border-color:var(--ds-color-danger-border-strong)}.ds-radio--error .ds-radio__input:checked+.ds-radio__mark:after{background:var(--ds-color-danger-text)}.ds-radio--small{gap:8px}.ds-radio--small .ds-radio__wrapper{margin-top:1px}.ds-radio--small .ds-radio__mark{width:16px;height:16px}.ds-radio--small .ds-radio__mark:after{width:6px;height:6px}.ds-radio--small .ds-radio__label{font-size:var(--font-size-xs)}.ds-radio--small .ds-radio__description{font-size:11px}.ds-radio--large{gap:16px}.ds-radio--large .ds-radio__wrapper{margin-top:3px}.ds-radio--large .ds-radio__mark{width:20px;height:20px}.ds-radio--large .ds-radio__mark:after{width:10px;height:10px}.ds-radio--large .ds-radio__label{font-size:var(--font-size-base)}.ds-radio--large .ds-radio__description{font-size:var(--font-size-xs)}.ds-switch{--ds-switch-on-bg: var(--btn-primary-bg, var(--color-accent-500));--ds-switch-on-hover-bg: var(--btn-primary-hover-bg, var(--ds-switch-on-bg));--ds-switch-on-border: var(--btn-primary-border, var(--ds-switch-on-bg));--ds-switch-on-thumb-bg: var(--btn-primary-color, var(--color-bg-elevated, #fff));display:inline-flex;align-items:flex-start;gap:12px;cursor:pointer;-webkit-user-select:none;user-select:none}.ds-switch--disabled{opacity:.6;cursor:default}.ds-switch--loading{cursor:wait}.ds-switch__wrapper{position:relative;display:flex;align-items:center;flex-shrink:0;margin-top:2px}.ds-switch__input{position:absolute;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;z-index:var(--ds-z-local, 1)}.ds-switch__input:disabled{cursor:default}.ds-switch__track{position:relative;display:flex;align-items:center;width:36px;height:20px;padding:2px;background:transparent;border:1px solid var(--border-subtle);border-radius:10px;box-shadow:inset 0 0 0 1px transparent;transition:all .2s ease;pointer-events:none}.ds-switch__track--checked{background:var(--ds-switch-on-bg);border-color:var(--ds-switch-on-border);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-switch-on-thumb-bg) 18%,transparent),0 0 0 2px color-mix(in srgb,var(--ds-switch-on-bg) 18%,transparent)}.ds-switch__text{position:absolute;font-size:9px;font-weight:600;color:#a0a0a0;text-transform:uppercase;letter-spacing:.5px;transition:opacity .2s ease}.ds-switch__thumb{position:absolute;left:2px;width:16px;height:16px;background:var(--element-bg-subtle);border:1px solid var(--border-base);border-radius:50%;transition:all .2s ease;display:flex;align-items:center;justify-content:center;z-index:var(--ds-z-raised, 2)}.ds-switch__loading{width:10px;height:10px;color:var(--color-accent-500, #60a5fa);animation:ds-switch-spin 1s linear infinite}.ds-switch__input:checked+.ds-switch__track .ds-switch__thumb{left:calc(100% - 18px);background:var(--ds-switch-on-thumb-bg);border-color:color-mix(in srgb,var(--ds-switch-on-bg) 42%,transparent);box-shadow:0 1px 3px color-mix(in srgb,#000 22%,transparent),0 0 0 1px color-mix(in srgb,var(--ds-switch-on-thumb-bg) 34%,transparent)}.ds-switch__input:focus-visible+.ds-switch__track{outline:2px solid var(--color-accent-400, rgba(96, 165, 250, .4));outline-offset:2px}.ds-switch:hover:not(.ds-switch--disabled):not(.ds-switch--loading) .ds-switch__track{border-color:var(--border-base)}.ds-switch:hover:not(.ds-switch--disabled):not(.ds-switch--loading) .ds-switch__thumb{background:var(--element-bg-base);border-color:var(--border-base)}.ds-switch:hover:not(.ds-switch--disabled):not(.ds-switch--loading) .ds-switch__input:checked+.ds-switch__track{background:var(--ds-switch-on-hover-bg);border-color:var(--ds-switch-on-hover-bg);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-switch-on-thumb-bg) 22%,transparent),0 0 0 2px color-mix(in srgb,var(--ds-switch-on-hover-bg) 24%,transparent)}.ds-switch:hover:not(.ds-switch--disabled):not(.ds-switch--loading) .ds-switch__input:checked+.ds-switch__track .ds-switch__thumb{background:var(--ds-switch-on-thumb-bg);border-color:color-mix(in srgb,var(--ds-switch-on-hover-bg) 48%,transparent)}.ds-switch__input:active:not(:disabled)+.ds-switch__track{transform:scale(.98)}.ds-switch__content{display:flex;flex-direction:column;gap:4px}.ds-switch__label{font-size:var(--font-size-sm);font-weight:500;color:var(--color-text-primary, #e8e8e8);line-height:1.5}.ds-switch__description{font-size:var(--font-size-xs);color:var(--color-text-muted, #a0a0a0);line-height:1.5}.ds-switch--small{gap:8px}.ds-switch--small .ds-switch__track{width:32px;height:18px;border-radius:9px;padding:2px}.ds-switch--small .ds-switch__thumb{width:14px;height:14px;left:2px}.ds-switch--small .ds-switch__input:checked+.ds-switch__track .ds-switch__thumb{left:calc(100% - 16px)}.ds-switch--small .ds-switch__loading{width:8px;height:8px}.ds-switch--small .ds-switch__label{font-size:var(--font-size-xs)}.ds-switch--small .ds-switch__description{font-size:11px}.ds-switch--large{gap:16px}.ds-switch--large .ds-switch__wrapper{margin-top:2px}.ds-switch--large .ds-switch__track{width:44px;height:24px;border-radius:12px;padding:2px}.ds-switch--large .ds-switch__thumb{width:20px;height:20px}.ds-switch--large .ds-switch__input:checked+.ds-switch__track .ds-switch__thumb{left:calc(100% - 22px)}.ds-switch--large .ds-switch__loading{width:12px;height:12px}.ds-switch--large .ds-switch__label{font-size:var(--font-size-base)}.ds-switch--large .ds-switch__description{font-size:var(--font-size-xs)}:root[data-theme-type=dark] .ds-switch{--ds-switch-on-bg: var(--color-accent-500);--ds-switch-on-hover-bg: var(--color-accent-600, var(--color-accent-500));--ds-switch-on-border: color-mix(in srgb, var(--color-accent-500) 78%, #fff);--ds-switch-on-thumb-bg: #ffffff}:root[data-theme=slate] .ds-switch{--ds-switch-on-bg: var(--color-purple-500, var(--color-accent-500));--ds-switch-on-hover-bg: var(--color-purple-600, var(--color-accent-600));--ds-switch-on-border: color-mix(in srgb, var(--color-purple-500, var(--color-accent-500)) 82%, #fff)}@keyframes ds-switch-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ds-textarea{display:flex;flex-direction:column;gap:8px;width:100%}.ds-textarea__label{font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-medium, 500);color:var(--color-text-primary);line-height:1.4}.ds-textarea__required{color:var(--color-error);margin-left:4px}.ds-textarea__wrapper{position:relative;width:100%;outline:none}.ds-textarea:focus-within{outline:none}.ds-textarea__field{width:100%;min-height:100px;padding:12px 14px;font-size:14px;line-height:1.5;color:var(--color-text-primary);background:var(--element-bg-subtle);border:1.5px solid var(--border-base);border-radius:4px;transition:all .2s cubic-bezier(.4,0,.2,1);resize:vertical;font-family:inherit}.ds-textarea__field::placeholder{color:var(--color-text-muted)}.ds-textarea__field::selection{border-radius:2px;background:var(--color-accent-300)}.ds-textarea__field:hover:not(:disabled){border-color:var(--border-medium);background:var(--element-bg-soft)}.ds-textarea__field:focus{outline:none!important;border-color:var(--border-medium);background:var(--element-bg-subtle)}.ds-textarea__field:focus-visible{outline:none!important;outline-offset:0!important}.ds-textarea__field:disabled{opacity:var(--opacity-disabled, .4);cursor:default}.ds-textarea__footer{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;min-height:18px}.ds-textarea__hint-wrapper{flex:1}.ds-textarea__hint{font-size:12px;color:var(--color-text-muted);line-height:1.4}.ds-textarea__error-message{font-size:12px;color:var(--color-error);line-height:1.4}.ds-textarea__count{font-size:12px;color:var(--color-text-muted);line-height:1.4;white-space:nowrap}.ds-textarea--error .ds-textarea__field{border-color:var(--color-error-border)}.ds-textarea--error .ds-textarea__field:focus{border-color:var(--color-error-border);background:var(--element-bg-subtle)}.ds-textarea--error .ds-textarea__field:focus-visible{outline:none}.ds-textarea--disabled{opacity:.5;cursor:default}.ds-textarea--filled .ds-textarea__field{background:var(--element-bg-soft);border-color:transparent}.ds-textarea--filled .ds-textarea__field:hover:not(:disabled){background:var(--element-bg-base)}.ds-textarea--filled .ds-textarea__field:focus{background:var(--element-bg-soft);border-color:transparent}.ds-textarea--outlined .ds-textarea__field{background:transparent;border-width:1.5px;border-color:var(--border-subtle)}.ds-textarea--outlined .ds-textarea__field:hover:not(:disabled){border-color:var(--border-medium);background:var(--element-bg-subtle)}.ds-textarea--outlined .ds-textarea__field:focus{border-color:var(--border-medium);background:var(--element-bg-subtle)}.ds-popup-menu{background:var(--ds-color-bg-elevated, var(--color-bg-elevated, #18181a));border:1px solid var(--ds-color-border-base, var(--border-base, rgba(255, 255, 255, .14)));border-color:transparent;border-radius:var(--ds-radius-xl, 16px);box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-color-border-base) 42%,transparent),var(--ds-shadow-floating, 0 16px 34px var(--ds-shadow-color-floating, rgba(0, 0, 0, .45))),0 28px 64px -20px color-mix(in srgb,var(--ds-shadow-color-floating, rgba(0, 0, 0, .45)) 82%,transparent);--ds-popup-menu-row-hover-bg: var(--ds-color-element-soft, var(--element-bg-soft));isolation:isolate;color:var(--ds-color-text-secondary, var(--color-text-secondary));outline:none;animation:ds-popup-menu-enter .14s cubic-bezier(.16,1,.3,1)}.ds-popup-menu--padding-none{padding:0}.ds-popup-menu--padding-compact{padding:var(--ds-space-1, 4px)}@keyframes ds-popup-menu-enter{0%{opacity:0;transform:translateY(3px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}@media(prefers-reduced-motion:reduce){.ds-popup-menu{animation:none}}.cl-dropdown-menu__backdrop{position:fixed;inset:0;z-index:100}.cl-dropdown-menu{position:fixed;z-index:340}.cl-dropdown-menu__submenu-wrap{position:relative}.cl-dropdown-menu__item{display:flex;align-items:center;gap:8px;width:100%;height:30px;padding:0 8px;border:none;border-radius:var(--ds-list-row-radius, var(--ds-radius-full));background:transparent;color:var(--color-text-secondary);cursor:pointer;font-size:var(--font-size-sm, 13px);font-weight:400;text-align:left;white-space:nowrap;transition:color .15s cubic-bezier(.4,0,.2,1),background .15s cubic-bezier(.4,0,.2,1)}.cl-dropdown-menu__item:hover,.cl-dropdown-menu__item.is-open{color:var(--color-text-primary);background:var(--ds-popup-menu-row-hover-bg)}.cl-dropdown-menu__item.is-checked{color:var(--color-text-primary)}.cl-dropdown-menu__item:focus-visible{outline:2px solid var(--color-accent-500);outline-offset:-1px}.cl-dropdown-menu__item:disabled{opacity:.5;cursor:default;pointer-events:auto}.cl-dropdown-menu__item:disabled:hover{color:var(--color-text-secondary);background:transparent}.cl-dropdown-menu__item-label{flex:1;min-width:0;text-align:left;overflow:hidden;text-overflow:ellipsis}.cl-dropdown-menu__check-icon{flex-shrink:0;color:var(--color-accent-500)}.cl-dropdown-menu__submenu-icon{flex-shrink:0;opacity:.65;transition:opacity .15s cubic-bezier(.4,0,.2,1),transform .15s cubic-bezier(.4,0,.2,1)}.cl-dropdown-menu__item:hover .cl-dropdown-menu__submenu-icon,.cl-dropdown-menu__item.is-open .cl-dropdown-menu__submenu-icon{opacity:.95}.cl-dropdown-menu__submenu-icon.is-open{transform:rotate(90deg)}.cl-dropdown-menu__submenu{position:absolute;top:0;min-width:200px;max-height:min(70vh,360px);overflow-x:hidden;overflow-y:auto;z-index:341}.cl-dropdown-menu__submenu.is-right{left:calc(100% + 4px)}.cl-dropdown-menu__submenu.is-left{right:calc(100% + 4px)}.cl-dropdown-menu__separator{height:1px;margin:4px 8px;background:var(--border-subtle, rgba(255, 255, 255, .08))}.cl-dropdown-menu__label{display:flex;flex-direction:column;gap:1px;padding:4px 8px;color:var(--color-text-secondary);font-size:11px;opacity:.7;pointer-events:none;white-space:nowrap}.badge{display:inline-flex;align-items:center;gap:3px;padding:2px 8px;border-radius:6px;font-size:var(--badge-font-size, var(--font-size-xs));font-weight:500;line-height:1;border:none;white-space:nowrap;flex-shrink:0}.badge--neutral{background:var(--element-bg-base);color:var(--color-text-secondary)}.badge--accent{background:var(--color-accent-200);color:var(--color-text-secondary)}.badge--purple{background:var(--color-purple-200);color:var(--color-purple-500)}.badge--success{background:var(--color-success-bg);color:var(--color-success)}.badge--warning{background:var(--color-warning-bg);color:var(--color-warning)}.badge--error{background:var(--color-error-bg);color:var(--color-error)}.badge--info{background:var(--color-info-bg);color:var(--color-info)}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 16px;border-radius:8px;border:1px solid;background:var(--element-bg-soft);backdrop-filter:blur(8px) saturate(1.1);-webkit-backdrop-filter:blur(8px) saturate(1.1);position:relative}.alert--success{border-color:var(--color-success-border);background:linear-gradient(135deg,#34d3990f,#34d3990a)}.alert--success .alert__icon{color:var(--color-success)}.alert--success .alert__title{color:var(--color-text-primary)}.alert--error{border-color:var(--color-error-border);background:linear-gradient(135deg,#ef44440f,#ef44440a)}.alert--error .alert__icon{color:var(--color-error)}.alert--error .alert__title{color:var(--color-text-primary)}.alert--warning{border-color:var(--color-warning-border);background:linear-gradient(135deg,#f59e0b0f,#f59e0b0a)}.alert--warning .alert__icon{color:var(--color-warning)}.alert--warning .alert__title{color:var(--color-text-primary)}.alert--info{border-color:var(--color-info-border);background:linear-gradient(135deg,#60a5fa0f,#60a5fa0a)}.alert--info .alert__icon{color:var(--color-info)}.alert--info .alert__title{color:var(--color-text-primary)}.alert__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}.alert__icon svg{display:block}.alert__content{flex:1;min-width:0}.alert__title{font-size:var(--font-size-sm);font-weight:500;line-height:1.5;margin-bottom:2px}.alert__message{font-size:var(--font-size-xs);color:var(--color-text-secondary);line-height:1.5}.alert__description{font-size:var(--font-size-xs);color:var(--color-text-muted);line-height:1.5;margin-top:4px}.alert__close{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;border:none;background:transparent;color:var(--color-text-muted);cursor:pointer;border-radius:6px;transition:all .3s cubic-bezier(.4,0,.2,1)}.alert__close:hover{background:var(--element-bg-medium);color:var(--color-text-primary)}.ds-avatar{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;background:linear-gradient(135deg,#60a5fa33,#3b82f633);border:2px solid rgba(96,165,250,.3);color:#ffffffe6;font-weight:500;vertical-align:middle;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.ds-avatar img{width:100%;height:100%;object-fit:cover}.ds-avatar__icon{display:flex;align-items:center;justify-content:center;width:60%;height:60%}.ds-avatar__icon svg{width:100%;height:100%}.ds-avatar__text{font-size:14px;line-height:1;transform:scale(.8)}.ds-avatar--circle{border-radius:50%}.ds-avatar--square{border-radius:8px}.ds-avatar--small{font-size:12px}.ds-avatar--medium{font-size:14px}.ds-avatar--large{font-size:16px}.ds-avatar-group{display:inline-flex;align-items:center}.ds-avatar-group .ds-avatar{margin-left:-8px;border:2px solid rgba(15,23,42,.8);transition:all .2s cubic-bezier(.4,0,.2,1)}.ds-avatar-group .ds-avatar:first-child{margin-left:0}.ds-avatar-group .ds-avatar:hover{transform:translateY(-2px);z-index:var(--ds-z-local, 1);box-shadow:0 4px 12px #60a5fa4d}.ds-avatar-group__rest{background:linear-gradient(135deg,#1e293be6,#334155e6);font-size:12px}.v-card{display:flex;flex-direction:column;position:relative;background:var(--card-bg-default, rgba(255, 255, 255, .04));border:none;border-radius:var(--size-radius-base, 8px);color:var(--color-text-secondary, #e5e5e5);transition:all var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.v-card--default{background:var(--card-bg-default, rgba(255, 255, 255, .04))}.v-card--elevated{background:var(--card-bg-elevated, rgba(255, 255, 255, .06))}.v-card--subtle{background:var(--card-bg-subtle, rgba(255, 255, 255, .02))}.v-card--accent{background:var(--card-bg-accent, rgba(96, 165, 250, .1))}.v-card--accent .v-card-header__title{color:var(--color-accent-500, #60a5fa)}.v-card--purple{background:var(--card-bg-purple, rgba(139, 92, 246, .1))}.v-card--purple .v-card-header__title{color:var(--color-purple-500, #8b5cf6)}.v-card--interactive{cursor:pointer}.v-card--interactive:hover{background:var(--card-bg-hover, rgba(255, 255, 255, .06))}.v-card--interactive:active{background:var(--card-bg-active, rgba(255, 255, 255, .08))}.v-card--interactive.v-card--accent:hover{background:var(--card-bg-accent-hover, rgba(96, 165, 250, .14))}.v-card--interactive.v-card--purple:hover{background:var(--card-bg-purple-hover, rgba(139, 92, 246, .14))}.v-card--interactive.v-card--elevated:hover{background:var(--card-bg-active, rgba(255, 255, 255, .08))}.v-card--interactive.v-card--subtle:hover{background:var(--card-bg-default, rgba(255, 255, 255, .04))}.v-card--padding-none{padding:0}.v-card--padding-small{padding:var(--size-gap-2, 8px)}.v-card--padding-medium{padding:var(--size-gap-4, 16px)}.v-card--padding-large{padding:var(--size-gap-6, 24px)}.v-card--radius-small{border-radius:var(--size-radius-sm, 6px)}.v-card--radius-medium{border-radius:var(--size-radius-base, 8px)}.v-card--radius-large{border-radius:var(--size-radius-lg, 12px)}.v-card--full-width{width:100%}.v-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--size-gap-3, 12px)}.v-card-header__content{flex:1;min-width:0}.v-card-header__title{font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-primary, #e8e8e8);line-height:var(--line-height-tight, 1.2);margin-bottom:var(--size-gap-1, 4px)}.v-card-header__subtitle{font-size:var(--font-size-xs, 12px);color:var(--color-text-muted, #a0a0a0);line-height:var(--line-height-base, 1.5)}.v-card-header__extra{flex-shrink:0;display:flex;align-items:center;gap:var(--size-gap-2, 8px)}.v-card-body{flex:1;color:var(--color-text-secondary, #e5e5e5);font-size:var(--font-size-sm, 14px);line-height:var(--line-height-relaxed, 1.6)}.v-card-header+.v-card-body{margin-top:var(--size-gap-3, 12px);padding-top:var(--size-gap-3, 12px);border-top:1px dashed var(--color-border-subtle, rgba(255, 255, 255, .08))}.v-card-footer{display:flex;align-items:center;gap:var(--size-gap-2, 8px)}.v-card-body+.v-card-footer,.v-card-header+.v-card-footer{margin-top:var(--size-gap-4, 16px)}.v-card-footer--left{justify-content:flex-start}.v-card-footer--center{justify-content:center}.v-card-footer--right{justify-content:flex-end}.v-card-footer--between{justify-content:space-between}.cube-loading{align-items:center;color:var(--ds-color-text-muted);display:flex;flex-direction:column;gap:var(--ds-space-2)}.cube-loading__matrix{color:currentColor}.cube-loading__text{color:var(--ds-color-text-muted);font-size:var(--ds-font-size-sm);line-height:var(--ds-line-height-tight)}.ds-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ds-space-10, 40px) var(--ds-space-5, 20px);text-align:center}.ds-empty-state__image{margin-bottom:var(--ds-space-4, 16px);opacity:.8;animation:ds-empty-state-fade-in .5s ease-out}.ds-empty-state__image svg{display:block}.ds-empty-state__description{display:flex;flex-direction:column;gap:var(--ds-space-1, 4px);margin-bottom:var(--ds-space-4, 16px);color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-md, 14px);animation:ds-empty-state-fade-in .5s ease-out .1s both}.ds-empty-state__description strong{color:var(--ds-color-text-primary, var(--color-text-primary));font-weight:600}.ds-empty-state__footer{animation:ds-empty-state-fade-in .5s ease-out .2s both}@keyframes ds-empty-state-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.v-filter-pill-group{display:flex;gap:8px;flex-wrap:wrap}.v-filter-pill{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;background:#ffffff12;border:1px solid transparent;border-radius:14px;color:var(--color-text-secondary);font-size:var(--font-size-xs);font-weight:500;font-family:Noto Sans SC,PingFang SC,Microsoft YaHei,-apple-system,BlinkMacSystemFont,Segoe UI,SF Pro Display,Roboto,sans-serif;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);white-space:nowrap}.v-filter-pill:hover:not(:disabled){background:#ffffff18;color:var(--color-text-primary)}.v-filter-pill--active{background:var(--ds-color-element-soft, rgba(255, 255, 255, .07));border-color:transparent;color:var(--ds-color-text-primary, var(--color-text-primary))}.v-filter-pill--active .v-filter-pill__count{background:var(--ds-color-element-base, rgba(255, 255, 255, .095));color:var(--ds-color-text-secondary, var(--color-text-secondary))}.v-filter-pill--active:hover:not(:disabled){background:var(--ds-color-element-soft, rgba(255, 255, 255, .07))}.v-filter-pill--disabled{opacity:.6;cursor:not-allowed}.v-filter-pill__label{flex-shrink:0}.v-filter-pill__count{display:inline-flex;align-items:center;justify-content:center;padding:1px 5px;background:#ffffff18;border-radius:6px;font-size:10px;font-weight:600;font-family:Fira Code,JetBrains Mono,SF Mono,Consolas,Noto Sans SC,Microsoft YaHei,Liberation Mono,monospace;color:var(--color-text-muted)}.ds-floating-card{background:var(--ds-color-bg-elevated, var(--color-bg-elevated, #18181a));border:1px solid var(--ds-color-border-base, var(--border-base, rgba(255, 255, 255, .14)));border-color:transparent;border-radius:var(--ds-radius-2xl, 20px);box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-color-border-base) 42%,transparent),var(--ds-shadow-floating, 0 16px 34px var(--ds-shadow-color-floating, rgba(0, 0, 0, .45))),0 28px 64px -20px color-mix(in srgb,var(--ds-shadow-color-floating, rgba(0, 0, 0, .45)) 82%,transparent);position:relative;isolation:isolate;color:var(--ds-color-text-secondary, var(--color-text-secondary));animation:ds-floating-card-enter .18s cubic-bezier(.16,1,.3,1)}.ds-floating-card:focus{outline:none}.ds-floating-card--padding-compact{padding:var(--ds-space-3, 12px)}.ds-floating-card--padding-default{padding:var(--ds-space-4, 16px)}.ds-floating-card--padding-spacious{padding:var(--ds-space-5, 20px)}.ds-floating-card--dismissible{padding-inline-end:calc(var(--ds-space-4, 16px) + 26px)}.ds-floating-card__action.icon-btn{color:var(--ds-color-text-muted, var(--color-text-muted));background:var(--ds-color-element-soft, var(--element-bg-soft));border:1px solid color-mix(in srgb,var(--ds-color-border-base) 72%,transparent);box-shadow:inset 0 1px color-mix(in srgb,var(--ds-color-text-primary) 5%,transparent)}.ds-floating-card__action.icon-btn:hover:not(:disabled){color:var(--ds-color-text-primary, var(--color-text-primary));background:var(--ds-color-element-medium, var(--element-bg-medium));border-color:var(--ds-color-border-base, var(--border-base))}.ds-floating-card__dismiss.icon-btn{position:absolute;inset-block-start:var(--ds-space-2, 8px);inset-inline-end:var(--ds-space-2, 8px);z-index:var(--ds-z-local, 1);background:transparent;border-color:transparent;box-shadow:none}.ds-floating-card__dismiss.icon-btn:hover:not(:disabled),.ds-floating-card__dismiss.icon-btn:focus-visible{background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:transparent;box-shadow:none}@keyframes ds-floating-card-enter{0%{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}@media(prefers-reduced-motion:reduce){.ds-floating-card{animation:none}}.ds-input-wrapper{display:flex;flex-direction:column;gap:6px;min-width:0}.ds-input-wrapper--small .ds-input-container{height:var(--button-height-sm, 32px);font-size:13px}.ds-input-wrapper--small .ds-input-prefix,.ds-input-wrapper--small .ds-input-suffix{font-size:13px}.ds-input-wrapper--medium .ds-input-container{height:36px;font-size:14px}.ds-input-wrapper--large .ds-input-container{height:44px;font-size:15px}.ds-input-wrapper--default .ds-input-container{background:transparent;border:1px solid var(--border-base, rgba(255, 255, 255, .14))}.ds-input-wrapper--filled .ds-input-container{background:var(--element-bg-subtle, rgba(255, 255, 255, .05));border:1px solid transparent}.ds-input-wrapper--filled .ds-input-container:hover:not(.ds-input-wrapper--disabled .ds-input-wrapper--filled .ds-input-container){background:var(--element-bg-soft, rgba(255, 255, 255, .08));border-color:var(--border-base, rgba(255, 255, 255, .14))}.ds-input-wrapper--filled .ds-input-container:focus-within{background:var(--element-bg-soft, rgba(255, 255, 255, .08));border-color:var(--ds-input-focus-border, transparent)}.ds-input-wrapper--filled .ds-input-container:hover:focus-within{border-color:var(--ds-input-focus-border, var(--color-accent-500, #60a5fa))}.ds-input-wrapper--outlined .ds-input-container{background:transparent;border:1px solid var(--border-medium, rgba(255, 255, 255, .2))}.ds-input-wrapper--pill .ds-input-container{border-radius:var(--ds-radius-full, 999px)}.ds-input-wrapper--focus-danger{--ds-input-focus-border: var(--ds-color-danger-border, var(--color-error, #c77070))}.ds-input-wrapper--error .ds-input-container{border-color:var(--color-error-border, rgba(199, 112, 112, .3))!important}.ds-input-wrapper--error .ds-input-container:hover:not(.ds-input-wrapper--disabled .ds-input-wrapper--error .ds-input-container){border-color:var(--color-error, #c77070)!important}.ds-input-wrapper--error .ds-input-container:focus-within{border-color:var(--color-error, #c77070)!important}.ds-input-wrapper--disabled{opacity:var(--opacity-disabled, .6);cursor:default}.ds-input-wrapper--disabled .ds-input-container{background:transparent}.ds-input-label{font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-medium, 500);color:var(--color-text-secondary, #e5e5e5);letter-spacing:.2px}.ds-input-container{display:flex;align-items:center;gap:var(--size-gap-2, 8px);padding:0 var(--size-gap-3, 12px);border-radius:4px;transition:all var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1));position:relative;min-width:0;overflow:hidden}.ds-input-container:hover:not(.ds-input-wrapper--disabled .ds-input-container){background:var(--element-bg-subtle, rgba(255, 255, 255, .05));border-color:var(--border-strong, rgba(255, 255, 255, .26))}.ds-input-container:focus-within{background:transparent;border-color:var(--color-accent-500, #60a5fa);outline:none}.ds-input-wrapper--focus-danger .ds-input-container:focus-within{border-color:var(--ds-color-danger, var(--color-error, #c77070))!important}.ds-input-wrapper--focus-danger:not(.ds-input-wrapper--disabled) .ds-input-container:hover{border-color:var(--ds-color-danger, var(--color-error, #c77070))}.ds-input{flex:1;min-width:0;background:transparent;border:none!important;outline:none!important;box-shadow:none!important;color:var(--color-text-primary, #e8e8e8);font-family:inherit;position:relative;z-index:var(--ds-z-local, 1)}.ds-input::placeholder{color:color-mix(in srgb,var(--color-text-muted, #a0a0a0) 40%,var(--color-bg-primary, #121214))}.ds-input::selection{border-radius:2px;background:var(--color-accent-300)}.ds-input:focus,.ds-input:focus-visible{border:none!important;outline:none!important;outline-offset:0!important;box-shadow:none!important}.ds-input:disabled{cursor:default}.ds-input-prefix,.ds-input-suffix{color:var(--color-text-muted, #a0a0a0);display:flex;align-items:center;flex-shrink:0;position:relative;z-index:var(--ds-z-local, 1)}.ds-input-error-message{font-size:var(--font-size-xs, 12px);color:var(--color-error, #c77070);margin-top:-2px}.ds-segmented-control{align-items:center;background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-md, 8px);display:inline-flex;gap:2px;min-width:0;padding:2px}.ds-segmented-control--stretch{display:flex;width:100%}.ds-segmented-control--disabled{opacity:.62}.ds-segmented-control__item{align-items:center;background:transparent;border:0;border-radius:calc(var(--ds-radius-md, 8px) - 2px);color:var(--ds-color-text-secondary, var(--color-text-secondary));cursor:pointer;display:inline-flex;flex:0 1 auto;font:inherit;font-size:var(--ds-font-size-sm, 13px);font-weight:var(--ds-font-weight-medium, 500);gap:var(--ds-space-2, 8px);justify-content:center;line-height:1.2;min-width:0;padding:7px var(--ds-space-3, 12px);transition:background var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease)}.ds-segmented-control__item:hover:not(:disabled){background:var(--ds-color-element-soft, var(--element-bg-soft));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-segmented-control__item:focus-visible{outline:2px solid var(--ds-focus-ring, var(--color-accent-400));outline-offset:2px}.ds-segmented-control__item:disabled{cursor:not-allowed;opacity:.56}.ds-segmented-control__item--selected{background:var(--ds-color-surface-base, var(--surface-bg-base));box-shadow:var(--ds-shadow-sm, 0 1px 2px var(--shadow-color));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-segmented-control--small .ds-segmented-control__item{font-size:var(--ds-font-size-xs, 12px);padding:5px var(--ds-space-2, 8px)}.ds-segmented-control--accent,.ds-segmented-control--accent .ds-segmented-control__item{border-radius:var(--ds-radius-full, 999px);box-shadow:none}.ds-segmented-control--accent .ds-segmented-control__item:hover:not(:disabled):not(.ds-segmented-control__item--selected){background:var(--ds-color-element-soft, var(--element-bg-soft))}.ds-segmented-control--accent .ds-segmented-control__item--selected{background:var(--btn-primary-bg, var(--ds-color-accent-500, var(--color-accent-500)));color:var(--btn-primary-color, var(--ds-color-text-inverse, white));font-weight:var(--ds-font-weight-semibold, 600)}.ds-segmented-control--stretch .ds-segmented-control__item{flex:1 1 0}.ds-segmented-control__icon{align-items:center;display:inline-flex;flex:0 0 auto}.ds-segmented-control__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ds-divider-switch{background:transparent;border:0;border-radius:0;gap:0;padding:0}.ds-divider-switch .ds-segmented-control__item{background:transparent;border-radius:0;box-shadow:none;color:var(--ds-color-text-muted);position:relative;padding-inline:var(--ds-space-3)}.ds-divider-switch .ds-segmented-control__item:before{background:var(--ds-color-border-subtle);content:"";height:14px;left:0;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%);width:1px}.ds-divider-switch .ds-segmented-control__item:first-child:before{content:none}.ds-divider-switch .ds-segmented-control__item:after{background:transparent;border-radius:var(--ds-radius-sm);content:"";inset:2px 5px;pointer-events:none;position:absolute;transition:background var(--ds-motion-fast) var(--ds-easing-standard)}.ds-divider-switch .ds-segmented-control__item--selected{background:transparent;color:var(--ds-color-text-primary);font-weight:var(--ds-font-weight-semibold)}.ds-divider-switch .ds-segmented-control__item:hover:not(:disabled){background:transparent}.ds-divider-switch .ds-segmented-control__item:hover:not(:disabled):after{background:var(--ds-color-element-soft)}.ds-divider-switch .ds-segmented-control__label,.ds-divider-switch .ds-segmented-control__icon{position:relative;z-index:var(--ds-z-local)}.ds-divider-switch--medium .ds-segmented-control__item{font-size:var(--ds-font-size-sm, 13px);padding-block:9px;padding-inline:var(--ds-space-4, 16px)}.ds-divider-switch--medium .ds-segmented-control__item:before{height:16px}.ds-mode-switch--divider{background:transparent;border:0;border-radius:0;gap:0;padding:0}.ds-mode-switch--divider .ds-segmented-control__item{background:transparent;border-radius:0;box-shadow:none;color:var(--ds-color-text-muted);position:relative;padding-inline:var(--ds-space-3)}.ds-mode-switch--divider .ds-segmented-control__item:before{background:var(--ds-color-border-subtle);content:"";height:14px;left:0;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%);width:1px}.ds-mode-switch--divider .ds-segmented-control__item:first-child:before{content:none}.ds-mode-switch--divider .ds-segmented-control__item:after{background:transparent;border-radius:var(--ds-radius-sm);content:"";inset:2px 5px;pointer-events:none;position:absolute;transition:background var(--ds-motion-fast) var(--ds-easing-standard)}.ds-mode-switch--divider .ds-segmented-control__item--selected{background:transparent;color:var(--ds-color-text-primary);font-weight:var(--ds-font-weight-semibold)}.ds-mode-switch--divider .ds-segmented-control__item:hover:not(:disabled){background:transparent}.ds-mode-switch--divider .ds-segmented-control__item:hover:not(:disabled):after{background:var(--ds-color-element-soft)}.ds-mode-switch--divider .ds-segmented-control__label,.ds-mode-switch--divider .ds-segmented-control__icon{position:relative;z-index:var(--ds-z-local)}.ds-mode-switch--slider{position:relative;isolation:isolate;display:inline-grid;grid-template-columns:repeat(var(--ds-mode-switch-option-count),minmax(0,1fr));min-height:34px;padding:2px;border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-full, 999px);background:var(--ds-color-element-subtle, var(--element-bg-subtle));box-shadow:none}.ds-mode-switch--slider:before{position:absolute;inset-block:2px;inset-inline-start:2px;z-index:var(--ds-z-base);width:var(--ds-mode-switch-indicator-width);border-radius:var(--ds-radius-full, 999px);background:var(--btn-primary-bg, var(--ds-color-accent-500, var(--color-accent-500)));box-shadow:none;content:"";pointer-events:none;transform:translate(var(--ds-mode-switch-active-offset));transition:transform var(--ds-motion-base) var(--ds-easing-decelerate),background var(--ds-motion-fast) var(--ds-easing-standard)}.ds-mode-switch--slider .ds-segmented-control__item{position:relative;z-index:var(--ds-z-local);min-width:52px;min-height:28px;padding-inline:var(--ds-space-2);border-radius:var(--ds-radius-full, 999px);background:transparent;box-shadow:none;transition:transform var(--ds-motion-fast) var(--ds-easing-standard),color var(--ds-motion-fast) var(--ds-easing-standard),background var(--ds-motion-fast) var(--ds-easing-standard)}.ds-mode-switch--slider .ds-segmented-control__item:after{content:none}.ds-mode-switch--slider .ds-segmented-control__item:hover:not(:disabled):not(.ds-segmented-control__item--selected){background:color-mix(in srgb,var(--ds-color-element-soft, var(--element-bg-soft)) 72%,transparent);color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-mode-switch--slider .ds-segmented-control__item:active:not(:disabled){transform:scale(.98)}.ds-mode-switch--slider .ds-segmented-control__item--selected{background:transparent;box-shadow:none;color:var(--btn-primary-color, var(--ds-color-text-inverse, var(--color-text-inverse)));font-weight:var(--ds-font-weight-semibold, 600)}.ds-mode-switch--slider.ds-segmented-control--stretch{display:grid}@media(prefers-reduced-motion:reduce){.ds-mode-switch--slider:before,.ds-mode-switch--slider .ds-segmented-control__item{transition:none}}.ds-number-field{display:flex;flex-direction:column;gap:6px}.ds-number-field__label{color:var(--color-text-secondary, #e5e5e5);font-size:var(--font-size-sm, 14px);font-weight:var(--font-weight-medium, 500);letter-spacing:.2px}.ds-number-field__container{position:relative;display:flex;align-items:center;overflow:hidden;background:transparent;border:1px solid var(--border-base, rgba(255, 255, 255, .14));border-radius:var(--size-radius-sm, 6px);transition:all var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.ds-number-field__container:hover:not(.ds-number-field--disabled .ds-number-field__container){background:var(--element-bg-subtle, rgba(255, 255, 255, .05));border-color:var(--border-strong, rgba(255, 255, 255, .26))}.ds-number-field__container:focus-within{background:transparent;border-color:var(--color-accent-500, #60a5fa)}.ds-number-field__value-area{position:relative;z-index:var(--ds-z-local, 1);display:flex;flex:1;align-items:center;gap:4px;padding:0 12px}.ds-number-field__input{flex:1;width:100%;min-width:0;padding:0;color:var(--color-text-primary, #e8e8e8);font:inherit;font-weight:var(--font-weight-medium, 500);font-variant-numeric:tabular-nums;text-align:center;background:transparent;border:none!important;outline:none!important;box-shadow:none!important}.ds-number-field__input::placeholder{color:var(--color-text-muted, #a0a0a0)}.ds-number-field__input:disabled{cursor:default}.ds-number-field__input::-webkit-outer-spin-button,.ds-number-field__input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.ds-number-field__input[type=number]{-moz-appearance:textfield}.ds-number-field__unit{flex-shrink:0;color:var(--color-text-muted, #a0a0a0);font-size:.85em;font-weight:var(--font-weight-normal, 400);opacity:.8}.ds-number-field__buttons{position:relative;z-index:var(--ds-z-local, 1);display:flex;flex-direction:column;border-left:1px solid var(--border-subtle, rgba(255, 255, 255, .1))}.ds-number-field__btn{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--color-text-muted, #a0a0a0);cursor:pointer;background:transparent;border:none;transition:all var(--motion-fast, .15s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.ds-number-field__btn:hover:not(:disabled){color:var(--color-accent-500, #60a5fa);background:var(--element-bg-subtle, rgba(255, 255, 255, .05))}.ds-number-field__btn:active:not(:disabled){transform:scale(.9)}.ds-number-field__btn:disabled{cursor:default;opacity:.3}.ds-number-field__btn svg{position:relative;z-index:var(--ds-z-local, 1)}.ds-number-field__btn--up{border-bottom:1px solid var(--border-subtle, rgba(255, 255, 255, .08));border-radius:0 var(--size-radius-sm, 6px) 0 0}.ds-number-field__btn--down{border-radius:0 0 var(--size-radius-sm, 6px) 0}.ds-number-field__btn--minus,.ds-number-field__btn--plus{border-radius:var(--size-radius-sm, 6px)}.ds-number-field__progress{position:absolute;right:0;bottom:0;left:0;height:2px;overflow:hidden;background:transparent;opacity:0;transition:opacity var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.ds-number-field__container:hover .ds-number-field__progress,.ds-number-field__container:focus-within .ds-number-field__progress{opacity:1}.ds-number-field__progress-bar{height:100%;background:var(--color-accent-500, #60a5fa);border-radius:0 2px 2px 0;transition:width var(--motion-base, .3s) var(--easing-standard, cubic-bezier(.4, 0, .2, 1))}.ds-number-field--small .ds-number-field__container{height:28px;font-size:12px}.ds-number-field--small .ds-number-field__value-area{padding:0 8px}.ds-number-field--small .ds-number-field__btn{width:22px;height:14px}.ds-number-field--small .ds-number-field__btn svg{width:12px;height:12px}.ds-number-field--medium .ds-number-field__container{height:36px;font-size:14px}.ds-number-field--medium .ds-number-field__btn{width:28px;height:18px}.ds-number-field--large .ds-number-field__container{height:44px;font-size:16px}.ds-number-field--large .ds-number-field__value-area{padding:0 16px}.ds-number-field--large .ds-number-field__btn{width:36px;height:22px}.ds-number-field--large .ds-number-field__btn svg{width:16px;height:16px}.ds-number-field--compact .ds-number-field__container{border-radius:var(--size-radius-sm, 6px)}.ds-number-field--compact .ds-number-field__value-area{padding:0 8px}.ds-number-field--compact .ds-number-field__progress{display:none}.ds-number-field--stepper .ds-number-field__buttons{position:absolute;inset:0;flex-direction:row;justify-content:space-between;pointer-events:none;border-left:none}.ds-number-field--stepper .ds-number-field__btn{width:32px;height:100%;pointer-events:auto;border:none}.ds-number-field--stepper .ds-number-field__btn--minus{border-right:1px solid var(--border-subtle, rgba(255, 255, 255, .1));border-radius:var(--size-radius-sm, 6px) 0 0 var(--size-radius-sm, 6px)}.ds-number-field--stepper .ds-number-field__btn--plus{border-left:1px solid var(--border-subtle, rgba(255, 255, 255, .1));border-radius:0 var(--size-radius-sm, 6px) var(--size-radius-sm, 6px) 0}.ds-number-field--stepper .ds-number-field__value-area{padding:0 40px}.ds-number-field--disabled{pointer-events:none;opacity:var(--opacity-disabled, .6)}.ds-number-field--disabled .ds-number-field__container{background:transparent}.ds-number-field--dragging .ds-number-field__container{background:var(--color-purple-100, rgba(139, 92, 246, .08));border-color:var(--color-purple-500, #8b5cf6)}.ds-number-field--dragging .ds-number-field__progress-bar{background:var(--color-purple-500, #8b5cf6)}.search{position:relative;width:100%}.search__wrapper{position:relative;display:flex;align-items:center;gap:8px;padding:8px 12px;background:transparent;border:1px solid var(--border-base);border-radius:6px;transition:all .3s cubic-bezier(.4,0,.2,1);min-height:36px}.search--pill .search__wrapper{border-radius:9999px}.search--hovered:not(.search--disabled) .search__wrapper{border-color:var(--border-medium)}.search--focused:not(.search--disabled) .search__wrapper{border-color:var(--color-accent-500)}.search--focused:not(.search--disabled) .search__prefix .search__icon{color:var(--color-accent-500)}.search--expandable:not(.search--focused) .search__wrapper{width:200px;transition:width .3s cubic-bezier(.4,0,.2,1)}.search--expandable.search--focused .search__wrapper{width:100%}.search__prefix{display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--color-text-muted);transition:color .3s cubic-bezier(.4,0,.2,1)}.search__icon{display:block;transition:color .3s cubic-bezier(.4,0,.2,1)}.search__loading-icon{display:block;color:var(--color-accent-500);animation:search-spin .85s linear infinite;transform-origin:center;will-change:transform}.search__loading-track{opacity:.2}.search__loading-arc{opacity:1}.search__input{flex:1;border:none!important;outline:none!important;box-shadow:none!important;background:transparent;color:var(--color-text-primary);font-size:var(--font-size-sm);font-family:Noto Sans SC,PingFang SC,Microsoft YaHei,-apple-system,BlinkMacSystemFont,Segoe UI,SF Pro Display,Roboto,sans-serif;line-height:1.5;padding:0;min-width:0}.search__input::placeholder{color:var(--color-text-muted);transition:color .3s cubic-bezier(.4,0,.2,1)}.search__input:focus{border:none!important;outline:none!important;box-shadow:none!important}.search__input:focus::placeholder{color:var(--color-text-disabled)}.search__input:disabled{cursor:default;opacity:.5}.search__input:-webkit-autofill,.search__input:-webkit-autofill:hover,.search__input:-webkit-autofill:focus,.search__input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 30px transparent inset!important;-webkit-text-fill-color:var(--color-text-primary)!important;border:none!important;outline:none!important}.search__clear{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:transparent;color:var(--color-text-muted);cursor:pointer;transition:color .3s cubic-bezier(.4,0,.2,1);animation:search-fade-in .2s ease forwards}.search__clear:hover{color:var(--color-text-secondary)}.search__clear:active{color:var(--color-text-primary)}.search__suffix-content{display:flex;align-items:center;gap:8px;flex-shrink:0;margin-left:8px}.search__button{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:8px 16px;border:1px solid var(--color-accent-500);border-radius:6px;background:transparent;color:var(--color-accent-500);font-size:var(--font-size-sm);font-weight:500;font-family:Noto Sans SC,PingFang SC,Microsoft YaHei,-apple-system,BlinkMacSystemFont,Segoe UI,SF Pro Display,Roboto,sans-serif;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);white-space:nowrap}.search__button:hover:not(:disabled){background:#60a5fa14;color:var(--color-accent-400)}.search__button:active:not(:disabled){transform:scale(.98)}.search__button:disabled{opacity:.5;cursor:default}.search--disabled{opacity:.5;cursor:default}.search--disabled .search__wrapper{cursor:default}.search--error .search__wrapper{border-color:var(--color-error)}.search--error .search__prefix{color:var(--color-error)}.search__error-message{margin-top:8px;font-size:var(--font-size-xs);color:var(--color-error);display:flex;align-items:center;gap:4px;animation:search-slide-down .2s ease}.search--small .search__wrapper{padding:4px 8px;min-height:30px;gap:4px}.search--small .search__input{font-size:var(--font-size-xs)}.search--small .search__icon,.search--small .search__loading-icon{width:14px;height:14px}.search--small .search__clear{width:16px;height:16px}.search--small .search__clear svg{width:12px;height:12px}.search--small .search__button{padding:4px 8px;font-size:var(--font-size-xs)}.search--large .search__wrapper{padding:12px 16px;min-height:44px;gap:12px}.search--large .search__input{font-size:var(--font-size-base)}.search--large .search__icon,.search--large .search__loading-icon{width:20px;height:20px}.search--large .search__clear{width:22px;height:22px}.search--large .search__clear svg{width:16px;height:16px}.search--large .search__button{padding:8px 20px;font-size:var(--font-size-base)}.search--with-button .search__wrapper{padding-right:8px}@keyframes search-spin{to{transform:rotate(360deg)}}@keyframes search-fade-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes search-slide-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.ds-squeeze-segmented-control{align-items:stretch;background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-full, 999px);display:flex;gap:2px;min-width:0;padding:2px;width:100%}.ds-squeeze-segmented-control--disabled{opacity:.62}.ds-squeeze-segmented-control__option{align-items:center;background:transparent;border:1px solid transparent;border-radius:var(--ds-radius-full, 999px);box-sizing:border-box;color:var(--ds-color-text-secondary, var(--color-text-secondary));cursor:pointer;display:flex;flex:.34 1 0;font:inherit;font-size:var(--ds-font-size-xs, 12px);font-weight:var(--ds-font-weight-medium, 500);gap:0;height:32px;justify-content:center;line-height:1.2;min-width:46px;padding:0 var(--ds-space-2);transition:flex .26s var(--ds-easing-standard),background var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),border-color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),box-shadow var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),transform var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease);white-space:nowrap}.ds-squeeze-segmented-control__option:hover:not(:disabled){background:var(--ds-color-element-soft, var(--element-bg-soft));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-squeeze-segmented-control__option:active:not(:disabled){transform:scale(.98)}.ds-squeeze-segmented-control__option:focus-visible{outline:2px solid var(--ds-focus-ring, var(--color-accent-400));outline-offset:2px}.ds-squeeze-segmented-control__option:disabled{cursor:not-allowed;opacity:.56}.ds-squeeze-segmented-control__option--selected{--ds-squeeze-selected-accent: var(--ds-switch-on-bg, var(--btn-primary-bg, var(--ds-color-accent-500, var(--color-accent-500))));background:transparent;border-color:var(--ds-squeeze-selected-accent);box-shadow:none;color:var(--ds-color-text-primary, var(--color-text-primary));flex:2.45 1 0;justify-content:flex-start}.ds-squeeze-segmented-control__option--selected:hover:not(:disabled){background:transparent;border-color:var(--ds-switch-on-hover-bg, var(--btn-primary-hover-bg, var(--ds-squeeze-selected-accent)));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-squeeze-segmented-control__option--with-trailing{flex:2.75 1 0;padding-right:var(--ds-space-2)}.ds-squeeze-segmented-control__content{align-items:center;display:inline-flex;flex:1 1 auto;min-width:0;overflow:hidden}.ds-squeeze-segmented-control__label{flex:0 0 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}.ds-squeeze-segmented-control__detail{border-left:1px solid color-mix(in srgb,var(--ds-squeeze-selected-accent, var(--ds-color-accent-500, var(--color-accent-500))) 28%,transparent);color:var(--ds-color-text-secondary, var(--color-text-secondary));flex:1 1 auto;font-weight:var(--ds-font-weight-normal, 400);margin-left:var(--ds-space-1);min-width:0;overflow:hidden;padding-left:var(--ds-space-2);text-align:center;text-overflow:ellipsis;white-space:nowrap}.ds-squeeze-segmented-control__trailing{align-items:center;color:color-mix(in srgb,var(--ds-squeeze-selected-accent, var(--ds-color-accent-500, var(--color-accent-500))) 80%,var(--ds-color-text-secondary, var(--color-text-secondary)));display:inline-flex;flex:0 0 auto;margin-left:auto}.ds-squeeze-segmented-control--medium .ds-squeeze-segmented-control__option{font-size:var(--ds-font-size-sm, 13px);height:36px;min-width:54px}@container config-panel (max-width: 520px){.ds-squeeze-segmented-control__option{flex:.42 1 0}.ds-squeeze-segmented-control__option--selected{flex:2.1 1 0}.ds-squeeze-segmented-control__option--with-trailing{flex:2.35 1 0}}.ds-skeleton{background:linear-gradient(90deg,var(--ds-color-element-subtle, var(--element-bg-subtle)) 0%,var(--ds-color-element-soft, var(--element-bg-soft)) 45%,var(--ds-color-element-subtle, var(--element-bg-subtle)) 100%);background-size:220% 100%;border-radius:var(--ds-radius-sm, 6px);display:inline-block;max-width:100%;min-width:0}.ds-skeleton--text{height:.8em;width:100%}.ds-skeleton--block{height:64px;width:100%}.ds-skeleton--circle{aspect-ratio:1;border-radius:var(--ds-radius-full, 999px);height:32px;width:32px}.ds-skeleton--animated{animation:ds-skeleton-shimmer var(--ds-motion-slow, 1.4s) var(--ds-easing-standard, ease) infinite}.ds-loading-skeleton{align-items:flex-start;display:flex;gap:var(--ds-space-3, 12px);min-width:0;width:100%}.ds-loading-skeleton--compact{gap:var(--ds-space-2, 8px)}.ds-loading-skeleton__avatar{flex:0 0 auto}.ds-loading-skeleton__content{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--ds-space-2, 8px);min-width:0}.ds-loading-skeleton__line{width:var(--ds-skeleton-line-scale, 100%)}@keyframes ds-skeleton-shimmer{0%{background-position:120% 0}to{background-position:-120% 0}}.stream-text{display:inline;font-family:var(--font-family-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);line-height:1.6;position:relative}.stream-text__content{display:inline;color:var(--color-text-primary)}.stream-text__char{display:inline-block;position:relative;color:var(--color-text-primary)}.stream-text__char--new{animation:char-appear .3s ease-out}@keyframes char-appear{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.stream-text--smooth .stream-text__char--smooth{animation:smooth-appear .2s ease-out}@keyframes smooth-appear{0%{opacity:0}to{opacity:1}}.stream-text--typewriter .stream-text__char--typewriter{animation:typewriter-appear .1s steps(1)}@keyframes typewriter-appear{0%{opacity:0}to{opacity:1}}.stream-text--wave .stream-text__char--wave{animation:wave-appear .6s ease-in-out;transform-origin:bottom}@keyframes wave-appear{0%{opacity:0;transform:translateY(20px) scale(.8)}50%{transform:translateY(-8px) scale(1.05)}to{opacity:1;transform:translateY(0) scale(1)}}.stream-text--fade .stream-text__char--fade{animation:fade-appear .8s ease-in-out}@keyframes fade-appear{0%{opacity:0;filter:blur(10px)}to{opacity:1;filter:blur(0)}}.stream-text--glitch .stream-text__char--glitch{animation:glitch-appear .4s ease-out}.stream-text--glitch .stream-text__char--new{animation:glitch-flash .3s ease-out}@keyframes glitch-appear{0%{opacity:0;transform:translate(calc(var(--char-index, 0) * -2px));text-shadow:2px 0 #ff00ff,-2px 0 #00ffff}20%{transform:translate(calc(var(--char-index, 0) * 2px),-2px)}40%{transform:translate(calc(var(--char-index, 0) * -1px),2px)}60%{text-shadow:1px 0 #ff00ff,-1px 0 #00ffff}to{opacity:1;transform:translate(0);text-shadow:none}}@keyframes glitch-flash{0%,to{opacity:1}20%,60%{opacity:.8;text-shadow:1px 0 #ff00ff,-1px 0 #00ffff}}.stream-text--neon{text-shadow:0 0 5px currentColor,0 0 10px currentColor,0 0 20px currentColor}.stream-text--neon .stream-text__char--neon{animation:neon-appear .5s ease-out}@keyframes neon-appear{0%{opacity:0;text-shadow:0 0 40px currentColor,0 0 80px currentColor}50%{text-shadow:0 0 30px currentColor,0 0 60px currentColor,0 0 100px currentColor}to{opacity:1;text-shadow:0 0 5px currentColor,0 0 10px currentColor,0 0 20px currentColor}}.stream-text--matrix{color:#0f0;font-family:Courier New,monospace;text-shadow:0 0 5px #0f0}.stream-text--matrix .stream-text__char--matrix{animation:matrix-appear .4s ease-out}@keyframes matrix-appear{0%{opacity:0;transform:translateY(-20px);color:#fff;text-shadow:0 0 20px #0f0}50%{opacity:1;color:#0f0;text-shadow:0 0 10px #0f0,0 0 20px #0f0}to{opacity:1;transform:translateY(0);color:#0f0;text-shadow:0 0 5px #0f0}}.stream-text--gradient{background:linear-gradient(90deg,#ff0080,#ff8c00,#40e0d0,#00bfff,#9370db,#ff1493);background-size:200% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-flow 3s linear infinite}.stream-text--gradient .stream-text__char--gradient{animation:gradient-appear .6s ease-out}@keyframes gradient-appear{0%{opacity:0;filter:brightness(2) blur(4px)}to{opacity:1;filter:brightness(1) blur(0)}}@keyframes gradient-flow{0%{background-position:0% center}to{background-position:200% center}}.stream-text--pulse .stream-text__char--pulse{animation:pulse-appear .8s ease-out}@keyframes pulse-appear{0%{opacity:0;transform:scale(.5)}50%{opacity:1;transform:scale(1.2)}to{opacity:1;transform:scale(1)}}.stream-text--blur .stream-text__char--blur{animation:blur-appear .8s ease-out}@keyframes blur-appear{0%{opacity:0;filter:blur(20px)}to{opacity:1;filter:blur(0)}}.stream-text--bounce .stream-text__char--bounce{animation:bounce-appear .6s cubic-bezier(.68,-.55,.265,1.55)}@keyframes bounce-appear{0%{opacity:0;transform:translateY(-50px) scale(.5)}50%{transform:translateY(10px) scale(1.1)}70%{transform:translateY(-5px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.stream-text--shimmer{position:relative}.stream-text--shimmer .stream-text__char--shimmer{animation:shimmer-appear 1s ease-out}@keyframes shimmer-appear{0%{opacity:0}20%{opacity:1;filter:brightness(2);text-shadow:0 0 8px rgba(255,255,255,.8)}to{opacity:1;filter:brightness(1);text-shadow:none}}.stream-cursor{display:inline-block;margin-left:2px;vertical-align:text-bottom}.stream-cursor--line{width:2px;height:1em;background:#3b82f6cc;animation:cursor-blink 1s step-end infinite}.stream-cursor--line.stream-cursor--active{animation:cursor-pulse .8s ease-in-out infinite}.stream-cursor--block{width:.6em;height:1em;background:#3b82f699;animation:cursor-blink 1s step-end infinite}.stream-cursor--underline{width:.6em;height:2px;background:#3b82f6cc;animation:cursor-blink 1s step-end infinite}.stream-cursor--glow{width:2px;height:1em;background:#3b82f6;box-shadow:0 0 10px #3b82f6cc,0 0 20px #3b82f699,0 0 30px #3b82f666;animation:cursor-glow 1s ease-in-out infinite}@keyframes cursor-glow{0%,to{opacity:1;box-shadow:0 0 10px #3b82f6cc,0 0 20px #3b82f699}50%{opacity:.7;box-shadow:0 0 20px #3b82f6,0 0 40px #3b82f6cc,0 0 60px #3b82f699}}.stream-cursor--rainbow{width:2px;height:1em;background:linear-gradient(180deg,#ff0080,#ff8c00,#40e0d0,#00bfff,#9370db);animation:cursor-rainbow 2s linear infinite}@keyframes cursor-rainbow{0%,to{filter:hue-rotate(0deg)}50%{filter:hue-rotate(180deg)}}@keyframes cursor-blink{0%,50%{opacity:1}50.1%,to{opacity:0}}@keyframes cursor-pulse{0%,to{opacity:1;transform:scaleY(1)}50%{opacity:.5;transform:scaleY(.8)}}.stream-text--theme-blue{color:#3b82f6}.stream-text--theme-blue.stream-text--neon{color:#60a5fa}.stream-text--theme-purple{color:#a855f7}.stream-text--theme-purple.stream-text--neon{color:#c084fc}.stream-text--theme-green{color:var(--ds-color-success-base)}.stream-text--theme-green.stream-text--neon{color:#34d399}.stream-text--theme-rainbow{background:linear-gradient(90deg,#ff0080,#ff8c00,#40e0d0,#00bfff,#9370db,#ff1493);background-size:200% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-flow 3s linear infinite}.stream-text--theme-fire{background:linear-gradient(90deg,red,#f80,#fd0,#f80,red);background-size:200% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-flow 2s linear infinite}.stream-text--theme-ocean{background:linear-gradient(90deg,#0077be,#00b4d8,#48cae4,#00b4d8,#0077be);background-size:200% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-flow 3s linear infinite}.stream-text--theme-sunset{background:linear-gradient(90deg,#ff6b6b,#ffd93d,#ff9ff3,#ffd93d,#ff6b6b);background-size:200% auto;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-flow 2.5s linear infinite}@media(max-width:768px){.stream-text{font-size:.95em}.stream-cursor{width:1.5px}.stream-text--glitch .stream-text__char--glitch,.stream-text--matrix .stream-text__char--matrix,.stream-text--bounce .stream-text__char--bounce{animation-duration:.3s}}@media(prefers-reduced-motion:reduce){.stream-cursor,.stream-text__char,.stream-text__char--new,.stream-text{animation:none!important}.stream-cursor{opacity:1}.stream-text--gradient,.stream-text--theme-rainbow,.stream-text--theme-fire,.stream-text--theme-ocean,.stream-text--theme-sunset{animation:none;background-position:0% center}.stream-text--neon,.stream-text--matrix,.stream-text__char{text-shadow:none!important;filter:none!important}}@media(prefers-contrast:high){.stream-text{filter:none!important}.stream-text--gradient,.stream-text--theme-rainbow,.stream-text--theme-fire,.stream-text--theme-ocean,.stream-text--theme-sunset{background:none;-webkit-text-fill-color:currentColor;color:inherit}.stream-cursor{background:currentColor;opacity:1}}@media print{.stream-text__char,.stream-text{animation:none!important;opacity:1!important}.stream-cursor{display:none}}.ds-tabs{display:flex;flex-direction:column;width:100%}.ds-tabs__nav{position:relative;display:flex;align-items:center;flex-shrink:0}.ds-tabs__nav-list{display:flex;gap:4px;flex:1}.ds-tabs__tab{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 12px;font-size:var(--font-size-sm);font-weight:500;color:var(--color-text-secondary);cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);-webkit-user-select:none;user-select:none;position:relative;background:transparent;border:none;white-space:nowrap}.ds-tabs__tab:hover:not(.ds-tabs__tab--disabled):not(.ds-tabs__tab--active){color:var(--color-text-primary);background:#ffffff0d}.ds-tabs__tab--active{color:var(--color-accent-500)}.ds-tabs__tab--disabled{opacity:.6;cursor:default}.ds-tabs__tab-icon{display:flex;align-items:center;flex-shrink:0}.ds-tabs__tab-icon svg{width:16px;height:16px}.ds-tabs__tab-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ds-tabs__tab-close{display:flex;align-items:center;justify-content:center;width:16px;height:16px;margin-left:4px;border-radius:3px;font-size:18px;line-height:1;transition:all .2s;opacity:1}.ds-tabs__tab-close:hover{background:#ef444433;color:#ef4444}.ds-tabs__content{width:100%}.ds-tabs--stretch .ds-tabs__tab{flex:1}.ds-tabs--line .ds-tabs__nav{border-bottom:1px solid var(--border-base)}.ds-tabs--line .ds-tabs__tab{border-bottom:2px solid transparent;margin-bottom:-1px;border-radius:0}.ds-tabs--line .ds-tabs__tab--active{color:var(--color-accent-500);border-bottom-color:var(--color-accent-500)}.ds-tabs--line .ds-tabs__tab .ds-tabs__tab-close{opacity:0;width:0;margin-left:0;overflow:hidden}.ds-tabs--line .ds-tabs__tab:hover .ds-tabs__tab-close{opacity:1;width:16px;margin-left:4px}.ds-tabs--card .ds-tabs__nav{background:linear-gradient(135deg,#ffffff18,#ffffff12);border:1px solid var(--border-base);border-radius:8px;padding:4px;backdrop-filter:blur(8px) saturate(1.1);-webkit-backdrop-filter:blur(8px) saturate(1.1)}.ds-tabs--card .ds-tabs__tab{border-radius:6px}.ds-tabs--card .ds-tabs__tab--active{background:linear-gradient(135deg,#ffffff14,#ffffff0f,#ffffff1a);border:1px solid rgba(255,255,255,.08);color:#e5e5e5;backdrop-filter:blur(8px) saturate(1.1);-webkit-backdrop-filter:blur(8px) saturate(1.1);box-shadow:0 2px 4px #0000001a,inset 0 1px #ffffff14;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;color:#e8e8e8}.ds-tabs--card .ds-tabs__tab:hover:not(.ds-tabs--card .ds-tabs__tab--disabled):not(.ds-tabs--card .ds-tabs__tab--active){background:#ffffff20}.ds-tabs--pill .ds-tabs__tab{border-radius:20px;padding:6px 16px}.ds-tabs--pill .ds-tabs__tab--active{background:linear-gradient(135deg,#60a5fae6,#3b82f6e6);color:#fff;box-shadow:0 4px 12px #60a5fa4d}.ds-tabs--small .ds-tabs__tab{padding:6px 12px;font-size:12px}.ds-tabs--large .ds-tabs__tab{padding:10px 20px;font-size:16px}.ds-tabs--variant-purple.ds-tabs--line .ds-tabs__nav{border-bottom-color:#8b5cf640}.ds-tabs--variant-purple.ds-tabs--line .ds-tabs__tab--active{color:#8b5cf6;border-bottom-color:#8b5cf6}.ds-tabs--variant-purple.ds-tabs--card .ds-tabs__tab--active{background:linear-gradient(135deg,#8b5cf626,#8b5cf640);box-shadow:0 2px 8px #8b5cf633}.ds-tabs--variant-purple.ds-tabs--pill .ds-tabs__tab--active{background:linear-gradient(135deg,#8b5cf6e6,#7c3aede6);box-shadow:0 4px 12px #8b5cf64d}.ds-tabs--variant-mixed.ds-tabs--line .ds-tabs__nav{border-bottom:1px solid transparent;background:linear-gradient(90deg,#60a5fa26,#8b5cf626)}.ds-tabs--variant-mixed.ds-tabs--line .ds-tabs__tab--active{background:linear-gradient(135deg,#60a5fa26,#8b5cf626);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;border-bottom-color:#8b5cf666}.ds-tabs--variant-mixed.ds-tabs--card .ds-tabs__tab--active{background:linear-gradient(135deg,#60a5fa26,#8b5cf626);box-shadow:0 2px 8px #60a5fa26,0 2px 8px #8b5cf626}.ds-tabs--variant-mixed.ds-tabs--pill .ds-tabs__tab--active{background:linear-gradient(135deg,#3b82f6,#7c3aed);box-shadow:0 4px 12px #60a5fa33,0 4px 12px #8b5cf633}.ds-tab-pane{width:100%}.tag{display:inline-flex;align-items:center;gap:8px;padding:4px 12px;border-radius:6px;font-weight:500;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative}.tag--small{font-size:var(--font-size-xs);padding:2px 8px;gap:4px}.tag--medium{font-size:var(--font-size-xs);padding:4px 12px}.tag--large{font-size:var(--font-size-sm);padding:8px 16px}.tag--blue{background:var(--color-accent-200);color:var(--color-text-secondary)}.tag--blue:hover{background:var(--color-accent-300)}.tag--green{background:#34d39924;color:#6eb88c}.tag--green:hover{background:#34d39933}.tag--red{background:#ef444424;color:#c77070}.tag--red:hover{background:#ef444433}.tag--yellow{background:#f59e0b24;color:#c9944d}.tag--yellow:hover{background:#f59e0b33}.tag--purple{background:#8b5cf624;color:#8b5cf6}.tag--purple:hover{background:#8b5cf633}.tag--gray{background:#ffffff20;color:#e5e5e5}.tag--gray:hover{background:#ffffff28;color:#e8e8e8}.tag--rounded{border-radius:9999px}.tag__content{line-height:1}.tag__close{display:flex;align-items:center;justify-content:center;width:14px;height:14px;padding:0;background:transparent;border:none;border-radius:50%;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.tag__close:hover{background:#00000026}.tag__close svg{width:10px;height:10px}.ds-pagination{align-items:center;display:inline-flex;gap:var(--ds-space-2, 8px);min-width:0}.ds-pagination__pages{align-items:center;display:inline-flex;gap:var(--ds-space-1, 4px);min-width:0}.ds-pagination__button{align-items:center;background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-sm, 6px);color:var(--ds-color-text-secondary, var(--color-text-secondary));cursor:pointer;display:inline-flex;font:inherit;font-size:var(--ds-font-size-xs, 12px);font-weight:var(--ds-font-weight-medium, 500);height:28px;justify-content:center;min-width:28px;padding:0 var(--ds-space-2, 8px);transition:background var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),border-color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease)}.ds-pagination__button:hover:not(:disabled){background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:var(--ds-color-border-base, var(--border-base));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-pagination__button:focus-visible{outline:2px solid var(--ds-focus-ring, var(--color-accent-400));outline-offset:2px}.ds-pagination__button:disabled{cursor:not-allowed;opacity:.56}.ds-pagination__button--current{background:color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 14%,transparent);border-color:var(--ds-color-accent-300, var(--color-accent-300));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-pagination__button--icon{padding:0;width:28px}.ds-pagination__gap,.ds-pagination__summary{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-xs, 12px);white-space:nowrap}.ds-pagination__gap{padding:0 var(--ds-space-1, 4px)}.ds-pagination--compact .ds-pagination__summary{min-width:52px;text-align:center}.ds-pagination--loading{opacity:.72}.ds-status-dot{--ds-status-color: var(--ds-color-text-muted, var(--color-text-muted));background:var(--ds-status-color);border-radius:var(--ds-radius-full, 999px);box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-status-color) 24%,transparent);display:inline-block;flex:0 0 auto;height:8px;width:8px}.ds-status-dot--small{height:6px;width:6px}.ds-status-dot--medium{height:8px;width:8px}.ds-status-dot--neutral{--ds-status-color: var(--ds-color-text-muted, var(--color-text-muted))}.ds-status-dot--info{--ds-status-color: var(--ds-color-info, var(--color-info))}.ds-status-dot--success{--ds-status-color: var(--ds-color-success, var(--color-success))}.ds-status-dot--warning{--ds-status-color: var(--ds-color-warning, var(--color-warning))}.ds-status-dot--error{--ds-status-color: var(--ds-color-error, var(--color-error))}.ds-status-dot--accent{--ds-status-color: var(--ds-color-accent-500, var(--color-accent-500))}.ds-status-dot--pulse{animation:ds-status-dot-pulse var(--ds-motion-slow, 1.4s) var(--ds-easing-standard, ease) infinite}.ds-status-pill{--ds-status-pill-bg: var(--ds-color-element-subtle, var(--element-bg-subtle));--ds-status-pill-text: var(--ds-color-text-secondary, var(--color-text-secondary));align-items:center;background:var(--ds-status-pill-bg);border:1px solid color-mix(in srgb,var(--ds-status-pill-text) 20%,transparent);border-radius:var(--ds-radius-full, 999px);color:var(--ds-status-pill-text);display:inline-flex;font-size:var(--ds-font-size-xs, 12px);font-weight:var(--ds-font-weight-medium, 500);gap:var(--ds-space-2, 8px);line-height:1;max-width:100%;min-width:0;padding:5px var(--ds-space-2, 8px);vertical-align:middle}.ds-status-pill--small{font-size:var(--ds-font-size-2xs, 11px);padding:4px var(--ds-space-2, 8px)}.ds-status-pill--neutral{--ds-status-pill-bg: var(--ds-color-element-subtle, var(--element-bg-subtle));--ds-status-pill-text: var(--ds-color-text-secondary, var(--color-text-secondary))}.ds-status-pill--info{--ds-status-pill-bg: var(--ds-color-info-bg, var(--color-info-bg));--ds-status-pill-text: var(--ds-color-info, var(--color-info))}.ds-status-pill--success{--ds-status-pill-bg: var(--ds-color-success-bg, var(--color-success-bg));--ds-status-pill-text: var(--ds-color-success, var(--color-success))}.ds-status-pill--warning{--ds-status-pill-bg: var(--ds-color-warning-bg, var(--color-warning-bg));--ds-status-pill-text: var(--ds-color-warning, var(--color-warning))}.ds-status-pill--error{--ds-status-pill-bg: var(--ds-color-error-bg, var(--color-error-bg));--ds-status-pill-text: var(--ds-color-error, var(--color-error))}.ds-status-pill--accent{--ds-status-pill-bg: color-mix(in srgb, var(--ds-color-accent-500, var(--color-accent-500)) 12%, transparent);--ds-status-pill-text: var(--ds-color-accent-600, var(--color-accent-600))}.ds-status-pill__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes ds-status-dot-pulse{0%,to{box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-status-color) 24%,transparent)}50%{box-shadow:0 0 0 5px color-mix(in srgb,var(--ds-status-color) 12%,transparent)}}.window-controls{display:flex;align-items:center;gap:2px;flex-shrink:0}.window-controls__btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--size-radius-sm, 6px);color:var(--btn-ghost-color, #8a8a8a);cursor:pointer;transition:background .15s ease,border-color .15s ease,color .15s ease;position:relative;overflow:visible;outline:none;-webkit-user-select:none;user-select:none}.window-controls__btn svg{stroke:currentColor;fill:none;stroke-width:1.5;transition:all .3s cubic-bezier(.4,0,.2,1)}.window-controls__btn:hover:not(:disabled) svg{stroke-width:2.5}.window-controls__btn.is-active svg,.window-controls__btn[aria-current=true] svg,.window-controls__btn[data-active=true] svg{stroke-width:2.2}.window-controls__btn:after{display:none}.window-controls__btn svg{display:block;flex-shrink:0;position:relative;opacity:1;z-index:var(--ds-z-raised, 2)}.window-controls__btn:before{display:none}.window-controls__btn:hover{background:var(--btn-ghost-hover-bg, rgba(255, 255, 255, .06));color:var(--btn-ghost-hover-color, #b8b8b8);border-color:var(--btn-ghost-hover-border, transparent)}.window-controls__btn:active{opacity:.8}.window-controls__btn:focus-visible{outline:2px solid rgba(96,165,250,.4);outline-offset:2px}.window-controls__btn--minimize:hover{background:var(--btn-ghost-hover-bg, rgba(255, 255, 255, .06));color:var(--btn-ghost-hover-color, #b8b8b8);border-color:var(--btn-ghost-hover-border, transparent)}.window-controls__btn--minimize:focus-visible{outline-color:#60a5fa66}.window-controls__btn--maximize:hover{background:var(--btn-ghost-hover-bg, rgba(255, 255, 255, .06));color:var(--btn-ghost-hover-color, #b8b8b8);border-color:var(--btn-ghost-hover-border, transparent)}.window-controls__btn--maximize:focus-visible{outline-color:#60a5fa66}.window-controls__btn--close:hover{background:var(--btn-ghost-hover-bg, rgba(255, 255, 255, .06));color:var(--window-control-close-hover-color, #ef4444);border-color:var(--btn-ghost-hover-border, transparent)}.window-controls__btn--close:focus-visible{outline-color:var(--window-control-close-hover-color, #ef4444)}.window-controls__btn:disabled{opacity:var(--opacity-disabled, .5);cursor:default;pointer-events:none}.window-controls__btn:disabled:hover{background:transparent;color:var(--btn-ghost-color, #8a8a8a);border-color:transparent}@media(max-width:768px){.window-controls{gap:4px}.window-controls__btn{width:28px;height:28px;border-radius:var(--size-radius-sm, 6px)}.window-controls__btn svg{width:12px;height:12px}}@media(prefers-contrast:high){.window-controls__btn:hover{border-width:2px}}@media(prefers-reduced-motion:reduce){.window-controls__btn{transition:none}}.ds-action-list-row{align-items:center;background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-md, 8px);color:var(--ds-color-text-primary, var(--color-text-primary));display:flex;gap:var(--ds-space-3, 12px);min-height:48px;min-width:0;padding:var(--ds-space-3, 12px);transition:background var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),border-color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease);width:100%}.ds-action-list-row--single-line{border-radius:var(--ds-list-row-radius, var(--ds-radius-full, 999px))}.ds-action-list-row--selectable{cursor:pointer;font:inherit;text-align:left}.ds-action-list-row--selectable:hover:not(:disabled){background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:var(--ds-color-border-base, var(--border-base))}.ds-action-list-row--selectable:focus-visible{outline:2px solid var(--ds-focus-ring, var(--color-accent-400));outline-offset:2px}.ds-action-list-row--selected{background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:var(--ds-color-border-subtle, var(--border-subtle));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-action-list-row--disabled,.ds-action-list-row:disabled{cursor:not-allowed;opacity:.58}.ds-action-list-row--error{border-color:var(--ds-color-error, var(--color-error))}.ds-action-list-row--loading{opacity:.72}.ds-action-list-row__leading,.ds-action-list-row__selected-icon{align-items:center;color:var(--ds-color-text-muted, var(--color-text-muted));display:inline-flex;flex:0 0 auto;justify-content:center}.ds-action-list-row--selected .ds-action-list-row__selected-icon{color:var(--ds-color-accent-600, var(--color-accent-600))}.ds-action-list-row__content{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--ds-space-1, 4px);min-width:0}.ds-action-list-row__title{color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 13px);font-weight:var(--ds-font-weight-semibold, 600);line-height:1.35;overflow-wrap:anywhere}.ds-action-list-row__description,.ds-action-list-row__meta,.ds-action-list-row__error{font-size:var(--ds-font-size-xs, 12px);line-height:1.35}.ds-action-list-row__description,.ds-action-list-row__meta{color:var(--ds-color-text-muted, var(--color-text-muted))}.ds-action-list-row__meta{flex:0 1 auto;max-width:36%;min-width:0;overflow:hidden;text-align:right;text-overflow:ellipsis;white-space:nowrap}.ds-action-list-row__error{color:var(--ds-color-error, var(--color-error));overflow-wrap:anywhere}.ds-action-list-row__actions{align-items:center;display:inline-flex;flex:0 0 auto;gap:var(--ds-space-2, 8px)}@media(max-width:420px){.ds-action-list-row{align-items:flex-start;flex-wrap:wrap}.ds-action-list-row__meta{max-width:100%;text-align:left}.ds-action-list-row__actions{margin-left:calc(20px + var(--ds-space-3, 12px))}}.ds-app-window{background:var(--ds-color-bg-elevated, var(--color-bg-elevated, #18181a));border:1px solid var(--ds-color-border-base, var(--border-base, rgba(255, 255, 255, .14)));position:fixed;inset-block-start:50%;inset-inline-start:50%;z-index:var(--ds-z-dialog, var(--ds-z-modal, 240));display:flex;flex-direction:column;width:calc(100% - 48px);max-height:calc(100vh - 48px);overflow:hidden;color:var(--ds-color-text-secondary, var(--color-text-secondary));border-radius:var(--ds-radius-lg, 12px);box-shadow:0 -4px 12px -10px color-mix(in srgb,var(--ds-shadow-color-modal, rgba(0, 0, 0, .45)) 34%,transparent),var(--ds-shadow-modal, 0 16px 40px rgba(0, 0, 0, .45));transform:translate(-50%,-50%);animation:ds-app-window-enter .18s cubic-bezier(.16,1,.3,1)}.ds-app-window:focus{outline:none}.ds-app-window--large{max-width:760px}.ds-app-window--wide{max-width:900px}.ds-app-window--full{max-width:1120px}.ds-app-window__header-shell{position:relative;flex-shrink:0}.ds-app-window__header-shell--close-only{min-height:34px}.ds-app-window__header{display:flex;min-height:34px;align-items:center;justify-content:space-between;gap:var(--ds-space-2, 8px);padding:var(--ds-space-2, 8px) var(--ds-space-3, 12px);border-bottom:1px solid var(--ds-color-border-subtle, var(--border-subtle))}.ds-app-window--with-close .ds-app-window__header{padding-inline-end:calc(var(--ds-space-3, 12px) + 30px)}.ds-app-window__title-group{display:flex;min-width:0;flex:1;align-items:center;gap:var(--ds-space-2, 8px)}.ds-app-window__title{min-width:0;margin:0;overflow:hidden;color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 13px);font-weight:600;line-height:1.35;text-overflow:ellipsis;white-space:nowrap}.ds-app-window__title-extra{display:inline-flex;min-width:0;flex:1;align-items:center}.ds-app-window__close.icon-btn{position:absolute;inset-block-start:6px;inset-inline-end:var(--ds-space-2, 8px);z-index:var(--ds-z-local, 1);color:var(--ds-color-text-muted, var(--color-text-muted));background:transparent;border:1px solid transparent;box-shadow:none}.ds-app-window__close.icon-btn:hover:not(:disabled),.ds-app-window__close.icon-btn:focus-visible{color:var(--ds-color-text-primary, var(--color-text-primary));background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:transparent;box-shadow:none}.ds-app-window__body{min-height:0;overflow:auto;flex:1}.ds-app-window__body--inset{padding-inline:var(--ds-space-7, 28px)}.ds-app-window__footer{display:flex;flex-shrink:0;align-items:center;justify-content:flex-end;gap:var(--ds-space-2, 8px);padding:var(--ds-space-3, 12px);border-top:1px solid var(--ds-color-border-subtle, var(--border-subtle))}@keyframes ds-app-window-enter{0%{opacity:0;transform:translate(-50%,calc(-50% + 12px)) scale(.985)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@media(max-width:480px){.ds-app-window{width:calc(100% - 32px);max-height:calc(100vh - 32px)}.ds-app-window__title{font-size:var(--ds-font-size-md, 14px)}.ds-app-window__body--inset{padding-inline:var(--ds-space-4, 16px)}}@media(prefers-reduced-motion:reduce){.ds-app-window{animation:none}}.ds-data-list{display:flex;flex-direction:column;gap:var(--ds-space-2, 8px);min-width:0}.ds-data-list-item{background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-md, 8px);color:var(--ds-color-text-primary, var(--color-text-primary));min-width:0;padding:var(--ds-space-3, 12px);transition:background var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease),border-color var(--ds-motion-fast, .15s) var(--ds-easing-standard, ease)}.ds-data-list-item:hover{background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:var(--ds-color-border-base, var(--border-base))}.ds-data-list-item--interactive{cursor:pointer}.ds-data-list-item--interactive:focus-visible{outline:2px solid var(--ds-focus-ring, var(--color-accent-400));outline-offset:2px}.ds-data-list-item--selected{background:color-mix(in srgb,var(--ds-color-accent-500, var(--color-accent-500)) 12%,transparent);border-color:var(--ds-color-accent-300, var(--color-accent-300))}.ds-data-list-empty{align-items:center;color:var(--ds-color-text-muted, var(--color-text-muted));display:flex;justify-content:center;min-height:120px;padding:var(--ds-space-6, 24px);text-align:center}.ds-toolbar{align-items:center;display:flex;gap:var(--ds-space-3, 12px);justify-content:space-between;min-height:40px;min-width:0}.ds-toolbar--compact{gap:var(--ds-space-2, 8px);min-height:32px}.ds-toolbar-group{align-items:center;display:flex;flex-wrap:wrap;gap:var(--ds-space-2, 8px);min-width:0}.ds-toolbar-group--end{flex:0 0 auto;justify-content:flex-end;margin-left:auto}.ds-search-toolbar{flex-wrap:wrap}.ds-search-toolbar__query{flex:1 1 280px}.ds-search-toolbar__search{flex:1 1 220px;min-width:min(220px,100%)}.ds-filter-bar{align-items:center;display:flex;gap:var(--ds-space-2, 8px);min-width:0}.ds-filter-bar__label{color:var(--ds-color-text-muted, var(--color-text-muted));flex:0 0 auto;font-size:var(--ds-font-size-sm, 14px)}.ds-filter-bar__items{align-items:center;display:flex;flex:1 1 auto;flex-wrap:wrap;gap:var(--ds-space-2, 8px);min-width:0}.ds-filter-bar__actions{align-items:center;display:flex;flex:0 0 auto;gap:var(--ds-space-2, 8px)}.ds-command-bar{border-top:1px solid var(--ds-color-border-subtle, var(--border-subtle));padding-block:var(--ds-space-2, 8px)}.ds-command-bar__meta{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-sm, 14px)}.ds-status-bar{align-items:center;background:var(--ds-color-element-subtle, var(--element-bg-subtle));border:1px solid var(--ds-color-border-subtle, var(--border-subtle));border-radius:var(--ds-radius-md, 8px);color:var(--ds-color-text-secondary, var(--color-text-secondary));display:flex;gap:var(--ds-space-2, 8px);min-height:32px;min-width:0;padding:var(--ds-space-2, 8px) var(--ds-space-3, 12px)}.ds-status-bar__content{flex:1 1 auto;font-size:var(--ds-font-size-sm, 14px);min-width:0}.ds-status-bar__leading,.ds-status-bar__trailing{align-items:center;display:inline-flex;flex:0 0 auto}.ds-status-bar--info{border-color:var(--ds-color-info-border, var(--border-base))}.ds-status-bar--success{border-color:var(--ds-color-success-border, var(--border-base))}.ds-status-bar--warning{border-color:var(--ds-color-warning-border, var(--border-base))}.ds-status-bar--danger{border-color:var(--ds-color-danger-border, var(--border-base))}.ds-list-detail{display:grid;gap:var(--ds-space-4, 16px);grid-template-columns:minmax(220px,.8fr) minmax(0,1.2fr);min-height:0;min-width:0}.ds-list-detail--narrow{grid-template-columns:minmax(180px,.6fr) minmax(0,1.4fr)}.ds-list-detail--wide{grid-template-columns:minmax(280px,1fr) minmax(0,1fr)}.ds-list-detail__list,.ds-list-detail__detail{min-height:0;min-width:0}.ds-list-detail__label{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-xs, 12px);font-weight:var(--ds-font-weight-semibold, 600);margin-bottom:var(--ds-space-2, 8px)}@media(max-width:720px){.ds-list-detail{grid-template-columns:1fr}}.ds-panel{background:var(--ds-color-bg-panel, var(--color-bg-secondary, #18181a));border:1px solid var(--ds-color-border-subtle, var(--border-subtle, rgba(255, 255, 255, .1)));border-radius:var(--ds-radius-md, 8px);color:var(--ds-color-text-primary, var(--color-text-primary));display:flex;flex-direction:column;min-height:0}.ds-panel--elevated{background:var(--ds-color-bg-elevated, var(--color-bg-elevated, #18181a));border:1px solid var(--ds-color-border-base, var(--border-base, rgba(255, 255, 255, .14)));box-shadow:var(--ds-shadow-sm, var(--shadow-sm, none))}.ds-panel--subtle{background:transparent;border-color:transparent}.ds-panel-header,.ds-panel-footer{align-items:center;display:flex;gap:var(--ds-space-3, 12px);justify-content:space-between;padding:var(--ds-space-4, 16px)}.ds-panel-header{border-bottom:1px solid var(--ds-color-border-subtle, var(--border-subtle))}.ds-panel-header__copy{min-width:0}.ds-panel-header__title{color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-base, 15px);font-weight:var(--ds-font-weight-semibold, 600);margin:0}.ds-panel-header__description{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-sm, 14px);margin:var(--ds-space-1, 4px) 0 0}.ds-panel-header__actions{align-items:center;display:flex;flex:0 0 auto;gap:var(--ds-space-2, 8px)}.ds-panel-body{min-height:0;overflow:auto;flex:1 1 auto;padding:var(--ds-space-4, 16px)}.ds-panel-footer{border-top:1px solid var(--ds-color-border-subtle, var(--border-subtle))}.ds-inspector-panel{min-width:min(320px,100%)}.ds-inspector-panel__body{display:flex;flex-direction:column;gap:var(--ds-space-4, 16px)}.ds-inspector-panel__footer{border-top:1px solid var(--ds-color-border-subtle, var(--border-subtle));padding:var(--ds-space-3, 12px) var(--ds-space-4, 16px)}.confirm-dialog{display:flex;flex-direction:column;align-items:stretch;width:100%;max-width:100%;box-sizing:border-box;padding-top:16px}.confirm-dialog__icon{flex-shrink:0;width:40px;height:40px;margin:0 auto 8px;display:flex;align-items:center;justify-content:center;border-radius:50%}.confirm-dialog__icon svg{flex-shrink:0}.confirm-dialog--info .confirm-dialog__icon{background:color-mix(in srgb,var(--color-info) 15%,transparent);color:var(--color-info)}.confirm-dialog--warning .confirm-dialog__icon{background:color-mix(in srgb,var(--color-warning) 15%,transparent);color:var(--color-warning)}.confirm-dialog--error .confirm-dialog__icon{background:color-mix(in srgb,var(--color-error) 15%,transparent);color:var(--color-error)}.confirm-dialog--success .confirm-dialog__icon{background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.confirm-dialog__content{flex:1;min-width:0;margin:0;padding:0 20px 12px}.confirm-dialog__title{font-size:var(--font-size-base);font-weight:600;line-height:1.35;letter-spacing:0;color:var(--color-text-primary);margin:0 0 8px;text-align:center}.confirm-dialog__title--compact{margin-bottom:0}.confirm-dialog__message{font-size:var(--font-size-sm);line-height:1.55;color:var(--color-text-secondary);text-align:left}.confirm-dialog__message>*:first-child{margin-top:0}.confirm-dialog__message>*:last-child{margin-bottom:0}.confirm-dialog__message-intro{margin:0 0 12px;font-size:var(--font-size-sm);font-weight:500;line-height:1.5;color:var(--color-text-primary)}.confirm-dialog__bullet-list{list-style:none;margin:0;padding:12px 20px;border-radius:8px;background:var(--color-bg-subtle);border:1px solid var(--color-border)}.confirm-dialog__bullet-list li{position:relative;margin:0;padding-left:20px;font-size:var(--font-size-sm);line-height:1.55;color:var(--color-text-secondary)}.confirm-dialog__bullet-list li:before{content:"";position:absolute;left:2px;top:.55em;width:6px;height:6px;border-radius:50%;background:color-mix(in srgb,var(--color-text-secondary) 45%,transparent)}.confirm-dialog__bullet-list li+li{margin-top:8px}.confirm-dialog__preview{margin-top:12px;padding:12px 16px;background:var(--color-bg-subtle);border:1px solid var(--color-border);border-radius:8px;text-align:left;overflow:auto}.confirm-dialog__preview pre{margin:0;padding:0;font-family:Consolas,Monaco,Courier New,monospace;font-size:var(--font-size-xs);color:var(--color-text-primary);white-space:pre-wrap;word-break:break-all;line-height:1.5}.confirm-dialog__actions{display:flex;flex-direction:row;flex-wrap:nowrap;gap:8px;justify-content:stretch;align-items:stretch;padding:12px 20px 16px;border-top:1px solid var(--color-border)}.confirm-dialog__actions .btn{flex:1 1 0;min-width:0;width:auto}.ds-empty-state-panel__body{align-items:center;display:flex;justify-content:center;min-height:220px}.input-dialog{display:flex;flex-direction:column}.input-dialog__body{padding:20px 20px 16px}.input-dialog__description{margin:0 0 12px;color:var(--color-text-muted);font-size:12px;line-height:1.5}.input-dialog__actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:10px 20px 12px;border-top:1px solid var(--border-subtle)}.input-dialog__actions .btn{min-width:68px;border:1px solid var(--border-base)}.input-dialog__actions .btn-primary{border-color:#60a5fa66}.input-dialog-overlay{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.input-dialog-overlay .ds-dialog--small{max-width:360px}.ds-item-card{position:relative;display:flex;flex-direction:column;gap:0;min-width:0;background:var(--ds-color-bg-elevated);border:1px solid var(--ds-color-border-subtle);border-radius:var(--ds-radius-lg);color:var(--ds-color-text-primary);overflow:hidden;outline:none;transition:border-color var(--ds-motion-fast) var(--ds-easing-standard),box-shadow var(--ds-motion-fast) var(--ds-easing-standard),background var(--ds-motion-fast) var(--ds-easing-standard),transform var(--ds-motion-fast) var(--ds-easing-standard)}.ds-item-card--interactive{cursor:pointer}.ds-item-card--interactive:hover{border-color:var(--ds-color-border-medium);box-shadow:var(--ds-shadow-card)}.ds-item-card--interactive:hover .ds-item-card__actions{opacity:1}.ds-item-card:focus-visible{outline:2px solid var(--ds-color-border-focus);outline-offset:-1px}.ds-item-card.is-highlighted{border-color:var(--ds-color-border-medium);box-shadow:var(--ds-shadow-card)}.ds-item-card.is-highlighted .ds-item-card__actions{opacity:1}.ds-item-card--running{border-color:color-mix(in srgb,var(--ds-color-accent-500) 28%,var(--ds-color-border-subtle))}.ds-item-card--running.ds-item-card--interactive:hover{border-color:color-mix(in srgb,var(--ds-color-accent-500) 44%,var(--ds-color-border-subtle))}.ds-item-card--running .ds-item-card__top:before{content:"";position:absolute;inset:0;background:linear-gradient(170deg,color-mix(in srgb,var(--ds-color-accent-500) 7%,transparent) 0%,color-mix(in srgb,var(--ds-color-accent-500) 3%,transparent) 55%,transparent 100%);pointer-events:none;border-radius:inherit}.ds-item-card--active{border-color:color-mix(in srgb,var(--ds-color-success) 30%,transparent)}.ds-item-card--error{border-color:color-mix(in srgb,var(--ds-color-danger) 35%,transparent)}.ds-item-card__top{position:relative;display:flex;align-items:center;gap:var(--ds-space-2);min-height:0;padding:var(--ds-space-4) var(--ds-space-4) var(--ds-space-2)}.ds-item-card__title{flex:1;min-width:0;color:var(--ds-color-text-primary);font-size:var(--ds-font-size-sm);font-weight:var(--ds-font-weight-medium);line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ds-item-card__title>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ds-item-card__meta{display:flex;align-items:center;flex-wrap:wrap;gap:var(--ds-space-1);padding:var(--ds-space-3) var(--ds-space-4)}.ds-item-card__meta-separator{color:var(--ds-color-border-medium);font-size:10px;line-height:1}.ds-item-card__meta-item{display:inline-flex;align-items:center;gap:3px;color:var(--ds-color-text-muted);font-size:10px;min-width:0}.ds-item-card__actions{display:flex;align-items:center;justify-content:space-between;gap:var(--ds-space-2);padding:var(--ds-space-1) var(--ds-space-3) var(--ds-space-2);background:var(--ds-color-element-medium);opacity:.7;transition:opacity var(--ds-motion-fast) var(--ds-easing-standard)}.ds-item-card__actions--composing{cursor:default}.ds-navigation-list{display:flex;flex-direction:column;gap:var(--ds-space-1, 4px);min-width:0}.ds-navigation-list-item{align-items:center;background:transparent;border:1px solid transparent;border-radius:var(--ds-list-row-radius, var(--ds-radius-full, 999px));color:var(--ds-color-text-secondary, var(--color-text-secondary));cursor:pointer;display:flex;font:inherit;gap:var(--ds-space-2, 8px);min-height:34px;min-width:0;padding:var(--ds-space-2, 8px);text-align:left;width:100%}.ds-navigation-list-item:hover{background:var(--ds-color-element-subtle, var(--element-bg-subtle));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-navigation-list-item--active{background:var(--ds-color-element-soft, var(--element-bg-soft));border-color:var(--ds-color-border-subtle, var(--border-subtle));color:var(--ds-color-text-primary, var(--color-text-primary))}.ds-navigation-list--plain{gap:var(--ds-space-1, 4px)}.ds-navigation-list--plain .ds-navigation-list-item{border-color:transparent;font-size:var(--ds-font-size-sm, 13px);font-weight:var(--ds-font-weight-normal, 400);min-height:32px;padding:var(--ds-space-1, 4px) var(--ds-space-2, 8px)}.ds-navigation-list--plain .ds-navigation-list-item--active{background:transparent;border-color:transparent;color:var(--ds-color-text-primary, var(--color-text-primary));font-weight:var(--ds-font-weight-medium, 500)}.ds-navigation-list-item__icon,.ds-navigation-list-item__meta{align-items:center;display:inline-flex;flex:0 0 auto}.ds-navigation-list-item__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ds-detail-header{align-items:flex-start;display:flex;gap:var(--ds-space-4, 16px);justify-content:space-between;min-width:0}.ds-detail-header__copy{min-width:0}.ds-detail-header__eyebrow,.ds-detail-header__meta{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-xs, 12px)}.ds-detail-header__title{color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-xl, 20px);font-weight:var(--ds-font-weight-semibold, 600);letter-spacing:0;line-height:var(--ds-line-height-tight, 1.25);margin:0;overflow-wrap:anywhere}.ds-detail-header__subtitle{color:var(--ds-color-text-secondary, var(--color-text-secondary));font-size:var(--ds-font-size-sm, 14px);margin:var(--ds-space-1, 4px) 0 0}.ds-detail-header__actions{align-items:center;display:flex;flex:0 0 auto;gap:var(--ds-space-2, 8px)}@media(max-width:560px){.ds-detail-header{flex-direction:column}}.ds-form-section{container-name:ds-form-section;container-type:inline-size;display:flex;flex-direction:column;gap:var(--ds-space-4, 16px);min-width:0}.ds-form-field{display:grid;gap:var(--ds-space-2, 8px);grid-template-areas:"copy" "control" "error";min-width:0}.ds-form-field--control-compact{--ds-form-field-columns: minmax(0, 7fr) minmax(0, 3fr)}.ds-form-field--control-balanced{--ds-form-field-columns: minmax(0, 2fr) minmax(0, 3fr)}.ds-form-field--control-wide{--ds-form-field-columns: minmax(0, 1fr) minmax(0, 4fr)}.ds-form-field--horizontal{align-items:start;column-gap:var(--ds-space-4, 16px);grid-template-areas:"copy control" ". error";grid-template-columns:var(--ds-form-field-columns);row-gap:var(--ds-space-2, 8px)}.ds-form-field__copy{display:grid;gap:var(--ds-space-1, 4px);grid-area:copy;min-width:0}.ds-form-field__label{color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-sm, 14px);font-weight:var(--ds-font-weight-medium, 500)}.ds-form-field__required,.ds-form-field__error{color:var(--ds-color-danger, var(--color-error))}.ds-form-field__description{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-xs, 12px);line-height:var(--ds-line-height-base, 1.5)}.ds-form-field__control{grid-area:control;min-width:0}.ds-form-field__error{font-size:var(--ds-font-size-xs, 12px);grid-area:error}@container ds-form-section (max-width: 520px){.ds-form-field--horizontal{grid-template-areas:"copy" "control" "error";grid-template-columns:minmax(0,1fr)}}.ds-form-actions{align-items:center;display:flex;gap:var(--ds-space-2, 8px);justify-content:flex-end}.ds-scene{background:var(--ds-color-bg-scene, var(--color-bg-scene, #16161a));color:var(--ds-color-text-primary, var(--color-text-primary));display:flex;flex-direction:column;gap:var(--ds-space-5, 20px);min-height:0;width:100%;height:100%;padding:var(--ds-space-5, 20px)}.ds-scene--compact{gap:var(--ds-space-3, 12px);padding:var(--ds-space-3, 12px)}.ds-scene--comfortable{gap:var(--ds-space-6, 24px);padding:var(--ds-space-6, 24px)}.ds-scene-header{align-items:flex-start;display:flex;gap:var(--ds-space-4, 16px);justify-content:space-between;min-width:0}.ds-scene-header__copy{min-width:0}.ds-scene-header__eyebrow{color:var(--ds-color-text-muted, var(--color-text-muted));font-size:var(--ds-font-size-xs, 12px);font-weight:var(--ds-font-weight-medium, 500);margin-bottom:var(--ds-space-1, 4px)}.ds-scene-header__title{color:var(--ds-color-text-primary, var(--color-text-primary));font-size:var(--ds-font-size-xl, 20px);font-weight:var(--ds-font-weight-semibold, 600);line-height:var(--ds-line-height-tight, 1.2);margin:0}.ds-scene-header__description{color:var(--ds-color-text-secondary, var(--color-text-secondary));font-size:var(--ds-font-size-sm, 14px);line-height:var(--ds-line-height-base, 1.5);margin:var(--ds-space-2, 8px) 0 0;max-width:720px}.ds-scene-header__actions{align-items:center;display:flex;flex:0 0 auto;gap:var(--ds-space-2, 8px)}.ds-scene-body{min-height:0;overflow:auto;display:flex;flex:1 1 auto;flex-direction:column;gap:var(--ds-space-4, 16px)}.ds-scene-rail{background:var(--ds-color-bg-panel, var(--color-bg-secondary, #18181a));border:1px solid var(--ds-color-border-subtle, var(--border-subtle, rgba(255, 255, 255, .1)));border-radius:var(--ds-radius-md, 8px);min-width:220px;padding:var(--ds-space-3, 12px)}.ds-settings-page{--ds-settings-page-max-width: 44rem;align-content:start;display:grid;gap:var(--ds-space-4, 16px);margin-inline:auto;max-width:var(--ds-settings-page-max-width);min-width:0;width:100%}.ds-settings-page--width-narrow{--ds-settings-page-max-width: 34rem}.ds-settings-page--width-wide{--ds-settings-page-max-width: 60rem}.ds-settings-page--width-full{--ds-settings-page-max-width: none}.ds-settings-section{width:100%}.ds-tool-card{background:var(--tool-card-bg-primary, var(--ds-color-element-base, var(--element-bg-base)));border:1px solid var(--tool-card-border, var(--ds-color-border-base, var(--border-base)));border-radius:var(--ds-radius-md, 8px);color:var(--tool-card-text-primary, var(--ds-color-text-primary, var(--color-text-primary)));display:flex;flex-direction:column;min-width:0;overflow:hidden}.ds-tool-card--info{border-color:var(--ds-color-info-border, var(--color-info-border))}.ds-tool-card--success{border-color:var(--ds-color-success-border, var(--color-success-border))}.ds-tool-card--warning{border-color:var(--ds-color-warning-border, var(--color-warning-border))}.ds-tool-card--danger,.ds-tool-card--error{border-color:var(--ds-color-danger-border, var(--color-error-border))}.ds-tool-card--ai{border-color:var(--ds-color-purple-300, var(--color-purple-300))}.ds-tool-card-header,.ds-tool-card-footer{align-items:center;display:flex;gap:var(--ds-space-2, 8px);padding:var(--ds-space-3, 12px)}.ds-tool-card-header{border-bottom:1px solid var(--tool-card-border-subtle, var(--ds-color-border-subtle, var(--border-subtle)))}.ds-tool-card-header__icon{color:var(--ds-color-accent-500, var(--color-accent-500));display:inline-flex;flex:0 0 auto}.ds-tool-card-header__copy{min-width:0}.ds-tool-card-header__title{font-size:var(--ds-font-size-sm, 14px);font-weight:var(--ds-font-weight-semibold, 600)}.ds-tool-card-header__meta{color:var(--tool-card-text-muted, var(--ds-color-text-muted, var(--color-text-muted)));font-size:var(--ds-font-size-xs, 12px);margin-top:var(--ds-space-1, 4px)}.ds-tool-card-header__actions{margin-left:auto}.ds-tool-card-body{min-width:0;padding:var(--ds-space-3, 12px)}.ds-tool-card-footer{border-top:1px solid var(--tool-card-border-subtle, var(--ds-color-border-subtle, var(--border-subtle)));justify-content:flex-end}.language-selector{position:relative;display:inline-flex;align-items:center}.language-selector--dropdown .language-selector__select{appearance:none;background:var(--ds-color-element-base);border:1px solid var(--ds-color-border-base);border-radius:var(--ds-radius-sm);padding:6px 28px 6px 10px;font-size:var(--ds-font-size-sm);color:var(--ds-color-text-primary);cursor:pointer;transition:background-color var(--ds-motion-base) var(--ds-easing-standard),border-color var(--ds-motion-base) var(--ds-easing-standard),box-shadow var(--ds-motion-base) var(--ds-easing-standard);background-image:linear-gradient(45deg,transparent 50%,var(--ds-color-text-muted) 50%),linear-gradient(135deg,var(--ds-color-text-muted) 50%,transparent 50%);background-repeat:no-repeat;background-position:calc(100% - 14px) center,calc(100% - 9px) center;background-size:5px 5px,5px 5px}.language-selector--dropdown .language-selector__select:hover:not(:disabled){border-color:var(--ds-color-border-medium);background-color:var(--ds-color-element-subtle)}.language-selector--dropdown .language-selector__select:focus{outline:none;border-color:var(--ds-color-border-focus);box-shadow:0 0 0 2px color-mix(in srgb,var(--ds-color-border-focus) 24%,transparent)}.language-selector--dropdown .language-selector__select:disabled{opacity:.6;cursor:not-allowed}.language-selector--dropdown .language-selector__loading{margin-left:8px;color:var(--ds-color-text-muted);font-size:var(--ds-font-size-xs)}.language-selector--inline{gap:4px}.language-selector--inline .language-selector__inline-button{padding:4px 10px;border:1px solid transparent;border-radius:var(--ds-radius-sm);background:transparent;color:var(--ds-color-text-secondary);font-size:var(--ds-font-size-sm);cursor:pointer;transition:background var(--ds-motion-base) var(--ds-easing-standard),border-color var(--ds-motion-base) var(--ds-easing-standard),color var(--ds-motion-base) var(--ds-easing-standard)}.language-selector--inline .language-selector__inline-button:hover:not(:disabled){background:var(--ds-color-element-subtle);color:var(--ds-color-text-primary)}.language-selector--inline .language-selector__inline-button--active{background:var(--ds-color-element-medium);color:var(--ds-color-accent-500);border-color:var(--ds-color-accent-200)}.language-selector--inline .language-selector__inline-button--active:hover:not(:disabled){background:var(--ds-color-element-medium)}.language-selector--inline .language-selector__inline-button:disabled{opacity:.6;cursor:not-allowed}.language-selector--icon-only .language-selector__button{display:flex;align-items:center;gap:4px;padding:6px 10px;border:1px solid transparent;border-radius:var(--ds-radius-sm);background:transparent;color:var(--ds-color-text-secondary);font-size:var(--ds-font-size-sm);cursor:pointer;transition:background var(--ds-motion-base) var(--ds-easing-standard),color var(--ds-motion-base) var(--ds-easing-standard)}.language-selector--icon-only .language-selector__button:hover:not(:disabled){background:var(--ds-color-element-subtle);color:var(--ds-color-text-primary)}.language-selector--icon-only .language-selector__button:disabled{opacity:.6;cursor:not-allowed}.language-selector--icon-only .language-selector__icon{font-size:var(--ds-font-size-base)}.language-selector--icon-only .language-selector__code{font-size:var(--ds-font-size-xs);font-weight:var(--ds-font-weight-medium)}.language-selector--icon-only .language-selector__dropdown{position:absolute;top:100%;right:0;margin-top:4px;min-width:150px;padding:4px;background:var(--ds-color-bg-elevated);border:1px solid var(--ds-color-border-base);border-radius:var(--ds-radius-md);box-shadow:var(--ds-shadow-popover);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity var(--ds-motion-base) var(--ds-easing-standard),transform var(--ds-motion-base) var(--ds-easing-standard),visibility var(--ds-motion-base) var(--ds-easing-standard);z-index:var(--ds-z-dropdown)}.language-selector--icon-only:hover .language-selector__dropdown,.language-selector--icon-only:focus-within .language-selector__dropdown{opacity:1;visibility:visible;transform:translateY(0)}.language-selector--icon-only .language-selector__option{display:flex;align-items:center;justify-content:space-between;width:100%;padding:8px 12px;border:none;border-radius:var(--ds-radius-sm);background:transparent;color:var(--ds-color-text-secondary);font-size:var(--ds-font-size-sm);text-align:left;cursor:pointer;transition:background var(--ds-motion-fast) var(--ds-easing-standard),color var(--ds-motion-fast) var(--ds-easing-standard)}.language-selector--icon-only .language-selector__option:hover:not(:disabled){background:var(--ds-color-element-subtle);color:var(--ds-color-text-primary)}.language-selector--icon-only .language-selector__option--active{color:var(--ds-color-accent-500);font-weight:var(--ds-font-weight-medium)}.language-selector--icon-only .language-selector__option:disabled{opacity:.6;cursor:not-allowed}.language-selector--icon-only .language-selector__check{color:var(--ds-color-accent-500);font-size:var(--ds-font-size-sm)}.tool-right-rail{position:relative;align-self:stretch;height:auto;min-height:0;min-width:40px;padding:0 var(--tool-card-header-pad-x, 10px) 0 8px;margin-left:2px;margin-right:calc(-1 * var(--tool-card-header-pad-x, 10px));margin-top:calc(-1 * var(--tool-card-header-pad-y, 10px));margin-bottom:calc(-1 * var(--tool-card-header-pad-y, 10px));box-sizing:border-box;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--tool-card-text-muted);border:0;border-radius:0;background:transparent;cursor:pointer;font:inherit;appearance:none}.tool-right-rail:hover:not(:disabled),.tool-right-rail:focus-visible{background:color-mix(in srgb,var(--tool-card-text-muted) 8%,transparent)}.tool-right-rail:hover .tool-right-rail__visual{color:var(--ds-chat-text-primary)}.tool-right-rail:after{content:"";position:absolute;left:0;top:0;bottom:0;width:0;border-left:1px solid var(--ds-chat-border-strong);pointer-events:none;z-index:var(--ds-z-local)}.tool-right-rail:focus-visible{outline:2px solid var(--ds-chat-accent, var(--ds-status-surface-info-fg));outline-offset:-2px}.tool-right-rail__visual{position:relative;z-index:var(--ds-z-local);display:flex;align-items:center;justify-content:center;pointer-events:none}.tool-display-compact{display:flex;align-items:center;gap:8px;font-size:var(--flowchat-font-size-base);line-height:1.65;position:relative}.tool-icon{flex-shrink:0;display:inline-flex;align-items:center}.tool-action{font-weight:500;white-space:nowrap}.status-icon{flex-shrink:0;display:inline-flex;align-items:center;margin-left:auto}@keyframes expandDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}:root{--tool-card-font-mono: "SF Mono", "Monaco", "Cascadia Code", "Cascadia Mono", Consolas, "Inconsolata", "Fira Code", "Fira Mono", "Droid Sans Mono", "Source Code Pro", "Lucida Console", "Courier New", monospace;--tool-card-header-pad-y: 7px;--tool-card-header-pad-x: 0px;--tool-card-header-pad-right: 10px;--tool-card-header-icon-rail: 24px;--tool-card-header-icon-slot: calc(var(--tool-card-header-icon-rail) + 10px);--tool-card-icon-size: 16px;--tool-card-action-font-size: var(--flowchat-font-size-base);--tool-card-action-line-height: 1.65;--tool-card-action-font-weight: 500;--tool-card-expanded-pad-y: 8px;--tool-card-expanded-pad-x: 12px}.tool-card-icon-slot{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;width:var(--tool-card-header-icon-slot);margin-right:8px;box-sizing:border-box;min-height:0}.tool-card-icon-slot:after{content:"";position:absolute;right:0;top:calc(-1 * var(--tool-card-header-pad-y));bottom:calc(-1 * var(--tool-card-header-pad-y));width:0;border-right:1px solid var(--ds-chat-border-strong);pointer-events:none;z-index:var(--ds-z-base)}.tool-card-icon-slot.tool-card-icon-slot--no-divider:after{display:none}.tool-card-icon-affordance-hit{position:absolute;inset:0;z-index:var(--ds-z-raised);margin:0;padding:0;border:none;background:transparent;cursor:pointer;appearance:none}.tool-card-icon-marks{position:relative;z-index:var(--ds-z-local);width:var(--tool-card-header-icon-rail);height:var(--tool-card-header-icon-rail);flex-shrink:0;display:flex;align-items:center;justify-content:center}.tool-card-icon.tool-identifier-icon.tool-card-icon-main svg{width:var(--tool-card-icon-size);height:var(--tool-card-icon-size)}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes slide-in-bottom{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slide-in-top{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes slide-in-left{0%{transform:translate(-20px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes slide-in-right{0%{transform:translate(20px);opacity:0}to{transform:translate(0);opacity:1}}.compact-tool-card-wrapper{display:flex;flex-direction:column;gap:0;font-size:var(--flowchat-font-size-base);line-height:1.65}.compact-tool-card-wrapper.compact-tool-card-wrapper--expanded{margin:4px 0;border:1px solid var(--ds-chat-border-strong);border-radius:8px;background:var(--ds-chat-surface);overflow:hidden;box-shadow:0 1px 4px color-mix(in srgb,var(--ds-color-bg-app) 8%,transparent),inset 0 1px color-mix(in srgb,var(--ds-chat-text-primary) 2%,transparent)}.compact-tool-card-wrapper.compact-tool-card-wrapper--expanded:hover{border-color:var(--ds-chat-border-strong)}.compact-tool-card-wrapper.compact-tool-card-wrapper--expanded>.compact-tool-card{padding:8px 10px}.compact-tool-card-wrapper.compact-tool-card-wrapper--expanded.requires-confirmation{border-color:var(--ds-chat-warning, var(--ds-status-surface-warning-fg));box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-status-surface-warning-fg) 14%,transparent),0 0 12px color-mix(in srgb,var(--ds-status-surface-warning-fg) 16%,transparent)}.flowchat-flow-item,.flowchat-tool-wrapper{margin:0 0 .6rem;font-size:var(--flowchat-font-size-base);line-height:1.65}.flow-tool-card-wrapper{display:flex;flex-direction:column;gap:.2rem}.flow-tool-card-note{margin-left:1.5rem;color:var(--ds-chat-text-secondary);font-size:.82em;line-height:1.45;opacity:.84}.flow-tool-card-note.flow-tool-card-note--interrupted{text-decoration:line-through;text-decoration-thickness:1px;text-decoration-color:currentColor}.compact-tool-card-wrapper--loading-shimmer .compact-card-status-icon:has(.cube-loading),.compact-tool-card-wrapper--loading-shimmer .compact-card-status-icon:has(.dot-matrix-loader){display:none}.compact-tool-card-wrapper--loading-shimmer .compact-card-status-icon,.compact-tool-card-wrapper--loading-shimmer .compact-card-action,.compact-tool-card-wrapper--loading-shimmer .compact-card-content{animation:tool-card-text-fade 1.6s ease-in-out infinite}.compact-tool-card{background:transparent;border:none;padding:0 8px 0 0;margin:0;box-shadow:none;display:flex;align-items:center;gap:8px;transition:all .25s cubic-bezier(.4,0,.2,1);position:relative}.compact-tool-card.clickable:hover{background:transparent;border:none;box-shadow:none}.compact-tool-card.clickable:hover .compact-card-status-icon{color:var(--ds-chat-success);transform:scale(1.05)}.compact-tool-card.clickable:hover .compact-card-action,.compact-tool-card.clickable:hover .compact-card-content,.compact-tool-card.clickable:hover .compact-card-extra{color:var(--ds-chat-text-primary)}.compact-tool-card.clickable:hover .compact-card-right-icon{color:var(--ds-chat-success);transform:scale(1.05)}.compact-tool-card.clickable:active{background:transparent}.compact-tool-card.clickable:active .compact-card-status-icon{transform:scale(1)}.compact-tool-card:not(.clickable):hover .compact-card-action,.compact-tool-card:not(.clickable):hover .compact-card-content{color:var(--ds-chat-text-primary)}.compact-tool-card:not(.clickable):hover .compact-card-status-icon{opacity:.95}.compact-card-status-icon{font-size:var(--flowchat-font-size-base);line-height:1;flex-shrink:0;color:var(--ds-chat-text-muted);display:flex;align-items:center;justify-content:center;transition:all .25s cubic-bezier(.4,0,.2,1);position:relative}.compact-card-status-icon>svg{display:block}button.compact-card-status-icon{margin:0;padding:0;border:0;background:transparent;font:inherit;cursor:pointer;appearance:none}button.compact-card-status-icon:focus-visible{border-radius:var(--ds-radius-xs);outline:2px solid var(--ds-chat-accent);outline-offset:2px}.compact-card-status-icon__main{display:flex;align-items:center;justify-content:center;transition:opacity .18s ease}.compact-card-status-icon__expand-hint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--ds-chat-text-secondary);opacity:0;pointer-events:none;transition:opacity .18s ease}.compact-card-status-icon__expand-hint svg{display:block;transition:transform .2s ease}.compact-card-status-icon__expand-hint--open svg{transform:rotate(180deg)}.compact-tool-card:hover .compact-card-status-icon--expandable .compact-card-status-icon__main,.compact-tool-card:focus-within .compact-card-status-icon--expandable .compact-card-status-icon__main{opacity:0}.compact-tool-card:hover .compact-card-status-icon--expandable .compact-card-status-icon__expand-hint,.compact-tool-card:focus-within .compact-card-status-icon--expandable .compact-card-status-icon__expand-hint{opacity:1}.compact-card-action{font-size:var(--flowchat-font-size-base);line-height:1.65;font-weight:500;color:var(--ds-chat-text-muted);transition:all .2s cubic-bezier(.4,0,.2,1);flex-shrink:0}.compact-card-content{flex:1;font-size:var(--flowchat-font-size-base);line-height:1.65;color:var(--ds-chat-text-muted);min-width:0;transition:all .2s cubic-bezier(.4,0,.2,1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.compact-card-content .read-file-meta{color:inherit;opacity:.85;transition:all .2s cubic-bezier(.4,0,.2,1)}.compact-card-content .read-file-name{display:inline;max-width:100%;padding:0;border:0;background:transparent;color:var(--ds-chat-text-primary);font:inherit;letter-spacing:0;vertical-align:baseline}.compact-card-content .read-file-name--openable{cursor:pointer}.compact-card-content .read-file-name--openable:hover,.compact-card-content .read-file-name--openable:focus-visible{color:var(--ds-chat-accent);text-decoration:underline;text-underline-offset:2px}.compact-card-content .read-file-name--openable:focus-visible{outline:1px solid var(--ds-chat-accent);outline-offset:2px;border-radius:3px}.compact-tool-card:hover .tool-card-icon-slot--expandable .tool-card-icon-main,.compact-tool-card:focus-within .tool-card-icon-slot--expandable .tool-card-icon-main{opacity:0}.compact-tool-card:hover .tool-card-icon-slot--expandable .tool-card-icon-expand-hint,.compact-tool-card:focus-within .tool-card-icon-slot--expandable .tool-card-icon-expand-hint{opacity:1}.compact-card-extra{font-size:var(--flowchat-font-size-base);line-height:1.65;color:var(--ds-chat-text-muted);display:flex;align-items:center;transition:all .2s cubic-bezier(.4,0,.2,1);flex-shrink:0}.compact-card-extra>svg{display:block}.compact-card-right-icon{font-size:var(--flowchat-font-size-base);line-height:1;flex-shrink:0;color:var(--ds-chat-text-muted);display:flex;align-items:center;justify-content:center;margin-left:auto;transition:all .25s cubic-bezier(.4,0,.2,1)}.compact-card-right-icon>svg{display:block}.compact-tool-card.status-completed .compact-card-status-icon{color:var(--ds-chat-text-muted)}.compact-tool-card.status-completed .compact-card-status-icon .icon-check-done{color:var(--ds-chat-success)}.compact-tool-card.status-running .compact-card-status-icon,.compact-tool-card.status-streaming .compact-card-status-icon{color:var(--ds-chat-accent)}.compact-tool-card.status-error .compact-card-status-icon,.compact-tool-card.status-cancelled .compact-card-status-icon{color:var(--ds-chat-danger)}.compact-tool-card.status-error .compact-card-action,.compact-tool-card.status-error .compact-card-content,.compact-tool-card.status-cancelled .compact-card-action,.compact-tool-card.status-cancelled .compact-card-content{text-decoration:line-through;text-decoration-thickness:1px;text-decoration-color:currentColor}.compact-tool-card-expanded{position:relative;margin:0;padding:10px;background:transparent;border:none;border-top:1px solid var(--ds-chat-border);border-radius:0;animation:expandDown .2s ease-out;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}.compact-detail-info-inline{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;margin:0 0 10px;padding-bottom:8px;border-bottom:1px solid var(--ds-chat-border);font-size:11px;line-height:1.45}.compact-detail-inline-item{display:flex;align-items:center;gap:4px;white-space:nowrap}.compact-detail-inline-label{color:var(--ds-chat-text-muted);font-weight:500}.compact-detail-inline-value{color:var(--ds-chat-text-secondary);font-family:var(--tool-card-font-mono)}.compact-detail-inline-separator{color:var(--ds-chat-border-strong)}.compact-detail-list{display:flex;flex-direction:column;gap:0;max-height:400px;overflow-y:auto}.compact-list-item{display:flex;align-items:center;gap:6px;min-height:0;padding:4px 0;font-size:11px;line-height:1.45;color:var(--ds-chat-text-secondary);border-bottom:1px solid var(--ds-chat-border)}.compact-list-item:last-child{border-bottom:none}.compact-expanded-results-list{display:flex;flex-direction:column;gap:8px;max-height:400px;overflow-y:auto}.compact-expanded-result-item{padding:6px 0;border-radius:0;transition:all .25s cubic-bezier(.4,0,.2,1)}.compact-expanded-result-item:hover{background:transparent}.compact-expanded-result-title{display:flex;align-items:center;gap:6px;color:var(--ds-chat-text-secondary);font-size:13px;font-weight:600;cursor:pointer;margin-bottom:4px;transition:all .2s cubic-bezier(.4,0,.2,1)}.compact-expanded-result-title:hover{color:var(--ds-chat-text-primary);text-decoration:underline}.compact-expanded-result-title:hover .inline-icon{color:var(--ds-chat-success);transform:translate(2px)}.compact-expanded-result-title .inline-icon{flex-shrink:0;color:var(--ds-chat-text-muted);transition:all .2s cubic-bezier(.4,0,.2,1)}.compact-expanded-result-snippet{color:var(--ds-chat-text-muted);font-size:12px;line-height:1.65;margin-bottom:4px;padding-left:18px}.compact-expanded-result-url{color:var(--ds-chat-text-muted);font-size:11px;font-family:var(--tool-card-font-mono);padding-left:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.compact-result-content{margin-top:0}.compact-result-content pre{margin:0;background:var(--ds-chat-surface-muted);border:1px solid var(--ds-chat-border);border-radius:6px;padding:8px 10px;color:var(--ds-chat-text-primary);font-family:var(--tool-card-font-mono);font-size:11px;line-height:1.65;white-space:pre-wrap;word-break:break-word;overflow-x:auto;max-height:400px;overflow-y:auto}@keyframes expandDown{0%{opacity:0}to{opacity:1}}.base-tool-card-wrapper{display:flex;flex-direction:column;margin:6px 0;border-radius:8px;border:1px solid var(--ds-chat-border-strong);background:var(--ds-chat-surface);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:all .3s cubic-bezier(.4,0,.2,1);overflow:hidden}.base-tool-card-wrapper:hover{border-color:var(--ds-chat-border-strong);box-shadow:0 2px 8px color-mix(in srgb,var(--ds-color-bg-app) 15%,transparent),0 1px 4px color-mix(in srgb,var(--ds-color-bg-app) 10%,transparent),inset 0 1px color-mix(in srgb,var(--ds-chat-text-primary) 3%,transparent)}.base-tool-card-wrapper:has(>.base-tool-card-expanded) .base-tool-card-header:after,.base-tool-card-wrapper:has(>.base-tool-card-error) .base-tool-card-header:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:var(--ds-chat-border-strong);pointer-events:none}.base-tool-card-wrapper.requires-confirmation{border-color:var(--ds-chat-warning, var(--ds-status-surface-warning-fg));border-width:1.5px;box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-status-surface-warning-fg) 15%,transparent),0 0 12px color-mix(in srgb,var(--ds-status-surface-warning-fg) 20%,transparent),inset 0 0 8px color-mix(in srgb,var(--ds-status-surface-warning-fg) 5%,transparent);animation:confirmationPulse 2s ease-in-out infinite}.base-tool-card-wrapper.requires-confirmation:hover{border-color:var(--ds-chat-warning, var(--ds-status-surface-warning-fg));box-shadow:0 0 0 2px color-mix(in srgb,var(--ds-status-surface-warning-fg) 25%,transparent),0 0 20px color-mix(in srgb,var(--ds-status-surface-warning-fg) 30%,transparent),0 4px 20px color-mix(in srgb,var(--ds-color-bg-app) 30%,transparent),inset 0 0 12px color-mix(in srgb,var(--ds-status-surface-warning-fg) 8%,transparent)}.base-tool-card-wrapper.requires-confirmation .base-tool-card-header:before{background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--ds-status-surface-warning-fg) 40%,transparent) 50%,transparent 100%)}.base-tool-card{cursor:pointer;position:relative;padding:0;background:transparent;border:none;width:100%;box-sizing:border-box}.base-tool-card-header{--tool-card-header-pad-y: 10px;--tool-card-header-pad-x: 10px;--tool-card-header-icon-rail: 28px;display:flex;align-items:center;gap:4px;padding:var(--tool-card-header-pad-y) var(--tool-card-header-pad-x);position:relative;flex-shrink:0;min-height:0;line-height:1.45;width:100%;box-sizing:border-box;background:transparent;transition:all .3s cubic-bezier(.4,0,.2,1);overflow:hidden}.base-tool-card-header:before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--ds-chat-text-muted) 20%,transparent) 50%,transparent 100%);pointer-events:none}.tool-card-icon-slot{position:relative;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;align-self:stretch;padding-right:10px;margin-right:8px;box-sizing:border-box;min-height:0}.tool-card-icon-slot:after{content:"";position:absolute;right:0;top:calc(-1 * var(--tool-card-header-pad-y));bottom:calc(-1 * var(--tool-card-header-pad-y));width:0;border-right:1px solid var(--ds-chat-border-strong);pointer-events:none}.tool-card-icon-affordance-hit{position:absolute;inset:0;margin:0;padding:0;border:none;background:transparent;cursor:pointer;appearance:none}.tool-card-icon-affordance-hit:focus-visible{outline:2px solid var(--ds-chat-accent, var(--ds-status-surface-info-fg));outline-offset:2px;border-radius:6px}.tool-card-icon-marks{position:relative;width:var(--tool-card-header-icon-rail);height:var(--tool-card-header-icon-rail);flex-shrink:0;display:flex;align-items:center;justify-content:center}.tool-card-icon.tool-identifier-icon.tool-card-icon-main{display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .18s ease}.tool-card-icon.tool-identifier-icon.tool-card-icon-main svg{width:16px;height:16px}.tool-card-icon-slot--expandable .tool-card-icon-expand-hint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;margin:0;padding:0;opacity:0;pointer-events:none;color:var(--ds-chat-text-secondary);transition:opacity .18s ease}.tool-card-icon-slot--expandable .tool-card-icon-expand-hint svg{width:16px;height:16px;flex-shrink:0;transition:transform .2s ease}.tool-card-icon-slot--expandable .tool-card-icon-expand-hint--open svg{transform:rotate(180deg)}.base-tool-card-wrapper:hover .base-tool-card.base-tool-card--header-expandable:not(.status-cancelled) .tool-card-icon-slot--expandable .tool-card-icon-main{opacity:0}.base-tool-card-wrapper:hover .base-tool-card.base-tool-card--header-expandable:not(.status-cancelled) .tool-card-icon-slot--expandable .tool-card-icon-expand-hint{opacity:1}.tool-card-status-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:4px;padding-left:4px;transition:all .2s ease}.tool-card-status-icon.tool-card-status-icon--with-divider{border-left:1px solid var(--ds-chat-border-strong)}.tool-card-status-icon svg{width:14px;height:14px}.tool-card-status-icon .icon-completed{color:var(--ds-chat-success)}.tool-card-status-icon .icon-error{color:var(--ds-chat-danger);filter:drop-shadow(0 0 4px color-mix(in srgb,var(--ds-status-surface-danger-fg) 40%,transparent))}.tool-card-action{font-size:12px;font-weight:500;color:var(--ds-chat-text-primary);transition:color .2s ease;letter-spacing:-.01em;flex-shrink:0;line-height:1.45}.tool-card-content{display:flex;align-items:center;gap:4px;flex:1;min-width:0;font-size:12px;font-weight:500;color:var(--ds-chat-text-primary);transition:color .2s ease;letter-spacing:-.01em;line-height:1.45;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tool-card-interruption-inline{display:inline-flex;align-items:baseline;gap:6px;min-width:0;max-width:100%;overflow:hidden}.tool-card-interruption-subject{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tool-card-interruption-note{display:inline-block;flex:1 0 auto;min-width:12ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ds-chat-text-secondary);opacity:.84;text-decoration:line-through;text-decoration-thickness:1px;text-decoration-color:currentColor}.tool-card-extra{display:flex;align-items:center;gap:2px;flex-shrink:0}.base-tool-card-expanded{padding:10px;background:transparent;position:relative;animation:expandDown .2s ease-out;box-sizing:border-box}.base-tool-card-error{margin-top:8px;padding:8px 12px 8px 22px;margin-left:6px;background:none;border:none;box-shadow:none;cursor:default}.base-tool-card-error .error-content{display:flex;flex-direction:column;gap:4px;background:none;border:none;padding:0}.base-tool-card-error .error-message{font-size:12px;line-height:1.5;color:var(--ds-chat-text-muted);white-space:pre-wrap;word-break:break-word;text-align:left;width:auto;background:none;border:none;padding:0;margin:0;box-shadow:none}@keyframes expandDown{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes confirmationPulse{0%,to{box-shadow:0 0 0 1px color-mix(in srgb,var(--ds-status-surface-warning-fg) 15%,transparent),0 0 12px color-mix(in srgb,var(--ds-status-surface-warning-fg) 20%,transparent),inset 0 0 8px color-mix(in srgb,var(--ds-status-surface-warning-fg) 5%,transparent)}50%{box-shadow:0 0 0 2px color-mix(in srgb,var(--ds-status-surface-warning-fg) 25%,transparent),0 0 20px color-mix(in srgb,var(--ds-status-surface-warning-fg) 35%,transparent),inset 0 0 12px color-mix(in srgb,var(--ds-status-surface-warning-fg) 8%,transparent)}}.base-tool-card.status-completed .icon-completed{color:var(--ds-chat-success)}.base-tool-card.status-error{cursor:default}.base-tool-card.status-error .tool-card-action,.base-tool-card.status-error .tool-card-content{color:var(--ds-chat-text-secondary);text-decoration:line-through;text-decoration-thickness:1px;text-decoration-color:currentColor}.base-tool-card.status-cancelled{cursor:default;opacity:.6}.base-tool-card.status-cancelled .tool-card-action,.base-tool-card.status-cancelled .tool-card-content{color:var(--ds-chat-text-muted)}.base-tool-card-wrapper--loading-shimmer .tool-card-status-icon:has(.cube-loading),.base-tool-card-wrapper--loading-shimmer .tool-card-status-icon:has(.dot-matrix-loader){display:none}.base-tool-card-wrapper--loading-shimmer .tool-card-icon-marks,.base-tool-card-wrapper--loading-shimmer .tool-card-action,.base-tool-card-wrapper--loading-shimmer .tool-card-content{animation:tool-card-text-fade 1.6s ease-in-out infinite}@keyframes tool-card-text-fade{0%,to{opacity:1}50%{opacity:.25}}.default-tool-card-template__action{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:0;height:18px;margin-left:1px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--ds-chat-text-muted);font:inherit;cursor:pointer;appearance:none;opacity:0;overflow:hidden;transform:translate(-2px);transition:width .14s ease,opacity .14s ease,transform .14s ease,background-color .14s ease,color .14s ease}.default-tool-card-template__action svg{display:block;flex-shrink:0}.default-tool-card-template__action:hover,.default-tool-card-template__action:focus-visible{background:var(--ds-chat-surface-hover);color:var(--ds-chat-text-primary)}.default-tool-card-template__action--always-visible,.compact-tool-card:hover .default-tool-card-template__action,.compact-tool-card:focus-within .default-tool-card-template__action{width:18px;opacity:1;transform:translate(0)}.heavy-tool-card-template.base-tool-card-wrapper .base-tool-card.status-error.base-tool-card--header-expandable{cursor:pointer}.heavy-tool-card-template .task-header-wrapper{display:flex;align-items:stretch;gap:4px;flex:1;min-width:0}.heavy-tool-card-template .task-icon-container{position:relative;display:flex;align-items:center;justify-content:center;flex-shrink:0;align-self:stretch;padding-right:10px;margin-right:8px;box-sizing:border-box;min-height:0;color:var(--ds-chat-text-secondary, var(--ds-status-surface-neutral-fg))}.heavy-tool-card-template .task-icon-container:after{content:"";position:absolute;right:0;top:calc(-1 * var(--tool-card-header-pad-y, 10px));bottom:calc(-1 * var(--tool-card-header-pad-y, 10px));width:0;border-right:1px solid var(--ds-chat-border-strong);pointer-events:none}.heavy-tool-card-template .task-icon-container.is-running{color:var(--ds-chat-accent, var(--ds-status-surface-info-fg))}.heavy-tool-card-template .task-task-icon-marks{position:relative;width:var(--tool-card-header-icon-rail, 28px);height:var(--tool-card-header-icon-rail, 28px);flex-shrink:0;display:flex;align-items:center;justify-content:center}.heavy-tool-card-template .task-task-icon-main{display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .18s ease}.heavy-tool-card-template .task-task-icon-main svg{width:16px;height:16px}.heavy-tool-card-template .task-icon-container--expandable .task-task-icon-hint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;margin:0;padding:0;opacity:0;pointer-events:none;color:var(--ds-chat-text-secondary);transition:opacity .18s ease}.heavy-tool-card-template .task-icon-container--expandable .task-task-icon-hint svg{width:16px;height:16px;flex-shrink:0;transition:transform .2s ease}.heavy-tool-card-template .task-icon-container--expandable .task-task-icon-hint--open svg{transform:rotate(180deg)}.heavy-tool-card-template.base-tool-card-wrapper:hover .base-tool-card.base-tool-card--header-expandable:not(.status-cancelled) .task-icon-container.task-icon-container--expandable .task-task-icon-main{opacity:0}.heavy-tool-card-template.base-tool-card-wrapper:hover .base-tool-card.base-tool-card--header-expandable:not(.status-cancelled) .task-icon-container.task-icon-container--expandable .task-task-icon-hint{opacity:1}.heavy-tool-card-template .task-content-wrapper{display:flex;flex-direction:column;flex:1;min-width:0;align-self:stretch;justify-content:center}.heavy-tool-card-template .task-body-columns{display:flex;align-items:center;gap:0;flex:1;min-width:0}.heavy-tool-card-template .task-body-main{display:flex;flex-direction:column;justify-content:center;flex:1;min-width:0}.heavy-tool-card-template .task-header-main{display:flex;align-items:center;gap:6px;width:100%;min-height:20px}.heavy-tool-card-template .task-header-subline{display:flex;align-items:center;min-width:0;margin-top:3px}.heavy-tool-card-template .task-action{font-size:12px;font-weight:500;color:var(--ds-chat-text-primary);flex-shrink:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.heavy-tool-card-template .task-header-main--failed .task-action{color:var(--ds-chat-text-muted, var(--ds-status-surface-neutral-fg))}.heavy-tool-card-template .task-header-meta{display:flex;align-items:center;gap:6px;margin-left:auto;margin-right:10px;flex-shrink:0}.heavy-tool-card-template .task-header-rail{min-width:40px;margin-left:4px;background:transparent}.heavy-tool-card-template .task-header-rail:hover .tool-right-rail__visual{color:var(--ds-chat-text-primary)}.heavy-tool-card-template .task-header-rail .tool-right-rail__visual{position:relative;display:flex;align-items:center;justify-content:center;align-self:center;gap:6px;color:var(--ds-chat-text-muted);pointer-events:none;background:transparent;border:0;box-shadow:none}.heavy-tool-card-template .task-header-rail .tool-right-rail__visual>svg{flex-shrink:0}.heavy-tool-card-template .task-status-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:4px;padding-left:4px;border-left:1px solid var(--ds-chat-border-strong)}.heavy-tool-card-template .task-status-icon .icon-completed{color:var(--ds-chat-success)}.heavy-tool-card-template .task-status-icon .loading{width:16px;height:16px}.heavy-tool-card-template .task-status-icon--rail{position:relative;margin-left:0;padding-left:0;border-left:none}.heavy-tool-card-template .task-status-icon--rail:empty{display:none}.heavy-tool-card-template .duration-text{display:flex;align-items:center;gap:4px;color:var(--tool-card-text-secondary, var(--ds-chat-text-secondary, var(--ds-chat-text-secondary)));font-size:12px;font-weight:600;letter-spacing:.01em;line-height:1.2}.heavy-tool-card-template .duration-text svg{flex-shrink:0;opacity:.95}.heavy-tool-card-template.base-tool-card-wrapper--loading-shimmer .task-status-icon:has(.cube-loading){display:none}.heavy-tool-card-template.base-tool-card-wrapper--loading-shimmer .task-action{animation:tool-card-text-fade 1.6s ease-in-out infinite}.heavy-tool-card-template .base-tool-card{cursor:pointer}.tool-action-group{display:inline-flex;align-items:center;gap:6px;flex-shrink:0}.tool-action-group__button{flex-shrink:0}.tool-action-group__text-button{gap:6px;min-height:24px;height:24px;padding:0 9px;border-radius:999px;font-size:var(--flowchat-font-size-xs);line-height:1}.tool-action-group__text-button--primary,.tool-action-group__text-button--success{color:var(--ds-chat-success)}.tool-action-group__text-button--danger{color:var(--ds-chat-danger)}.tool-action-group__text-button--warning{color:var(--ds-chat-warning)}.tool-error-block{display:flex;flex-direction:column;gap:8px;color:var(--ds-chat-danger, var(--ds-status-surface-danger-fg))}.tool-error-block__title{display:flex;align-items:center;gap:6px;font-weight:600}.tool-error-block__message,.tool-error-block__details{white-space:pre-wrap;word-break:break-word;font-size:var(--flowchat-font-size-base);line-height:1.55}.tool-error-block__details{color:var(--ds-chat-text-muted);font-size:var(--flowchat-font-size-xs)}.tool-json-preview-shell{position:relative;min-width:0}.tool-json-preview-shell__toolbar{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-bottom:6px}.tool-json-preview-shell__truncated{color:var(--tool-card-text-tertiary);font-size:11px}.tool-json-preview-shell__copy{display:inline-flex;align-items:center;gap:5px;padding:3px 7px;border:1px solid var(--tool-card-border-subtle);border-radius:999px;background:var(--tool-card-bg-secondary);color:var(--tool-card-text-secondary);font-size:11px;line-height:1;cursor:pointer}.tool-json-preview-shell__copy:hover{border-color:var(--tool-card-border);color:var(--tool-card-text-primary)}.tool-json-preview{margin:0;padding:10px 12px;border:1px solid var(--tool-card-border-subtle);border-radius:8px;background:var(--tool-card-bg-secondary);color:var(--tool-card-text-secondary);font-family:var(--tool-card-font-mono);font-size:12px;line-height:1.55;white-space:pre-wrap;word-break:break-word;max-height:280px;overflow:auto}.tool-structured-details,.tool-structured-details__rows{display:flex;flex-direction:column;gap:10px}.tool-structured-details__row{display:flex;align-items:baseline;gap:8px;min-width:0}.tool-structured-details__label{flex-shrink:0;color:var(--tool-card-text-muted);font-size:12px;font-weight:600}.tool-structured-details__value{min-width:0;color:var(--tool-card-text-secondary);word-break:break-word}.tool-structured-details__chips{display:flex;flex-wrap:wrap;gap:6px}.tool-structured-details__chip{display:inline-flex;align-items:center;max-width:100%;padding:2px 7px;border:1px solid var(--tool-card-border-subtle);border-radius:999px;background:color-mix(in srgb,var(--tool-card-bg-secondary) 75%,transparent);color:var(--tool-card-text-secondary);font-size:11px;line-height:1.45}.tool-structured-details__empty{color:var(--tool-card-text-muted);font-size:var(--flowchat-font-size-base)}.app-defined-tool-card{--app-defined-tool-accent: var(--ds-status-surface-neutral-fg);min-width:0}.app-defined-tool-card .tool-card-icon-main{color:var(--app-defined-tool-accent)}.app-defined-tool-card .compact-card-extra{display:inline-flex;align-items:center;gap:6px}.app-defined-tool-card.requires-confirmation .compact-tool-card{border-radius:8px;background:color-mix(in srgb,var(--ds-status-surface-warning-fg) 5%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ds-status-surface-warning-fg) 18%,transparent)}.app-defined-tool-card__bridge-status{color:var(--ds-chat-text-muted);font-size:var(--flowchat-font-size-xs);white-space:nowrap}.app-defined-tool-card__details{min-width:0}.app-defined-tool-card__json-field{display:flex;min-width:0;flex-direction:column;gap:6px}.app-defined-tool-card__json-label{color:var(--tool-card-text-muted);font-size:12px;font-weight:600}.compact-tool-card-wrapper.ls-display-card.compact-tool-card-wrapper--expanded .compact-tool-card-expanded{padding:0}.ls-display-card__table-wrap{max-height:400px;overflow-x:hidden;overflow-y:auto;scrollbar-gutter:auto;scrollbar-width:none;background:transparent}.ls-display-card__table-wrap::-webkit-scrollbar{width:0;height:0}.ls-display-card__table-wrap:hover{scrollbar-width:thin}.ls-display-card__table-wrap:hover::-webkit-scrollbar{width:6px;height:6px}.ls-display-card__table{width:100%;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:var(--flowchat-font-size-sm)}.ls-display-card__table td{min-width:0;padding:8px 10px;border-bottom:1px solid var(--ds-markdown-table-border);color:var(--ds-color-text-primary);text-align:left;vertical-align:middle;transition:background var(--ds-motion-fast) var(--ds-easing-standard),border-color var(--ds-motion-fast) var(--ds-easing-standard)}.ls-display-card__table tbody tr:nth-child(2n){background:color-mix(in srgb,var(--ds-markdown-table-row-hover-bg) 65%,transparent)}.ls-display-card__table tbody tr:hover{background:var(--ds-markdown-inline-code-bg)}.ls-display-card__table tbody tr:last-child td{border-bottom:none}.ls-display-card__entry-result{display:grid;grid-template-columns:16px minmax(0,1fr);align-items:center;column-gap:8px;min-width:0}.ls-display-card__entry-icon{display:block;color:var(--ds-chat-text-muted)}.ls-display-card__entry-name{display:block;min-width:0;color:var(--ds-color-text-primary);font-family:var(--tool-card-font-mono);line-height:1.45;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ls-display-card__table td.ls-display-card__more{text-align:center}.settings-catalog-card__results{display:flex;flex-direction:column;max-height:360px;margin:0;padding:0;overflow-y:auto;list-style:none}.settings-catalog-card__result{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--ds-space-4);align-items:center;min-width:0;padding:var(--ds-space-2) var(--ds-space-1);border-bottom:1px solid var(--ds-chat-border);border-radius:var(--ds-radius-sm);transition:background-color var(--ds-motion-fast) var(--ds-easing-standard)}.settings-catalog-card__result:last-child{border-bottom:0}.settings-catalog-card__result-copy,.settings-catalog-card__result-value{display:flex;flex-direction:column;min-width:0}.settings-catalog-card__result-title,.settings-catalog-card__result-value strong{overflow:hidden;color:var(--ds-chat-text-primary);font-size:var(--flowchat-font-size-base);font-weight:var(--ds-font-weight-medium);line-height:1.45;text-overflow:ellipsis;white-space:nowrap}.settings-catalog-card__result-location,.settings-catalog-card__result-value-label{color:var(--ds-chat-text-muted);font-size:var(--ds-font-size-xs);line-height:1.45}.settings-catalog-card__result-value{align-items:flex-end;max-width:18rem;text-align:right}@media(hover:hover){.settings-catalog-card__result:hover{background:var(--ds-color-element-soft)}}@media(max-width:560px){.settings-catalog-card__result{grid-template-columns:minmax(0,1fr);gap:var(--ds-space-1)}.settings-catalog-card__result-value{align-items:flex-start;max-width:none;text-align:left}}.compact-tool-card-quick-preview{display:grid;align-content:start;gap:var(--ds-space-8);width:min(100%,900px);min-height:100vh;margin:0 auto;padding:72px 48px;box-sizing:border-box;background:var(--ds-chat-surface, var(--ds-color-bg-scene))}.compact-tool-card-quick-preview__sample{min-width:0}body:has(.compact-tool-card-quick-preview){margin:0;background:var(--ds-chat-surface, var(--ds-color-bg-scene))}@media(max-width:560px){.compact-tool-card-quick-preview{gap:var(--ds-space-6);padding:32px 16px}}.focused-preview{height:100%;min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;background:var(--color-bg-secondary)}.focused-preview__header{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:32px;padding:26px clamp(28px,3.6vw,52px) 23px;border-bottom:1px solid var(--border-subtle);background:var(--color-bg-secondary)}.focused-preview__title-group,.focused-preview__heading>div{min-width:0}.focused-preview__eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:10px;color:var(--color-text-muted);font-size:9px;font-weight:700;letter-spacing:.09em;text-transform:uppercase}.focused-preview__eyebrow span+span:before{content:"/";margin-right:8px;color:var(--border-base)}.focused-preview__heading{display:flex;align-items:flex-start;justify-content:space-between;gap:28px}.focused-preview__heading h2{margin:0;color:var(--color-text-primary);font-size:clamp(26px,2.5vw,34px);font-weight:650;letter-spacing:-.035em;line-height:1.08}.focused-preview__heading p{max-width:720px;margin:8px 0 0;color:var(--color-text-secondary);font-size:12px;line-height:1.55}.focused-preview__heading code{max-width:240px;overflow:hidden;padding-top:7px;color:var(--color-text-muted);font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:9px;text-overflow:ellipsis;white-space:nowrap}.focused-preview__controls,.focused-preview__stepper{display:flex;align-items:center}.focused-preview__controls{gap:12px;padding-top:13px}.focused-preview__stepper{gap:3px}.focused-preview__stepper>span{min-width:54px;color:var(--color-text-secondary);font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:9px;text-align:center}.focused-preview__stepper i{margin:0 5px;color:var(--border-base);font-style:normal}.focused-preview__usage-trigger{gap:6px;color:var(--color-text-secondary)}.focused-preview__body{position:relative;min-height:0;overflow:hidden}.focused-preview__stage{width:100%;height:100%;min-height:0;display:flex;align-items:stretch;justify-content:center;overflow:auto;padding:clamp(26px,3.8vw,52px);scrollbar-width:thin}.focused-preview__viewport{min-width:0}.focused-preview--primitive .focused-preview__stage{align-items:center;background:var(--color-bg-secondary)}.focused-preview--primitive .focused-preview__viewport{width:min(100%,900px);display:flex;align-items:center;justify-content:center}.focused-preview--pattern .focused-preview__stage,.focused-preview--recipe .focused-preview__stage{align-items:flex-start;background:var(--color-bg-primary)}.focused-preview--pattern .focused-preview__viewport{width:min(100%,1280px)}.focused-preview--recipe .focused-preview__viewport{width:min(100%,1120px)}.focused-preview--pattern .focused-preview__viewport>*,.focused-preview--recipe .focused-preview__viewport>*{width:100%}.focused-preview__inspector{position:absolute;top:0;right:0;bottom:0;width:min(340px,88%);overflow-y:auto;padding:0 22px 24px;border-left:1px solid var(--border-subtle);background:var(--color-bg-secondary);scrollbar-width:thin}.focused-preview__inspector-header{position:sticky;top:0;min-height:54px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-bottom:1px solid var(--border-subtle);background:var(--color-bg-secondary);color:var(--color-text-primary);font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.focused-preview__inspector .preview-usage-guide{width:100%;border:0;background:transparent}.focused-preview__inspector .preview-usage-guide__panel-meta{padding:16px 0 2px;color:var(--color-text-muted);font-size:10px}.focused-preview__inspector .preview-usage-guide__body{padding:12px 0 0}.focused-preview__inspector .preview-usage-guide__grid{grid-template-columns:1fr;gap:20px}@media(max-width:900px){.focused-preview__header{gap:20px;padding:22px}.focused-preview__heading code{display:none}.focused-preview__controls{gap:6px}.focused-preview__usage-trigger{padding-inline:8px}.focused-preview__stage{padding:22px}}@media(max-width:700px){.focused-preview__header{grid-template-columns:1fr;gap:14px;padding:18px 14px 15px}.focused-preview__heading h2{font-size:24px}.focused-preview__controls{justify-content:space-between;padding-top:0}.focused-preview__stage{padding:18px 14px}.focused-preview__inspector{width:100%}}*{box-sizing:border-box}html,body,#root{height:100%}body{margin:0;font-family:var( --font-family-sans, "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif );-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:var(--color-bg-primary);color:var(--color-text-primary)}button,input{font:inherit}.preview-app{--preview-sidebar-width: 284px;height:100vh;display:flex;flex-direction:column;overflow:hidden;background:var(--color-bg-primary);color:var(--color-text-primary)}.preview-header{min-height:60px;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:10px 18px;background:var(--color-bg-secondary);border-bottom:1px solid var(--border-subtle)}.preview-brand,.preview-brand__copy,.preview-header-actions,.preview-theme-selector,.preview-theme-selector__label{display:flex;align-items:center}.preview-brand{min-width:0;gap:10px}.preview-brand__mark{width:24px;height:24px;display:grid;place-items:center;flex:0 0 auto;color:var(--color-text-primary)}.preview-brand__copy{min-width:0;gap:7px}.preview-brand__copy h1{margin:0;font-size:14px;font-weight:700;letter-spacing:-.01em;color:var(--color-text-primary)}.preview-brand__copy span{padding-left:7px;border-left:1px solid var(--border-base);color:var(--color-text-secondary);font-size:13px;white-space:nowrap}.preview-version{color:var(--color-text-muted);font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:10px}.preview-header-actions{flex-shrink:0;gap:14px}.preview-theme-selector{gap:10px}.preview-theme-selector__label{gap:6px;color:var(--color-text-muted);font-size:11px;font-weight:600;white-space:nowrap}.preview-theme-selector__select-control{width:176px}.preview-language-selector__select-control{width:138px}.preview-header-actions .select__label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.preview-theme-selector__select-control .select__trigger{min-height:32px;padding:4px 9px;border-radius:var(--ds-radius-lg, 9px);background:var(--element-bg-base)}.preview-theme-selector__select-control .select__value,.preview-theme-selector__select-control .select__placeholder{font-size:12px}.preview-theme-selector__select-control .select__dropdown{z-index:var(--ds-z-sticky, 20)}.preview-container{min-height:0;flex:1;display:flex;overflow:hidden}.preview-sidebar{width:var(--preview-sidebar-width);min-width:var(--preview-sidebar-width);min-height:0;display:flex;flex-direction:column;padding:18px 12px 12px;background:var(--color-bg-secondary);border-right:1px solid var(--border-subtle);transition:width var(--motion-fast) var(--easing-smooth),min-width var(--motion-fast) var(--easing-smooth)}.preview-sidebar--collapsed{width:68px;min-width:68px}.preview-sidebar-header{min-height:28px;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 4px 0 8px;margin-bottom:12px}.preview-sidebar-heading{min-width:0;display:flex;align-items:center;gap:7px}.preview-sidebar-title{color:var(--color-text-secondary);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.preview-sidebar-total,.example-count{display:inline-flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:10px}.preview-sidebar-total{min-width:18px;height:18px}.preview-sidebar-toggle{flex:0 0 auto}.preview-sidebar-toggle__icon{display:inline-flex;transition:transform var(--motion-fast) var(--easing-smooth)}.preview-sidebar-toggle__icon.is-collapsed{transform:rotate(180deg)}.preview-sidebar-search{padding:0 4px 14px}.preview-sidebar-search .search{width:100%}.preview-sidebar-search .search__wrapper{background:transparent;border:0;border-bottom:1px solid var(--border-base);border-radius:0}.preview-sidebar-search .search__input{font-size:12px}.preview-sidebar-search kbd{padding:2px 0;border:0;color:var(--color-text-muted);background:transparent;font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:9px;line-height:1.2}.preview-nav{min-height:0;flex:1;display:flex;flex-direction:column;gap:12px;overflow-y:auto;padding:0 4px 16px;scrollbar-width:thin}.category-section{display:flex;flex-direction:column;gap:2px}.category-button,.category-example-button{width:100%;display:flex;align-items:center;border:0;color:var(--color-text-secondary);background:transparent;cursor:pointer;text-align:left}.category-button{min-height:36px;gap:9px;padding:7px 9px;border-radius:0;font-size:12px;font-weight:650;transition:color var(--motion-fast) var(--easing-smooth),background var(--motion-fast) var(--easing-smooth)}.category-button:hover,.category-example-button:hover,.category-button.active{color:var(--color-text-primary);background:transparent}.category-button__icon{width:20px;height:20px;display:grid;place-items:center;flex:0 0 auto;color:var(--color-text-muted)}.category-button.active .category-button__icon{color:var(--color-accent-500)}.category-name{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.example-count{min-width:18px}.category-examples{display:flex;flex-direction:column;gap:1px;padding:2px 0 2px 37px}.category-example-button{position:relative;min-height:29px;padding:5px 8px;border-radius:0;font-size:11px;line-height:1.3}.category-example-button:before{content:"";position:absolute;left:-14px;width:5px;height:1px;background:var(--border-base)}.category-example-button span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.category-example-button.active{color:var(--color-accent-500);background:transparent}.category-example-button.active:before{height:5px;border-radius:999px;background:var(--color-accent-500)}.preview-sidebar-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 8px 0;border-top:1px solid var(--border-subtle);color:var(--color-text-muted);font-size:10px}.preview-sidebar-empty{display:grid;gap:4px;padding:16px 10px;color:var(--color-text-muted);font-size:11px}.preview-sidebar-empty strong{color:var(--color-text-secondary);font-size:12px}.preview-sidebar--collapsed .preview-sidebar-heading,.preview-sidebar--collapsed .preview-sidebar-search,.preview-sidebar--collapsed .category-name,.preview-sidebar--collapsed .example-count,.preview-sidebar--collapsed .category-examples,.preview-sidebar--collapsed .preview-sidebar-footer,.preview-sidebar--collapsed .preview-sidebar-empty{display:none}.preview-sidebar--collapsed .preview-sidebar-header{justify-content:center;padding:0}.preview-sidebar--collapsed .preview-nav{padding-inline:0}.preview-sidebar--collapsed .category-button{justify-content:center;padding-inline:0}.preview-main{min-width:0;min-height:0;flex:1;overflow:hidden;padding:0;background:var(--color-bg-primary)}.preview-surface-header{max-width:1440px;display:flex;align-items:flex-end;justify-content:space-between;gap:36px;margin:0 auto 28px;padding-bottom:24px;border-bottom:1px solid var(--border-subtle)}.preview-surface-heading{min-width:0}.preview-surface-kicker{display:flex;align-items:center;gap:8px;margin-bottom:10px;color:var(--color-text-muted);font-size:11px}.preview-surface-tier{display:inline-flex;align-items:center;padding:3px 7px;border:1px solid var(--border-subtle);border-radius:var(--ds-radius-md, 6px);background:var(--color-bg-secondary);color:var(--color-text-secondary);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.preview-surface-title{margin:0;color:var(--color-text-primary);font-size:clamp(26px,3vw,38px);font-weight:650;letter-spacing:-.035em;line-height:1.08}.preview-surface-description{max-width:720px;margin:10px 0 0;color:var(--color-text-secondary);font-size:13px;line-height:1.6}.preview-category-guidance{width:min(100%,260px);flex:0 0 auto;border-top:1px solid var(--border-subtle);color:var(--color-text-secondary);font-size:11px}.preview-category-guidance summary,.preview-usage-guide summary{display:flex;align-items:center;justify-content:space-between;gap:10px;cursor:pointer;list-style:none}.preview-category-guidance summary{min-height:34px;color:var(--color-text-secondary);font-weight:650}.preview-category-guidance summary::-webkit-details-marker,.preview-usage-guide summary::-webkit-details-marker{display:none}.preview-category-guidance summary:after,.preview-usage-guide summary:after{content:"+";color:var(--color-text-muted);font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:14px}.preview-category-guidance[open] summary:after,.preview-usage-guide[open] summary:after{content:"−"}.preview-category-guidance p{margin:8px 0 0;line-height:1.55}.preview-category-guidance ul{margin:10px 0 2px;padding-left:18px;line-height:1.55}.preview-category-guidance li+li{margin-top:5px}.preview-canvas{min-height:144px;max-height:600px;display:flex;align-items:flex-start;justify-content:center;overflow:auto;padding:28px;border:1px solid var(--border-subtle);border-radius:var(--ds-radius-lg, 10px);background:var(--color-bg-primary)}.preview-usage-guide{border-top:1px solid var(--border-subtle);background:var(--color-bg-secondary)}.preview-usage-guide summary{min-height:42px;padding:0 18px;color:var(--color-text-secondary);font-size:11px;font-weight:650}.preview-usage-guide summary:after{margin-left:2px}.preview-usage-guide__count{margin-left:auto;color:var(--color-text-muted);font-weight:500}.preview-usage-guide__body{padding:0 18px 18px}.preview-usage-guide__recipe{margin-bottom:12px;color:var(--color-text-secondary);font-size:11px}.preview-usage-guide__recipe code{margin-left:4px;color:var(--color-text-primary);font-family:var(--tool-card-font-mono, "Courier New", monospace)}.preview-usage-guide__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px}.preview-usage-guide__section h4{margin:0 0 6px;color:var(--color-text-primary);font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase}.preview-usage-guide__section ul{margin:0;padding-left:16px;color:var(--color-text-secondary);font-size:11px;line-height:1.5}.preview-usage-guide__section li+li{margin-top:4px}.info-list{min-height:36px;display:grid;grid-template-columns:28px minmax(0,1fr);align-items:center;gap:8px;margin:0;padding:0 18px;border-top:1px solid var(--border-subtle);color:var(--color-text-muted);font-size:10px}.info-list dt{font-weight:600}.info-list dd{min-width:0;margin:0;overflow:hidden;color:var(--color-text-secondary);font-family:var(--tool-card-font-mono, "Courier New", monospace);text-overflow:ellipsis;white-space:nowrap}.empty-state{min-height:420px;display:grid;place-content:center;gap:6px;color:var(--color-text-muted);text-align:center}.empty-state strong{color:var(--color-text-primary);font-size:15px}.empty-state p{margin:0;font-size:12px}.preview-app h3[style]{color:var(--color-text-primary)!important}.preview-surface-stage{min-height:0;flex:1;display:flex;flex-direction:column;overflow:hidden;padding:20px}.preview-surface-info{padding:20px;border-top:1px solid var(--border-subtle)}.recipe-preview-stack{width:min(100%,980px);display:grid;gap:16px}.production-tool-card-preview{width:min(100%,760px);margin:0 auto;display:grid;gap:14px}.production-tool-card-preview>*{min-width:0}.production-tool-card-preview .flowchat-tool-wrapper,.production-tool-card-preview .flowchat-flow-item{margin-bottom:0}.production-tool-card-preview__command{overflow:hidden;color:inherit;font-family:var(--tool-card-font-mono, "Courier New", monospace);font-size:.92em;text-overflow:ellipsis;white-space:nowrap}.production-tool-card-preview__duration{color:var(--ds-chat-text-muted, var(--color-text-muted));font-size:11px}.production-tool-card-preview__output{display:grid;gap:8px;color:var(--ds-chat-text-secondary, var(--color-text-secondary));font-size:12px}.production-tool-card-preview__output code{color:var(--ds-chat-text-primary, var(--color-text-primary));font-family:var(--tool-card-font-mono, "Courier New", monospace)}.recipe-preview-inline{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.recipe-preview-meta{display:grid;gap:6px;color:var(--color-text-secondary);font-size:13px;line-height:1.45}.recipe-preview-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.recipe-preview-metric{padding:10px;border:1px solid var(--border-subtle);border-radius:var(--ds-radius-lg, 8px);background:var(--element-bg-base)}.recipe-preview-metric strong{display:block;margin-bottom:2px;color:var(--color-text-primary);font-size:18px}.recipe-preview-metric span{color:var(--color-text-muted);font-size:12px}.recipe-preview-narrow{width:min(100%,420px)}.recipe-preview-row{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:12px}.recipe-preview-row__copy{min-width:0}.recipe-preview-row__title{margin:0;color:var(--color-text-primary);font-size:13px;font-weight:700}.recipe-preview-row__meta{margin:3px 0 0;overflow-wrap:anywhere;color:var(--color-text-muted);font-size:12px}.recipe-preview-code-path{overflow-wrap:anywhere;font-family:var(--tool-card-font-mono, "Courier New", monospace)}.category-button:focus-visible,.category-example-button:focus-visible{outline:none;box-shadow:inset 2px 0 0 var(--color-accent-500)}.preview-category-guidance summary:focus-visible,.preview-usage-guide summary:focus-visible{outline:2px solid var(--color-accent-500);outline-offset:2px}@media(max-width:1000px){.preview-app{--preview-sidebar-width: 250px}.preview-main{padding:0}.preview-surface-header{align-items:flex-start;flex-direction:column;gap:18px}.preview-category-guidance{width:min(100%,720px)}}@media(max-width:800px){.preview-header{min-height:56px;padding-inline:14px}.preview-container{flex-direction:column}.preview-sidebar,.preview-sidebar--collapsed{width:100%;min-width:100%;padding:10px 12px;border-right:0;border-bottom:1px solid var(--border-subtle)}.preview-sidebar-header{margin-bottom:8px}.preview-sidebar-toggle{display:none}.preview-sidebar--collapsed .preview-sidebar-heading,.preview-sidebar--collapsed .preview-sidebar-search,.preview-sidebar--collapsed .category-name,.preview-sidebar--collapsed .example-count{display:flex}.preview-sidebar-search{padding-bottom:10px}.preview-nav{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));flex:0 0 auto;gap:6px;overflow:visible;padding:0}.category-section{min-width:0}.category-button{min-height:34px}.category-examples,.preview-sidebar-footer{display:none}.preview-main{padding:0}.preview-surface-header{margin-bottom:20px;padding-bottom:18px}.preview-surface-title{font-size:28px}.preview-canvas{padding:22px}}@media(max-width:560px){.preview-brand__copy span,.preview-version,.preview-theme-selector__label{display:none}.preview-theme-selector__select-control{width:106px}.preview-language-selector__select-control{width:92px}.preview-header-actions{gap:6px}.preview-nav{grid-template-columns:1fr}.category-button{min-height:32px}.preview-surface-kicker{margin-bottom:8px}.preview-main{padding:0}.preview-usage-guide__grid,.recipe-preview-metrics{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){.preview-sidebar,.preview-sidebar-toggle__icon,.category-button,.category-example-button{transition:none}}:root{--tool-card-bg-primary: rgba(255, 255, 255, .08);--tool-card-bg-secondary: rgba(255, 255, 255, .06);--tool-card-bg-hover: rgba(255, 255, 255, .1);--tool-card-bg-elevated: rgba(255, 255, 255, .14);--tool-card-border: rgba(255, 255, 255, .08);--tool-card-border-subtle: rgba(255, 255, 255, .04);--tool-card-text-primary: #e8e8e8;--tool-card-text-secondary: #a0a0a0;--tool-card-text-muted: #6b7280;--tool-card-font-mono: "SF Mono", "Monaco", "Cascadia Code", "Cascadia Mono", Consolas, "Inconsolata", "Fira Code", "Fira Mono", "Droid Sans Mono", "Source Code Pro", "Lucida Console", "Courier New", monospace}.column-item-preview{display:block!important;width:100%}.column-item-preview>div{display:flex;flex-direction:column;gap:16px;width:100%}.column-item-preview h3{font-size:14px;font-weight:600;color:#a0a0a0;margin:0 0 12px;padding:0 0 8px;border-bottom:1px solid #1a1a1a}.column-item-preview .base-tool-card,.column-item-preview .read-file-card,.column-item-preview .file-operation-card,.column-item-preview .search-card,.column-item-preview .terminal-card,.column-item-preview .task-card,.column-item-preview .todo-card,.column-item-preview .think-card,.column-item-preview .web-search-card,.column-item-preview .flow-thinking-item{box-sizing:border-box;display:block}.column-item-preview .base-tool-card--compact,.column-item-preview .read-file-card--compact,.column-item-preview .file-operation-card--compact,.column-item-preview .search-card--compact,.column-item-preview .terminal-card--compact,.column-item-preview .task-card--compact,.column-item-preview .todo-card--compact,.column-item-preview .think-card--compact,.column-item-preview .web-search-card--compact{width:100%;max-width:none;margin-bottom:0}.column-item-preview .base-tool-card--standard,.column-item-preview .base-tool-card--detailed{width:100%;max-width:100%}.column-item-preview button{cursor:pointer;pointer-events:auto}.column-item-preview pre{overflow-x:auto;white-space:pre-wrap;word-wrap:break-word}.column-item-preview *{box-sizing:border-box}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.animate-spin{animation:spin 1s linear infinite}.column-item-preview .flow-thinking-item{width:100%;background:transparent;border:none}.column-item-preview .flow-thinking-item.streaming,.column-item-preview .flow-thinking-item.collapsed{background:transparent;border:none} diff --git a/src/web-ui/dist-preview/assets/preview-DWC_IH0E.js b/src/web-ui/dist-preview/assets/preview-DWC_IH0E.js new file mode 100644 index 00000000..0ade84ae --- /dev/null +++ b/src/web-ui/dist-preview/assets/preview-DWC_IH0E.js @@ -0,0 +1,1031 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const c of r)if(c.type==="childList")for(const u of c.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&s(u)}).observe(document,{childList:!0,subtree:!0});function n(r){const c={};return r.integrity&&(c.integrity=r.integrity),r.referrerPolicy&&(c.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?c.credentials="include":r.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function s(r){if(r.ep)return;r.ep=!0;const c=n(r);fetch(r.href,c)}})();function Ig(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var dc={exports:{}},li={},uc={exports:{}},Te={};var hm;function Ly(){if(hm)return Te;hm=1;var i=Symbol.for("react.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),u=Symbol.for("react.context"),m=Symbol.for("react.forward_ref"),h=Symbol.for("react.suspense"),f=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),v=Symbol.iterator;function b(C){return C===null||typeof C!="object"?null:(C=v&&C[v]||C["@@iterator"],typeof C=="function"?C:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},A=Object.assign,F={};function _(C,N,X){this.props=C,this.context=N,this.refs=F,this.updater=X||S}_.prototype.isReactComponent={},_.prototype.setState=function(C,N){if(typeof C!="object"&&typeof C!="function"&&C!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,C,N,"setState")},_.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function E(){}E.prototype=_.prototype;function j(C,N,X){this.props=C,this.context=N,this.refs=F,this.updater=X||S}var z=j.prototype=new E;z.constructor=j,A(z,_.prototype),z.isPureReactComponent=!0;var B=Array.isArray,W=Object.prototype.hasOwnProperty,I={current:null},ee={key:!0,ref:!0,__self:!0,__source:!0};function oe(C,N,X){var ie,ne={},ue=null,Se=null;if(N!=null)for(ie in N.ref!==void 0&&(Se=N.ref),N.key!==void 0&&(ue=""+N.key),N)W.call(N,ie)&&!ee.hasOwnProperty(ie)&&(ne[ie]=N[ie]);var me=arguments.length-2;if(me===1)ne.children=X;else if(1>>1,N=$[C];if(0>>1;Cr(ne,G))uer(Se,ne)?($[C]=Se,$[ue]=G,C=ue):($[C]=ne,$[ie]=G,C=ie);else if(uer(Se,G))$[C]=Se,$[ue]=G,C=ue;else break e}}return te}function r($,te){var G=$.sortIndex-te.sortIndex;return G!==0?G:$.id-te.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;i.unstable_now=function(){return c.now()}}else{var u=Date,m=u.now();i.unstable_now=function(){return u.now()-m}}var h=[],f=[],y=1,v=null,b=3,S=!1,A=!1,F=!1,_=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,j=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function z($){for(var te=n(f);te!==null;){if(te.callback===null)s(f);else if(te.startTime<=$)s(f),te.sortIndex=te.expirationTime,e(h,te);else break;te=n(f)}}function B($){if(F=!1,z($),!A)if(n(h)!==null)A=!0,we(W);else{var te=n(f);te!==null&&L(B,te.startTime-$)}}function W($,te){A=!1,F&&(F=!1,E(oe),oe=-1),S=!0;var G=b;try{for(z(te),v=n(h);v!==null&&(!(v.expirationTime>te)||$&&!Z());){var C=v.callback;if(typeof C=="function"){v.callback=null,b=v.priorityLevel;var N=C(v.expirationTime<=te);te=i.unstable_now(),typeof N=="function"?v.callback=N:v===n(h)&&s(h),z(te)}else s(h);v=n(h)}if(v!==null)var X=!0;else{var ie=n(f);ie!==null&&L(B,ie.startTime-te),X=!1}return X}finally{v=null,b=G,S=!1}}var I=!1,ee=null,oe=-1,O=5,U=-1;function Z(){return!(i.unstable_now()-U$||125<$?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):O=0<$?Math.floor(1e3/$):5},i.unstable_getCurrentPriorityLevel=function(){return b},i.unstable_getFirstCallbackNode=function(){return n(h)},i.unstable_next=function($){switch(b){case 1:case 2:case 3:var te=3;break;default:te=b}var G=b;b=te;try{return $()}finally{b=G}},i.unstable_pauseExecution=function(){},i.unstable_requestPaint=function(){},i.unstable_runWithPriority=function($,te){switch($){case 1:case 2:case 3:case 4:case 5:break;default:$=3}var G=b;b=$;try{return te()}finally{b=G}},i.unstable_scheduleCallback=function($,te,G){var C=i.unstable_now();switch(typeof G=="object"&&G!==null?(G=G.delay,G=typeof G=="number"&&0C?($.sortIndex=G,e(f,$),n(h)===null&&$===n(f)&&(F?(E(oe),oe=-1):F=!0,L(B,G-C))):($.sortIndex=N,e(h,$),A||S||(A=!0,we(W))),$},i.unstable_shouldYield=Z,i.unstable_wrapCallback=function($){var te=b;return function(){var G=b;b=te;try{return $.apply(this,arguments)}finally{b=G}}}})(gc)),gc}var bm;function Wy(){return bm||(bm=1,mc.exports=By()),mc.exports}var km;function zy(){if(km)return At;km=1;var i=gr(),e=Wy();function n(t){for(var o="https://reactjs.org/docs/error-decoder.html?invariant="+t,a=1;a"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),h=Object.prototype.hasOwnProperty,f=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,y={},v={};function b(t){return h.call(v,t)?!0:h.call(y,t)?!1:f.test(t)?v[t]=!0:(y[t]=!0,!1)}function S(t,o,a,d){if(a!==null&&a.type===0)return!1;switch(typeof o){case"function":case"symbol":return!0;case"boolean":return d?!1:a!==null?!a.acceptsBooleans:(t=t.toLowerCase().slice(0,5),t!=="data-"&&t!=="aria-");default:return!1}}function A(t,o,a,d){if(o===null||typeof o>"u"||S(t,o,a,d))return!0;if(d)return!1;if(a!==null)switch(a.type){case 3:return!o;case 4:return o===!1;case 5:return isNaN(o);case 6:return isNaN(o)||1>o}return!1}function F(t,o,a,d,p,g,w){this.acceptsBooleans=o===2||o===3||o===4,this.attributeName=d,this.attributeNamespace=p,this.mustUseProperty=a,this.propertyName=t,this.type=o,this.sanitizeURL=g,this.removeEmptyString=w}var _={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(t){_[t]=new F(t,0,!1,t,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(t){var o=t[0];_[o]=new F(o,1,!1,t[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(t){_[t]=new F(t,2,!1,t.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(t){_[t]=new F(t,2,!1,t,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(t){_[t]=new F(t,3,!1,t.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(t){_[t]=new F(t,3,!0,t,null,!1,!1)}),["capture","download"].forEach(function(t){_[t]=new F(t,4,!1,t,null,!1,!1)}),["cols","rows","size","span"].forEach(function(t){_[t]=new F(t,6,!1,t,null,!1,!1)}),["rowSpan","start"].forEach(function(t){_[t]=new F(t,5,!1,t.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function j(t){return t[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(t){var o=t.replace(E,j);_[o]=new F(o,1,!1,t,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(t){var o=t.replace(E,j);_[o]=new F(o,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(t){var o=t.replace(E,j);_[o]=new F(o,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(t){_[t]=new F(t,1,!1,t.toLowerCase(),null,!1,!1)}),_.xlinkHref=new F("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(t){_[t]=new F(t,1,!1,t.toLowerCase(),null,!0,!0)});function z(t,o,a,d){var p=_.hasOwnProperty(o)?_[o]:null;(p!==null?p.type!==0:d||!(2x||p[w]!==g[x]){var T=` +`+p[w].replace(" at new "," at ");return t.displayName&&T.includes("")&&(T=T.replace("",t.displayName)),T}while(1<=w&&0<=x);break}}}finally{X=!1,Error.prepareStackTrace=a}return(t=t?t.displayName||t.name:"")?N(t):""}function ne(t){switch(t.tag){case 5:return N(t.type);case 16:return N("Lazy");case 13:return N("Suspense");case 19:return N("SuspenseList");case 0:case 2:case 15:return t=ie(t.type,!1),t;case 11:return t=ie(t.type.render,!1),t;case 1:return t=ie(t.type,!0),t;default:return""}}function ue(t){if(t==null)return null;if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case ee:return"Fragment";case I:return"Portal";case O:return"Profiler";case oe:return"StrictMode";case se:return"Suspense";case pe:return"SuspenseList"}if(typeof t=="object")switch(t.$$typeof){case Z:return(t.displayName||"Context")+".Consumer";case U:return(t._context.displayName||"Context")+".Provider";case re:var o=t.render;return t=t.displayName,t||(t=o.displayName||o.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case fe:return o=t.displayName||null,o!==null?o:ue(t.type)||"Memo";case we:o=t._payload,t=t._init;try{return ue(t(o))}catch{}}return null}function Se(t){var o=t.type;switch(t.tag){case 24:return"Cache";case 9:return(o.displayName||"Context")+".Consumer";case 10:return(o._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=o.render,t=t.displayName||t.name||"",o.displayName||(t!==""?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return o;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ue(o);case 8:return o===oe?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof o=="function")return o.displayName||o.name||null;if(typeof o=="string")return o}return null}function me(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function xe(t){var o=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(o==="checkbox"||o==="radio")}function Pe(t){var o=xe(t)?"checked":"value",a=Object.getOwnPropertyDescriptor(t.constructor.prototype,o),d=""+t[o];if(!t.hasOwnProperty(o)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var p=a.get,g=a.set;return Object.defineProperty(t,o,{configurable:!0,get:function(){return p.call(this)},set:function(w){d=""+w,g.call(this,w)}}),Object.defineProperty(t,o,{enumerable:a.enumerable}),{getValue:function(){return d},setValue:function(w){d=""+w},stopTracking:function(){t._valueTracker=null,delete t[o]}}}}function Ye(t){t._valueTracker||(t._valueTracker=Pe(t))}function je(t){if(!t)return!1;var o=t._valueTracker;if(!o)return!0;var a=o.getValue(),d="";return t&&(d=xe(t)?t.checked?"true":"false":t.value),t=d,t!==a?(o.setValue(t),!0):!1}function tt(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function qe(t,o){var a=o.checked;return G({},o,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??t._wrapperState.initialChecked})}function ce(t,o){var a=o.defaultValue==null?"":o.defaultValue,d=o.checked!=null?o.checked:o.defaultChecked;a=me(o.value!=null?o.value:a),t._wrapperState={initialChecked:d,initialValue:a,controlled:o.type==="checkbox"||o.type==="radio"?o.checked!=null:o.value!=null}}function at(t,o){o=o.checked,o!=null&&z(t,"checked",o,!1)}function It(t,o){at(t,o);var a=me(o.value),d=o.type;if(a!=null)d==="number"?(a===0&&t.value===""||t.value!=a)&&(t.value=""+a):t.value!==""+a&&(t.value=""+a);else if(d==="submit"||d==="reset"){t.removeAttribute("value");return}o.hasOwnProperty("value")?so(t,o.type,a):o.hasOwnProperty("defaultValue")&&so(t,o.type,me(o.defaultValue)),o.checked==null&&o.defaultChecked!=null&&(t.defaultChecked=!!o.defaultChecked)}function wn(t,o,a){if(o.hasOwnProperty("value")||o.hasOwnProperty("defaultValue")){var d=o.type;if(!(d!=="submit"&&d!=="reset"||o.value!==void 0&&o.value!==null))return;o=""+t._wrapperState.initialValue,a||o===t.value||(t.value=o),t.defaultValue=o}a=t.name,a!==""&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,a!==""&&(t.name=a)}function so(t,o,a){(o!=="number"||tt(t.ownerDocument)!==t)&&(a==null?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+a&&(t.defaultValue=""+a))}var Mt=Array.isArray;function Le(t,o,a,d){if(t=t.options,o){o={};for(var p=0;p"+o.valueOf().toString()+"",o=Eo.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;o.firstChild;)t.appendChild(o.firstChild)}});function io(t,o){if(o){var a=t.firstChild;if(a&&a===t.lastChild&&a.nodeType===3){a.nodeValue=o;return}}t.textContent=o}var ao={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Ar=["Webkit","ms","Moz","O"];Object.keys(ao).forEach(function(t){Ar.forEach(function(o){o=o+t.charAt(0).toUpperCase()+t.substring(1),ao[o]=ao[t]})});function Lo(t,o,a){return o==null||typeof o=="boolean"||o===""?"":a||typeof o!="number"||o===0||ao.hasOwnProperty(t)&&ao[t]?(""+o).trim():o+"px"}function K(t,o){t=t.style;for(var a in o)if(o.hasOwnProperty(a)){var d=a.indexOf("--")===0,p=Lo(a,o[a],d);a==="float"&&(a="cssFloat"),d?t.setProperty(a,p):t[a]=p}}var ve=G({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Fe(t,o){if(o){if(ve[t]&&(o.children!=null||o.dangerouslySetInnerHTML!=null))throw Error(n(137,t));if(o.dangerouslySetInnerHTML!=null){if(o.children!=null)throw Error(n(60));if(typeof o.dangerouslySetInnerHTML!="object"||!("__html"in o.dangerouslySetInnerHTML))throw Error(n(61))}if(o.style!=null&&typeof o.style!="object")throw Error(n(62))}}function Ve(t,o){if(t.indexOf("-")===-1)return typeof o.is=="string";switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Tt=null;function Ht(t){return t=t.target||t.srcElement||window,t.correspondingUseElement&&(t=t.correspondingUseElement),t.nodeType===3?t.parentNode:t}var _r=null,$o=null,Oo=null;function Dd(t){if(t=Gs(t)){if(typeof _r!="function")throw Error(n(280));var o=t.stateNode;o&&(o=oa(o),_r(t.stateNode,t.type,o))}}function Id(t){$o?Oo?Oo.push(t):Oo=[t]:$o=t}function Md(){if($o){var t=$o,o=Oo;if(Oo=$o=null,Dd(t),o)for(t=0;t>>=0,t===0?32:31-(Zh(t)/Xh|0)|0}var Oi=64,Bi=4194304;function Fs(t){switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return t&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function Wi(t,o){var a=t.pendingLanes;if(a===0)return 0;var d=0,p=t.suspendedLanes,g=t.pingedLanes,w=a&268435455;if(w!==0){var x=w&~p;x!==0?d=Fs(x):(g&=w,g!==0&&(d=Fs(g)))}else w=a&~p,w!==0?d=Fs(w):g!==0&&(d=Fs(g));if(d===0)return 0;if(o!==0&&o!==d&&(o&p)===0&&(p=d&-d,g=o&-o,p>=g||p===16&&(g&4194240)!==0))return o;if((d&4)!==0&&(d|=a&16),o=t.entangledLanes,o!==0)for(t=t.entanglements,o&=d;0a;a++)o.push(t);return o}function Rs(t,o,a){t.pendingLanes|=o,o!==536870912&&(t.suspendedLanes=0,t.pingedLanes=0),t=t.eventTimes,o=31-qt(o),t[o]=a}function of(t,o){var a=t.pendingLanes&~o;t.pendingLanes=o,t.suspendedLanes=0,t.pingedLanes=0,t.expiredLanes&=o,t.mutableReadLanes&=o,t.entangledLanes&=o,o=t.entanglements;var d=t.eventTimes;for(t=t.expirationTimes;0=$s),lu=" ",cu=!1;function du(t,o){switch(t){case"keyup":return Df.indexOf(o.keyCode)!==-1;case"keydown":return o.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function uu(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var zo=!1;function Mf(t,o){switch(t){case"compositionend":return uu(o);case"keypress":return o.which!==32?null:(cu=!0,lu);case"textInput":return t=o.data,t===lu&&cu?null:t;default:return null}}function jf(t,o){if(zo)return t==="compositionend"||!Hr&&du(t,o)?(t=nu(),Vi=$r=En=null,zo=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(o.ctrlKey||o.altKey||o.metaKey)||o.ctrlKey&&o.altKey){if(o.char&&1=o)return{node:a,offset:o-t};t=d}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=wu(a)}}function bu(t,o){return t&&o?t===o?!0:t&&t.nodeType===3?!1:o&&o.nodeType===3?bu(t,o.parentNode):"contains"in t?t.contains(o):t.compareDocumentPosition?!!(t.compareDocumentPosition(o)&16):!1:!1}function ku(){for(var t=window,o=tt();o instanceof t.HTMLIFrameElement;){try{var a=typeof o.contentWindow.location.href=="string"}catch{a=!1}if(a)t=o.contentWindow;else break;o=tt(t.document)}return o}function Gr(t){var o=t&&t.nodeName&&t.nodeName.toLowerCase();return o&&(o==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||o==="textarea"||t.contentEditable==="true")}function Hf(t){var o=ku(),a=t.focusedElem,d=t.selectionRange;if(o!==a&&a&&a.ownerDocument&&bu(a.ownerDocument.documentElement,a)){if(d!==null&&Gr(a)){if(o=d.start,t=d.end,t===void 0&&(t=o),"selectionStart"in a)a.selectionStart=o,a.selectionEnd=Math.min(t,a.value.length);else if(t=(o=a.ownerDocument||document)&&o.defaultView||window,t.getSelection){t=t.getSelection();var p=a.textContent.length,g=Math.min(d.start,p);d=d.end===void 0?g:Math.min(d.end,p),!t.extend&&g>d&&(p=d,d=g,g=p),p=vu(a,g);var w=vu(a,d);p&&w&&(t.rangeCount!==1||t.anchorNode!==p.node||t.anchorOffset!==p.offset||t.focusNode!==w.node||t.focusOffset!==w.offset)&&(o=o.createRange(),o.setStart(p.node,p.offset),t.removeAllRanges(),g>d?(t.addRange(o),t.extend(w.node,w.offset)):(o.setEnd(w.node,w.offset),t.addRange(o)))}}for(o=[],t=a;t=t.parentNode;)t.nodeType===1&&o.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof a.focus=="function"&&a.focus(),a=0;a=document.documentMode,Uo=null,Kr=null,zs=null,Qr=!1;function Su(t,o,a){var d=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;Qr||Uo==null||Uo!==tt(d)||(d=Uo,"selectionStart"in d&&Gr(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),zs&&Ws(zs,d)||(zs=d,d=ea(Kr,"onSelect"),0Ko||(t.current=rl[Ko],rl[Ko]=null,Ko--)}function Ee(t,o){Ko++,rl[Ko]=t.current,t.current=o}var Bn={},ut=On(Bn),bt=On(!1),co=Bn;function Qo(t,o){var a=t.type.contextTypes;if(!a)return Bn;var d=t.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===o)return d.__reactInternalMemoizedMaskedChildContext;var p={},g;for(g in a)p[g]=o[g];return d&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=o,t.__reactInternalMemoizedMaskedChildContext=p),p}function kt(t){return t=t.childContextTypes,t!=null}function sa(){Oe(bt),Oe(ut)}function Lu(t,o,a){if(ut.current!==Bn)throw Error(n(168));Ee(ut,o),Ee(bt,a)}function $u(t,o,a){var d=t.stateNode;if(o=o.childContextTypes,typeof d.getChildContext!="function")return a;d=d.getChildContext();for(var p in d)if(!(p in o))throw Error(n(108,Se(t)||"Unknown",p));return G({},a,d)}function ia(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||Bn,co=ut.current,Ee(ut,t),Ee(bt,bt.current),!0}function Ou(t,o,a){var d=t.stateNode;if(!d)throw Error(n(169));a?(t=$u(t,o,co),d.__reactInternalMemoizedMergedChildContext=t,Oe(bt),Oe(ut),Ee(ut,t)):Oe(bt),Ee(bt,a)}var kn=null,aa=!1,ll=!1;function Bu(t){kn===null?kn=[t]:kn.push(t)}function ny(t){aa=!0,Bu(t)}function Wn(){if(!ll&&kn!==null){ll=!0;var t=0,o=Me;try{var a=kn;for(Me=1;t>=w,p-=w,Sn=1<<32-qt(o)+p|a<Ae?(st=ke,ke=null):st=ke.sibling;var Ne=H(R,ke,D[Ae],Y);if(Ne===null){ke===null&&(ke=st);break}t&&ke&&Ne.alternate===null&&o(R,ke),P=g(Ne,P,Ae),be===null?he=Ne:be.sibling=Ne,be=Ne,ke=st}if(Ae===D.length)return a(R,ke),Be&&po(R,Ae),he;if(ke===null){for(;AeAe?(st=ke,ke=null):st=ke.sibling;var Jn=H(R,ke,Ne.value,Y);if(Jn===null){ke===null&&(ke=st);break}t&&ke&&Jn.alternate===null&&o(R,ke),P=g(Jn,P,Ae),be===null?he=Jn:be.sibling=Jn,be=Jn,ke=st}if(Ne.done)return a(R,ke),Be&&po(R,Ae),he;if(ke===null){for(;!Ne.done;Ae++,Ne=D.next())Ne=Q(R,Ne.value,Y),Ne!==null&&(P=g(Ne,P,Ae),be===null?he=Ne:be.sibling=Ne,be=Ne);return Be&&po(R,Ae),he}for(ke=d(R,ke);!Ne.done;Ae++,Ne=D.next())Ne=ae(ke,R,Ae,Ne.value,Y),Ne!==null&&(t&&Ne.alternate!==null&&ke.delete(Ne.key===null?Ae:Ne.key),P=g(Ne,P,Ae),be===null?he=Ne:be.sibling=Ne,be=Ne);return t&&ke.forEach(function(Ey){return o(R,Ey)}),Be&&po(R,Ae),he}function Qe(R,P,D,Y){if(typeof D=="object"&&D!==null&&D.type===ee&&D.key===null&&(D=D.props.children),typeof D=="object"&&D!==null){switch(D.$$typeof){case W:e:{for(var he=D.key,be=P;be!==null;){if(be.key===he){if(he=D.type,he===ee){if(be.tag===7){a(R,be.sibling),P=p(be,D.props.children),P.return=R,R=P;break e}}else if(be.elementType===he||typeof he=="object"&&he!==null&&he.$$typeof===we&&Vu(he)===be.type){a(R,be.sibling),P=p(be,D.props),P.ref=Ks(R,be,D),P.return=R,R=P;break e}a(R,be);break}else o(R,be);be=be.sibling}D.type===ee?(P=bo(D.props.children,R.mode,Y,D.key),P.return=R,R=P):(Y=Ma(D.type,D.key,D.props,null,R.mode,Y),Y.ref=Ks(R,P,D),Y.return=R,R=Y)}return w(R);case I:e:{for(be=D.key;P!==null;){if(P.key===be)if(P.tag===4&&P.stateNode.containerInfo===D.containerInfo&&P.stateNode.implementation===D.implementation){a(R,P.sibling),P=p(P,D.children||[]),P.return=R,R=P;break e}else{a(R,P);break}else o(R,P);P=P.sibling}P=ic(D,R.mode,Y),P.return=R,R=P}return w(R);case we:return be=D._init,Qe(R,P,be(D._payload),Y)}if(Mt(D))return de(R,P,D,Y);if(te(D))return ge(R,P,D,Y);da(R,D)}return typeof D=="string"&&D!==""||typeof D=="number"?(D=""+D,P!==null&&P.tag===6?(a(R,P.sibling),P=p(P,D),P.return=R,R=P):(a(R,P),P=sc(D,R.mode,Y),P.return=R,R=P),w(R)):a(R,P)}return Qe}var Xo=Gu(!0),Ku=Gu(!1),ua=On(null),pa=null,es=null,gl=null;function hl(){gl=es=pa=null}function fl(t){var o=ua.current;Oe(ua),t._currentValue=o}function yl(t,o,a){for(;t!==null;){var d=t.alternate;if((t.childLanes&o)!==o?(t.childLanes|=o,d!==null&&(d.childLanes|=o)):d!==null&&(d.childLanes&o)!==o&&(d.childLanes|=o),t===a)break;t=t.return}}function ts(t,o){pa=t,gl=es=null,t=t.dependencies,t!==null&&t.firstContext!==null&&((t.lanes&o)!==0&&(St=!0),t.firstContext=null)}function Lt(t){var o=t._currentValue;if(gl!==t)if(t={context:t,memoizedValue:o,next:null},es===null){if(pa===null)throw Error(n(308));es=t,pa.dependencies={lanes:0,firstContext:t}}else es=es.next=t;return o}var mo=null;function wl(t){mo===null?mo=[t]:mo.push(t)}function Qu(t,o,a,d){var p=o.interleaved;return p===null?(a.next=a,wl(o)):(a.next=p.next,p.next=a),o.interleaved=a,Cn(t,d)}function Cn(t,o){t.lanes|=o;var a=t.alternate;for(a!==null&&(a.lanes|=o),a=t,t=t.return;t!==null;)t.childLanes|=o,a=t.alternate,a!==null&&(a.childLanes|=o),a=t,t=t.return;return a.tag===3?a.stateNode:null}var zn=!1;function vl(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ju(t,o){t=t.updateQueue,o.updateQueue===t&&(o.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,effects:t.effects})}function An(t,o){return{eventTime:t,lane:o,tag:0,payload:null,callback:null,next:null}}function Un(t,o,a){var d=t.updateQueue;if(d===null)return null;if(d=d.shared,(Re&2)!==0){var p=d.pending;return p===null?o.next=o:(o.next=p.next,p.next=o),d.pending=o,Cn(t,a)}return p=d.interleaved,p===null?(o.next=o,wl(d)):(o.next=p.next,p.next=o),d.interleaved=o,Cn(t,a)}function ma(t,o,a){if(o=o.updateQueue,o!==null&&(o=o.shared,(a&4194240)!==0)){var d=o.lanes;d&=t.pendingLanes,a|=d,o.lanes=a,Ir(t,a)}}function Yu(t,o){var a=t.updateQueue,d=t.alternate;if(d!==null&&(d=d.updateQueue,a===d)){var p=null,g=null;if(a=a.firstBaseUpdate,a!==null){do{var w={eventTime:a.eventTime,lane:a.lane,tag:a.tag,payload:a.payload,callback:a.callback,next:null};g===null?p=g=w:g=g.next=w,a=a.next}while(a!==null);g===null?p=g=o:g=g.next=o}else p=g=o;a={baseState:d.baseState,firstBaseUpdate:p,lastBaseUpdate:g,shared:d.shared,effects:d.effects},t.updateQueue=a;return}t=a.lastBaseUpdate,t===null?a.firstBaseUpdate=o:t.next=o,a.lastBaseUpdate=o}function ga(t,o,a,d){var p=t.updateQueue;zn=!1;var g=p.firstBaseUpdate,w=p.lastBaseUpdate,x=p.shared.pending;if(x!==null){p.shared.pending=null;var T=x,M=T.next;T.next=null,w===null?g=M:w.next=M,w=T;var q=t.alternate;q!==null&&(q=q.updateQueue,x=q.lastBaseUpdate,x!==w&&(x===null?q.firstBaseUpdate=M:x.next=M,q.lastBaseUpdate=T))}if(g!==null){var Q=p.baseState;w=0,q=M=T=null,x=g;do{var H=x.lane,ae=x.eventTime;if((d&H)===H){q!==null&&(q=q.next={eventTime:ae,lane:0,tag:x.tag,payload:x.payload,callback:x.callback,next:null});e:{var de=t,ge=x;switch(H=o,ae=a,ge.tag){case 1:if(de=ge.payload,typeof de=="function"){Q=de.call(ae,Q,H);break e}Q=de;break e;case 3:de.flags=de.flags&-65537|128;case 0:if(de=ge.payload,H=typeof de=="function"?de.call(ae,Q,H):de,H==null)break e;Q=G({},Q,H);break e;case 2:zn=!0}}x.callback!==null&&x.lane!==0&&(t.flags|=64,H=p.effects,H===null?p.effects=[x]:H.push(x))}else ae={eventTime:ae,lane:H,tag:x.tag,payload:x.payload,callback:x.callback,next:null},q===null?(M=q=ae,T=Q):q=q.next=ae,w|=H;if(x=x.next,x===null){if(x=p.shared.pending,x===null)break;H=x,x=H.next,H.next=null,p.lastBaseUpdate=H,p.shared.pending=null}}while(!0);if(q===null&&(T=Q),p.baseState=T,p.firstBaseUpdate=M,p.lastBaseUpdate=q,o=p.shared.interleaved,o!==null){p=o;do w|=p.lane,p=p.next;while(p!==o)}else g===null&&(p.shared.lanes=0);fo|=w,t.lanes=w,t.memoizedState=Q}}function Zu(t,o,a){if(t=o.effects,o.effects=null,t!==null)for(o=0;oa?a:4,t(!0);var d=Cl.transition;Cl.transition={};try{t(!1),o()}finally{Me=a,Cl.transition=d}}function yp(){return $t().memoizedState}function ay(t,o,a){var d=Gn(t);if(a={lane:d,action:a,hasEagerState:!1,eagerState:null,next:null},wp(t))vp(o,a);else if(a=Qu(t,o,a,d),a!==null){var p=wt();Yt(a,t,d,p),bp(a,o,d)}}function ry(t,o,a){var d=Gn(t),p={lane:d,action:a,hasEagerState:!1,eagerState:null,next:null};if(wp(t))vp(o,p);else{var g=t.alternate;if(t.lanes===0&&(g===null||g.lanes===0)&&(g=o.lastRenderedReducer,g!==null))try{var w=o.lastRenderedState,x=g(w,a);if(p.hasEagerState=!0,p.eagerState=x,Vt(x,w)){var T=o.interleaved;T===null?(p.next=p,wl(o)):(p.next=T.next,T.next=p),o.interleaved=p;return}}catch{}a=Qu(t,o,p,d),a!==null&&(p=wt(),Yt(a,t,d,p),bp(a,o,d))}}function wp(t){var o=t.alternate;return t===He||o!==null&&o===He}function vp(t,o){Zs=ya=!0;var a=t.pending;a===null?o.next=o:(o.next=a.next,a.next=o),t.pending=o}function bp(t,o,a){if((a&4194240)!==0){var d=o.lanes;d&=t.pendingLanes,a|=d,o.lanes=a,Ir(t,a)}}var ba={readContext:Lt,useCallback:pt,useContext:pt,useEffect:pt,useImperativeHandle:pt,useInsertionEffect:pt,useLayoutEffect:pt,useMemo:pt,useReducer:pt,useRef:pt,useState:pt,useDebugValue:pt,useDeferredValue:pt,useTransition:pt,useMutableSource:pt,useSyncExternalStore:pt,useId:pt,unstable_isNewReconciler:!1},ly={readContext:Lt,useCallback:function(t,o){return cn().memoizedState=[t,o===void 0?null:o],t},useContext:Lt,useEffect:cp,useImperativeHandle:function(t,o,a){return a=a!=null?a.concat([t]):null,wa(4194308,4,pp.bind(null,o,t),a)},useLayoutEffect:function(t,o){return wa(4194308,4,t,o)},useInsertionEffect:function(t,o){return wa(4,2,t,o)},useMemo:function(t,o){var a=cn();return o=o===void 0?null:o,t=t(),a.memoizedState=[t,o],t},useReducer:function(t,o,a){var d=cn();return o=a!==void 0?a(o):o,d.memoizedState=d.baseState=o,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:o},d.queue=t,t=t.dispatch=ay.bind(null,He,t),[d.memoizedState,t]},useRef:function(t){var o=cn();return t={current:t},o.memoizedState=t},useState:rp,useDebugValue:Nl,useDeferredValue:function(t){return cn().memoizedState=t},useTransition:function(){var t=rp(!1),o=t[0];return t=iy.bind(null,t[1]),cn().memoizedState=t,[o,t]},useMutableSource:function(){},useSyncExternalStore:function(t,o,a){var d=He,p=cn();if(Be){if(a===void 0)throw Error(n(407));a=a()}else{if(a=o(),ot===null)throw Error(n(349));(ho&30)!==0||np(d,o,a)}p.memoizedState=a;var g={value:a,getSnapshot:o};return p.queue=g,cp(sp.bind(null,d,g,t),[t]),d.flags|=2048,ti(9,op.bind(null,d,g,a,o),void 0,null),a},useId:function(){var t=cn(),o=ot.identifierPrefix;if(Be){var a=xn,d=Sn;a=(d&~(1<<32-qt(d)-1)).toString(32)+a,o=":"+o+"R"+a,a=Xs++,0<\/script>",t=t.removeChild(t.firstChild)):typeof d.is=="string"?t=w.createElement(a,{is:d.is}):(t=w.createElement(a),a==="select"&&(w=t,d.multiple?w.multiple=!0:d.size&&(w.size=d.size))):t=w.createElementNS(t,a),t[rn]=o,t[Vs]=d,Bp(t,o,!1,!1),o.stateNode=t;e:{switch(w=Ve(a,d),a){case"dialog":$e("cancel",t),$e("close",t),p=d;break;case"iframe":case"object":case"embed":$e("load",t),p=d;break;case"video":case"audio":for(p=0;pas&&(o.flags|=128,d=!0,ni(g,!1),o.lanes=4194304)}else{if(!d)if(t=ha(w),t!==null){if(o.flags|=128,d=!0,a=t.updateQueue,a!==null&&(o.updateQueue=a,o.flags|=4),ni(g,!0),g.tail===null&&g.tailMode==="hidden"&&!w.alternate&&!Be)return mt(o),null}else 2*Ke()-g.renderingStartTime>as&&a!==1073741824&&(o.flags|=128,d=!0,ni(g,!1),o.lanes=4194304);g.isBackwards?(w.sibling=o.child,o.child=w):(a=g.last,a!==null?a.sibling=w:o.child=w,g.last=w)}return g.tail!==null?(o=g.tail,g.rendering=o,g.tail=o.sibling,g.renderingStartTime=Ke(),o.sibling=null,a=Ue.current,Ee(Ue,d?a&1|2:a&1),o):(mt(o),null);case 22:case 23:return tc(),d=o.memoizedState!==null,t!==null&&t.memoizedState!==null!==d&&(o.flags|=8192),d&&(o.mode&1)!==0?(Nt&1073741824)!==0&&(mt(o),o.subtreeFlags&6&&(o.flags|=8192)):mt(o),null;case 24:return null;case 25:return null}throw Error(n(156,o.tag))}function fy(t,o){switch(dl(o),o.tag){case 1:return kt(o.type)&&sa(),t=o.flags,t&65536?(o.flags=t&-65537|128,o):null;case 3:return ns(),Oe(bt),Oe(ut),xl(),t=o.flags,(t&65536)!==0&&(t&128)===0?(o.flags=t&-65537|128,o):null;case 5:return kl(o),null;case 13:if(Oe(Ue),t=o.memoizedState,t!==null&&t.dehydrated!==null){if(o.alternate===null)throw Error(n(340));Zo()}return t=o.flags,t&65536?(o.flags=t&-65537|128,o):null;case 19:return Oe(Ue),null;case 4:return ns(),null;case 10:return fl(o.type._context),null;case 22:case 23:return tc(),null;case 24:return null;default:return null}}var Ca=!1,gt=!1,yy=typeof WeakSet=="function"?WeakSet:Set,le=null;function ss(t,o){var a=t.ref;if(a!==null)if(typeof a=="function")try{a(null)}catch(d){Ge(t,o,d)}else a.current=null}function Ul(t,o,a){try{a()}catch(d){Ge(t,o,d)}}var Up=!1;function wy(t,o){if(tl=Hi,t=ku(),Gr(t)){if("selectionStart"in t)var a={start:t.selectionStart,end:t.selectionEnd};else e:{a=(a=t.ownerDocument)&&a.defaultView||window;var d=a.getSelection&&a.getSelection();if(d&&d.rangeCount!==0){a=d.anchorNode;var p=d.anchorOffset,g=d.focusNode;d=d.focusOffset;try{a.nodeType,g.nodeType}catch{a=null;break e}var w=0,x=-1,T=-1,M=0,q=0,Q=t,H=null;t:for(;;){for(var ae;Q!==a||p!==0&&Q.nodeType!==3||(x=w+p),Q!==g||d!==0&&Q.nodeType!==3||(T=w+d),Q.nodeType===3&&(w+=Q.nodeValue.length),(ae=Q.firstChild)!==null;)H=Q,Q=ae;for(;;){if(Q===t)break t;if(H===a&&++M===p&&(x=w),H===g&&++q===d&&(T=w),(ae=Q.nextSibling)!==null)break;Q=H,H=Q.parentNode}Q=ae}a=x===-1||T===-1?null:{start:x,end:T}}else a=null}a=a||{start:0,end:0}}else a=null;for(nl={focusedElem:t,selectionRange:a},Hi=!1,le=o;le!==null;)if(o=le,t=o.child,(o.subtreeFlags&1028)!==0&&t!==null)t.return=o,le=t;else for(;le!==null;){o=le;try{var de=o.alternate;if((o.flags&1024)!==0)switch(o.tag){case 0:case 11:case 15:break;case 1:if(de!==null){var ge=de.memoizedProps,Qe=de.memoizedState,R=o.stateNode,P=R.getSnapshotBeforeUpdate(o.elementType===o.type?ge:Kt(o.type,ge),Qe);R.__reactInternalSnapshotBeforeUpdate=P}break;case 3:var D=o.stateNode.containerInfo;D.nodeType===1?D.textContent="":D.nodeType===9&&D.documentElement&&D.removeChild(D.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(n(163))}}catch(Y){Ge(o,o.return,Y)}if(t=o.sibling,t!==null){t.return=o.return,le=t;break}le=o.return}return de=Up,Up=!1,de}function oi(t,o,a){var d=o.updateQueue;if(d=d!==null?d.lastEffect:null,d!==null){var p=d=d.next;do{if((p.tag&t)===t){var g=p.destroy;p.destroy=void 0,g!==void 0&&Ul(o,a,g)}p=p.next}while(p!==d)}}function Aa(t,o){if(o=o.updateQueue,o=o!==null?o.lastEffect:null,o!==null){var a=o=o.next;do{if((a.tag&t)===t){var d=a.create;a.destroy=d()}a=a.next}while(a!==o)}}function Hl(t){var o=t.ref;if(o!==null){var a=t.stateNode;t.tag,t=a,typeof o=="function"?o(t):o.current=t}}function Hp(t){var o=t.alternate;o!==null&&(t.alternate=null,Hp(o)),t.child=null,t.deletions=null,t.sibling=null,t.tag===5&&(o=t.stateNode,o!==null&&(delete o[rn],delete o[Vs],delete o[al],delete o[ey],delete o[ty])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function qp(t){return t.tag===5||t.tag===3||t.tag===4}function Vp(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||qp(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function ql(t,o,a){var d=t.tag;if(d===5||d===6)t=t.stateNode,o?a.nodeType===8?a.parentNode.insertBefore(t,o):a.insertBefore(t,o):(a.nodeType===8?(o=a.parentNode,o.insertBefore(t,a)):(o=a,o.appendChild(t)),a=a._reactRootContainer,a!=null||o.onclick!==null||(o.onclick=na));else if(d!==4&&(t=t.child,t!==null))for(ql(t,o,a),t=t.sibling;t!==null;)ql(t,o,a),t=t.sibling}function Vl(t,o,a){var d=t.tag;if(d===5||d===6)t=t.stateNode,o?a.insertBefore(t,o):a.appendChild(t);else if(d!==4&&(t=t.child,t!==null))for(Vl(t,o,a),t=t.sibling;t!==null;)Vl(t,o,a),t=t.sibling}var rt=null,Qt=!1;function Hn(t,o,a){for(a=a.child;a!==null;)Gp(t,o,a),a=a.sibling}function Gp(t,o,a){if(an&&typeof an.onCommitFiberUnmount=="function")try{an.onCommitFiberUnmount($i,a)}catch{}switch(a.tag){case 5:gt||ss(a,o);case 6:var d=rt,p=Qt;rt=null,Hn(t,o,a),rt=d,Qt=p,rt!==null&&(Qt?(t=rt,a=a.stateNode,t.nodeType===8?t.parentNode.removeChild(a):t.removeChild(a)):rt.removeChild(a.stateNode));break;case 18:rt!==null&&(Qt?(t=rt,a=a.stateNode,t.nodeType===8?il(t.parentNode,a):t.nodeType===1&&il(t,a),js(t)):il(rt,a.stateNode));break;case 4:d=rt,p=Qt,rt=a.stateNode.containerInfo,Qt=!0,Hn(t,o,a),rt=d,Qt=p;break;case 0:case 11:case 14:case 15:if(!gt&&(d=a.updateQueue,d!==null&&(d=d.lastEffect,d!==null))){p=d=d.next;do{var g=p,w=g.destroy;g=g.tag,w!==void 0&&((g&2)!==0||(g&4)!==0)&&Ul(a,o,w),p=p.next}while(p!==d)}Hn(t,o,a);break;case 1:if(!gt&&(ss(a,o),d=a.stateNode,typeof d.componentWillUnmount=="function"))try{d.props=a.memoizedProps,d.state=a.memoizedState,d.componentWillUnmount()}catch(x){Ge(a,o,x)}Hn(t,o,a);break;case 21:Hn(t,o,a);break;case 22:a.mode&1?(gt=(d=gt)||a.memoizedState!==null,Hn(t,o,a),gt=d):Hn(t,o,a);break;default:Hn(t,o,a)}}function Kp(t){var o=t.updateQueue;if(o!==null){t.updateQueue=null;var a=t.stateNode;a===null&&(a=t.stateNode=new yy),o.forEach(function(d){var p=Ty.bind(null,t,d);a.has(d)||(a.add(d),d.then(p,p))})}}function Jt(t,o){var a=o.deletions;if(a!==null)for(var d=0;dp&&(p=w),d&=~g}if(d=p,d=Ke()-d,d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3e3>d?3e3:4320>d?4320:1960*by(d/1960))-d,10t?16:t,Vn===null)var d=!1;else{if(t=Vn,Vn=null,Ra=0,(Re&6)!==0)throw Error(n(331));var p=Re;for(Re|=4,le=t.current;le!==null;){var g=le,w=g.child;if((le.flags&16)!==0){var x=g.deletions;if(x!==null){for(var T=0;TKe()-Ql?wo(t,0):Kl|=a),Ct(t,o)}function rm(t,o){o===0&&((t.mode&1)===0?o=1:(o=Bi,Bi<<=1,(Bi&130023424)===0&&(Bi=4194304)));var a=wt();t=Cn(t,o),t!==null&&(Rs(t,o,a),Ct(t,a))}function _y(t){var o=t.memoizedState,a=0;o!==null&&(a=o.retryLane),rm(t,a)}function Ty(t,o){var a=0;switch(t.tag){case 13:var d=t.stateNode,p=t.memoizedState;p!==null&&(a=p.retryLane);break;case 19:d=t.stateNode;break;default:throw Error(n(314))}d!==null&&d.delete(o),rm(t,a)}var lm;lm=function(t,o,a){if(t!==null)if(t.memoizedProps!==o.pendingProps||bt.current)St=!0;else{if((t.lanes&a)===0&&(o.flags&128)===0)return St=!1,gy(t,o,a);St=(t.flags&131072)!==0}else St=!1,Be&&(o.flags&1048576)!==0&&Wu(o,la,o.index);switch(o.lanes=0,o.tag){case 2:var d=o.type;xa(t,o),t=o.pendingProps;var p=Qo(o,ut.current);ts(o,a),p=_l(null,o,d,t,p,a);var g=Tl();return o.flags|=1,typeof p=="object"&&p!==null&&typeof p.render=="function"&&p.$$typeof===void 0?(o.tag=1,o.memoizedState=null,o.updateQueue=null,kt(d)?(g=!0,ia(o)):g=!1,o.memoizedState=p.state!==null&&p.state!==void 0?p.state:null,vl(o),p.updater=ka,o.stateNode=p,p._reactInternals=o,Il(o,d,t,a),o=Ll(null,o,d,!0,g,a)):(o.tag=0,Be&&g&&cl(o),yt(null,o,p,a),o=o.child),o;case 16:d=o.elementType;e:{switch(xa(t,o),t=o.pendingProps,p=d._init,d=p(d._payload),o.type=d,p=o.tag=Fy(d),t=Kt(d,t),p){case 0:o=El(null,o,d,t,a);break e;case 1:o=Mp(null,o,d,t,a);break e;case 11:o=Fp(null,o,d,t,a);break e;case 14:o=Rp(null,o,d,Kt(d.type,t),a);break e}throw Error(n(306,d,""))}return o;case 0:return d=o.type,p=o.pendingProps,p=o.elementType===d?p:Kt(d,p),El(t,o,d,p,a);case 1:return d=o.type,p=o.pendingProps,p=o.elementType===d?p:Kt(d,p),Mp(t,o,d,p,a);case 3:e:{if(jp(o),t===null)throw Error(n(387));d=o.pendingProps,g=o.memoizedState,p=g.element,Ju(t,o),ga(o,d,null,a);var w=o.memoizedState;if(d=w.element,g.isDehydrated)if(g={element:d,isDehydrated:!1,cache:w.cache,pendingSuspenseBoundaries:w.pendingSuspenseBoundaries,transitions:w.transitions},o.updateQueue.baseState=g,o.memoizedState=g,o.flags&256){p=os(Error(n(423)),o),o=Ep(t,o,d,a,p);break e}else if(d!==p){p=os(Error(n(424)),o),o=Ep(t,o,d,a,p);break e}else for(Rt=$n(o.stateNode.containerInfo.firstChild),Ft=o,Be=!0,Gt=null,a=Ku(o,null,d,a),o.child=a;a;)a.flags=a.flags&-3|4096,a=a.sibling;else{if(Zo(),d===p){o=_n(t,o,a);break e}yt(t,o,d,a)}o=o.child}return o;case 5:return Xu(o),t===null&&pl(o),d=o.type,p=o.pendingProps,g=t!==null?t.memoizedProps:null,w=p.children,ol(d,p)?w=null:g!==null&&ol(d,g)&&(o.flags|=32),Ip(t,o),yt(t,o,w,a),o.child;case 6:return t===null&&pl(o),null;case 13:return Lp(t,o,a);case 4:return bl(o,o.stateNode.containerInfo),d=o.pendingProps,t===null?o.child=Xo(o,null,d,a):yt(t,o,d,a),o.child;case 11:return d=o.type,p=o.pendingProps,p=o.elementType===d?p:Kt(d,p),Fp(t,o,d,p,a);case 7:return yt(t,o,o.pendingProps,a),o.child;case 8:return yt(t,o,o.pendingProps.children,a),o.child;case 12:return yt(t,o,o.pendingProps.children,a),o.child;case 10:e:{if(d=o.type._context,p=o.pendingProps,g=o.memoizedProps,w=p.value,Ee(ua,d._currentValue),d._currentValue=w,g!==null)if(Vt(g.value,w)){if(g.children===p.children&&!bt.current){o=_n(t,o,a);break e}}else for(g=o.child,g!==null&&(g.return=o);g!==null;){var x=g.dependencies;if(x!==null){w=g.child;for(var T=x.firstContext;T!==null;){if(T.context===d){if(g.tag===1){T=An(-1,a&-a),T.tag=2;var M=g.updateQueue;if(M!==null){M=M.shared;var q=M.pending;q===null?T.next=T:(T.next=q.next,q.next=T),M.pending=T}}g.lanes|=a,T=g.alternate,T!==null&&(T.lanes|=a),yl(g.return,a,o),x.lanes|=a;break}T=T.next}}else if(g.tag===10)w=g.type===o.type?null:g.child;else if(g.tag===18){if(w=g.return,w===null)throw Error(n(341));w.lanes|=a,x=w.alternate,x!==null&&(x.lanes|=a),yl(w,a,o),w=g.sibling}else w=g.child;if(w!==null)w.return=g;else for(w=g;w!==null;){if(w===o){w=null;break}if(g=w.sibling,g!==null){g.return=w.return,w=g;break}w=w.return}g=w}yt(t,o,p.children,a),o=o.child}return o;case 9:return p=o.type,d=o.pendingProps.children,ts(o,a),p=Lt(p),d=d(p),o.flags|=1,yt(t,o,d,a),o.child;case 14:return d=o.type,p=Kt(d,o.pendingProps),p=Kt(d.type,p),Rp(t,o,d,p,a);case 15:return Np(t,o,o.type,o.pendingProps,a);case 17:return d=o.type,p=o.pendingProps,p=o.elementType===d?p:Kt(d,p),xa(t,o),o.tag=1,kt(d)?(t=!0,ia(o)):t=!1,ts(o,a),Sp(o,d,p),Il(o,d,p,a),Ll(null,o,d,!0,t,a);case 19:return Op(t,o,a);case 22:return Dp(t,o,a)}throw Error(n(156,o.tag))};function cm(t,o){return zd(t,o)}function Py(t,o,a,d){this.tag=t,this.key=a,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=o,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=d,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Bt(t,o,a,d){return new Py(t,o,a,d)}function oc(t){return t=t.prototype,!(!t||!t.isReactComponent)}function Fy(t){if(typeof t=="function")return oc(t)?1:0;if(t!=null){if(t=t.$$typeof,t===re)return 11;if(t===fe)return 14}return 2}function Qn(t,o){var a=t.alternate;return a===null?(a=Bt(t.tag,o,t.key,t.mode),a.elementType=t.elementType,a.type=t.type,a.stateNode=t.stateNode,a.alternate=t,t.alternate=a):(a.pendingProps=o,a.type=t.type,a.flags=0,a.subtreeFlags=0,a.deletions=null),a.flags=t.flags&14680064,a.childLanes=t.childLanes,a.lanes=t.lanes,a.child=t.child,a.memoizedProps=t.memoizedProps,a.memoizedState=t.memoizedState,a.updateQueue=t.updateQueue,o=t.dependencies,a.dependencies=o===null?null:{lanes:o.lanes,firstContext:o.firstContext},a.sibling=t.sibling,a.index=t.index,a.ref=t.ref,a}function Ma(t,o,a,d,p,g){var w=2;if(d=t,typeof t=="function")oc(t)&&(w=1);else if(typeof t=="string")w=5;else e:switch(t){case ee:return bo(a.children,p,g,o);case oe:w=8,p|=8;break;case O:return t=Bt(12,a,o,p|2),t.elementType=O,t.lanes=g,t;case se:return t=Bt(13,a,o,p),t.elementType=se,t.lanes=g,t;case pe:return t=Bt(19,a,o,p),t.elementType=pe,t.lanes=g,t;case L:return ja(a,p,g,o);default:if(typeof t=="object"&&t!==null)switch(t.$$typeof){case U:w=10;break e;case Z:w=9;break e;case re:w=11;break e;case fe:w=14;break e;case we:w=16,d=null;break e}throw Error(n(130,t==null?t:typeof t,""))}return o=Bt(w,a,o,p),o.elementType=t,o.type=d,o.lanes=g,o}function bo(t,o,a,d){return t=Bt(7,t,d,o),t.lanes=a,t}function ja(t,o,a,d){return t=Bt(22,t,d,o),t.elementType=L,t.lanes=a,t.stateNode={isHidden:!1},t}function sc(t,o,a){return t=Bt(6,t,null,o),t.lanes=a,t}function ic(t,o,a){return o=Bt(4,t.children!==null?t.children:[],t.key,o),o.lanes=a,o.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},o}function Ry(t,o,a,d,p){this.tag=o,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Dr(0),this.expirationTimes=Dr(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Dr(0),this.identifierPrefix=d,this.onRecoverableError=p,this.mutableSourceEagerHydrationData=null}function ac(t,o,a,d,p,g,w,x,T){return t=new Ry(t,o,a,x,T),o===1?(o=1,g===!0&&(o|=8)):o=0,g=Bt(3,null,null,o),t.current=g,g.stateNode=t,g.memoizedState={element:d,isDehydrated:a,cache:null,transitions:null,pendingSuspenseBoundaries:null},vl(g),t}function Ny(t,o,a){var d=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(e){console.error(e)}}return i(),pc.exports=zy(),pc.exports}var xm;function Uy(){if(xm)return za;xm=1;var i=Mg();return za.createRoot=i.createRoot,za.hydrateRoot=i.hydrateRoot,za}var Hy=Uy();const qy=Ig(Hy),_e=i=>typeof i=="string",ci=()=>{let i,e;const n=new Promise((s,r)=>{i=s,e=r});return n.resolve=i,n.reject=e,n},Cm=i=>i==null?"":""+i,Vy=(i,e,n)=>{i.forEach(s=>{e[s]&&(n[s]=e[s])})},Gy=/###/g,Am=i=>i&&i.indexOf("###")>-1?i.replace(Gy,"."):i,_m=i=>!i||_e(i),wi=(i,e,n)=>{const s=_e(e)?e.split("."):e;let r=0;for(;r{const{obj:s,k:r}=wi(i,e,Object);if(s!==void 0||e.length===1){s[r]=n;return}let c=e[e.length-1],u=e.slice(0,e.length-1),m=wi(i,u,Object);for(;m.obj===void 0&&u.length;)c=`${u[u.length-1]}.${c}`,u=u.slice(0,u.length-1),m=wi(i,u,Object),m?.obj&&typeof m.obj[`${m.k}.${c}`]<"u"&&(m.obj=void 0);m.obj[`${m.k}.${c}`]=n},Ky=(i,e,n,s)=>{const{obj:r,k:c}=wi(i,e,Object);r[c]=r[c]||[],r[c].push(n)},nr=(i,e)=>{const{obj:n,k:s}=wi(i,e);if(n&&Object.prototype.hasOwnProperty.call(n,s))return n[s]},Qy=(i,e,n)=>{const s=nr(i,n);return s!==void 0?s:nr(e,n)},jg=(i,e,n)=>{for(const s in e)s!=="__proto__"&&s!=="constructor"&&(s in i?_e(i[s])||i[s]instanceof String||_e(e[s])||e[s]instanceof String?n&&(i[s]=e[s]):jg(i[s],e[s],n):i[s]=e[s]);return i},ls=i=>i.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var Jy={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};const Yy=i=>_e(i)?i.replace(/[&<>"'\/]/g,e=>Jy[e]):i;class Zy{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const n=this.regExpMap.get(e);if(n!==void 0)return n;const s=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,s),this.regExpQueue.push(e),s}}const Xy=[" ",",","?","!",";"],ew=new Zy(20),tw=(i,e,n)=>{e=e||"",n=n||"";const s=Xy.filter(u=>e.indexOf(u)<0&&n.indexOf(u)<0);if(s.length===0)return!0;const r=ew.getRegExp(`(${s.map(u=>u==="?"?"\\?":u).join("|")})`);let c=!r.test(i);if(!c){const u=i.indexOf(n);u>0&&!r.test(i.substring(0,u))&&(c=!0)}return c},jc=(i,e,n=".")=>{if(!i)return;if(i[e])return Object.prototype.hasOwnProperty.call(i,e)?i[e]:void 0;const s=e.split(n);let r=i;for(let c=0;c-1&&hi?.replace("_","-"),nw={type:"logger",log(i){this.output("log",i)},warn(i){this.output("warn",i)},error(i){this.output("error",i)},output(i,e){console?.[i]?.apply?.(console,e)}};let ow=class Ec{constructor(e,n={}){this.init(e,n)}init(e,n={}){this.prefix=n.prefix||"i18next:",this.logger=e||nw,this.options=n,this.debug=n.debug}log(...e){return this.forward(e,"log","",!0)}warn(...e){return this.forward(e,"warn","",!0)}error(...e){return this.forward(e,"error","")}deprecate(...e){return this.forward(e,"warn","WARNING DEPRECATED: ",!0)}forward(e,n,s,r){return r&&!this.debug?null:(_e(e[0])&&(e[0]=`${s}${this.prefix} ${e[0]}`),this.logger[n](e))}create(e){return new Ec(this.logger,{prefix:`${this.prefix}:${e}:`,...this.options})}clone(e){return e=e||this.options,e.prefix=e.prefix||this.prefix,new Ec(this.logger,e)}};var fn=new ow;class hr{constructor(){this.observers={}}on(e,n){return e.split(" ").forEach(s=>{this.observers[s]||(this.observers[s]=new Map);const r=this.observers[s].get(n)||0;this.observers[s].set(n,r+1)}),this}off(e,n){if(this.observers[e]){if(!n){delete this.observers[e];return}this.observers[e].delete(n)}}emit(e,...n){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([r,c])=>{for(let u=0;u{for(let u=0;u-1&&this.options.ns.splice(n,1)}getResource(e,n,s,r={}){const c=r.keySeparator!==void 0?r.keySeparator:this.options.keySeparator,u=r.ignoreJSONStructure!==void 0?r.ignoreJSONStructure:this.options.ignoreJSONStructure;let m;e.indexOf(".")>-1?m=e.split("."):(m=[e,n],s&&(Array.isArray(s)?m.push(...s):_e(s)&&c?m.push(...s.split(c)):m.push(s)));const h=nr(this.data,m);return!h&&!n&&!s&&e.indexOf(".")>-1&&(e=m[0],n=m[1],s=m.slice(2).join(".")),h||!u||!_e(s)?h:jc(this.data?.[e]?.[n],s,c)}addResource(e,n,s,r,c={silent:!1}){const u=c.keySeparator!==void 0?c.keySeparator:this.options.keySeparator;let m=[e,n];s&&(m=m.concat(u?s.split(u):s)),e.indexOf(".")>-1&&(m=e.split("."),r=n,n=m[1]),this.addNamespaces(n),Tm(this.data,m,r),c.silent||this.emit("added",e,n,s,r)}addResources(e,n,s,r={silent:!1}){for(const c in s)(_e(s[c])||Array.isArray(s[c]))&&this.addResource(e,n,c,s[c],{silent:!0});r.silent||this.emit("added",e,n,s)}addResourceBundle(e,n,s,r,c,u={silent:!1,skipCopy:!1}){let m=[e,n];e.indexOf(".")>-1&&(m=e.split("."),r=s,s=n,n=m[1]),this.addNamespaces(n);let h=nr(this.data,m)||{};u.skipCopy||(s=JSON.parse(JSON.stringify(s))),r?jg(h,s,c):h={...h,...s},Tm(this.data,m,h),u.silent||this.emit("added",e,n,s)}removeResourceBundle(e,n){this.hasResourceBundle(e,n)&&delete this.data[e][n],this.removeNamespaces(n),this.emit("removed",e,n)}hasResourceBundle(e,n){return this.getResource(e,n)!==void 0}getResourceBundle(e,n){return n||(n=this.options.defaultNS),this.getResource(e,n)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const n=this.getDataByLanguage(e);return!!(n&&Object.keys(n)||[]).find(r=>n[r]&&Object.keys(n[r]).length>0)}toJSON(){return this.data}}var Eg={processors:{},addPostProcessor(i){this.processors[i.name]=i},handle(i,e,n,s,r){return i.forEach(c=>{e=this.processors[c]?.process(e,n,s,r)??e}),e}};const Lg=Symbol("i18next/PATH_KEY");function sw(){const i=[],e=Object.create(null);let n;return e.get=(s,r)=>(n?.revoke?.(),r===Lg?i:(i.push(r),n=Proxy.revocable(s,e),n.proxy)),Proxy.revocable(Object.create(null),e).proxy}function Lc(i,e){const{[Lg]:n}=i(sw());return n.join(e?.keySeparator??".")}const Fm={},hc=i=>!_e(i)&&typeof i!="boolean"&&typeof i!="number";class or extends hr{constructor(e,n={}){super(),Vy(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=n,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.logger=fn.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e,n={interpolation:{}}){const s={...n};if(e==null)return!1;const r=this.resolve(e,s);if(r?.res===void 0)return!1;const c=hc(r.res);return!(s.returnObjects===!1&&c)}extractFromKey(e,n){let s=n.nsSeparator!==void 0?n.nsSeparator:this.options.nsSeparator;s===void 0&&(s=":");const r=n.keySeparator!==void 0?n.keySeparator:this.options.keySeparator;let c=n.ns||this.options.defaultNS||[];const u=s&&e.indexOf(s)>-1,m=!this.options.userDefinedKeySeparator&&!n.keySeparator&&!this.options.userDefinedNsSeparator&&!n.nsSeparator&&!tw(e,s,r);if(u&&!m){const h=e.match(this.interpolator.nestingRegexp);if(h&&h.length>0)return{key:e,namespaces:_e(c)?[c]:c};const f=e.split(s);(s!==r||s===r&&this.options.ns.indexOf(f[0])>-1)&&(c=f.shift()),e=f.join(r)}return{key:e,namespaces:_e(c)?[c]:c}}translate(e,n,s){let r=typeof n=="object"?{...n}:n;if(typeof r!="object"&&this.options.overloadTranslationOptionHandler&&(r=this.options.overloadTranslationOptionHandler(arguments)),typeof r=="object"&&(r={...r}),r||(r={}),e==null)return"";typeof e=="function"&&(e=Lc(e,{...this.options,...r})),Array.isArray(e)||(e=[String(e)]);const c=r.returnDetails!==void 0?r.returnDetails:this.options.returnDetails,u=r.keySeparator!==void 0?r.keySeparator:this.options.keySeparator,{key:m,namespaces:h}=this.extractFromKey(e[e.length-1],r),f=h[h.length-1];let y=r.nsSeparator!==void 0?r.nsSeparator:this.options.nsSeparator;y===void 0&&(y=":");const v=r.lng||this.language,b=r.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(v?.toLowerCase()==="cimode")return b?c?{res:`${f}${y}${m}`,usedKey:m,exactUsedKey:m,usedLng:v,usedNS:f,usedParams:this.getUsedParamsDetails(r)}:`${f}${y}${m}`:c?{res:m,usedKey:m,exactUsedKey:m,usedLng:v,usedNS:f,usedParams:this.getUsedParamsDetails(r)}:m;const S=this.resolve(e,r);let A=S?.res;const F=S?.usedKey||m,_=S?.exactUsedKey||m,E=["[object Number]","[object Function]","[object RegExp]"],j=r.joinArrays!==void 0?r.joinArrays:this.options.joinArrays,z=!this.i18nFormat||this.i18nFormat.handleAsObject,B=r.count!==void 0&&!_e(r.count),W=or.hasDefaultValue(r),I=B?this.pluralResolver.getSuffix(v,r.count,r):"",ee=r.ordinal&&B?this.pluralResolver.getSuffix(v,r.count,{ordinal:!1}):"",oe=B&&!r.ordinal&&r.count===0,O=oe&&r[`defaultValue${this.options.pluralSeparator}zero`]||r[`defaultValue${I}`]||r[`defaultValue${ee}`]||r.defaultValue;let U=A;z&&!A&&W&&(U=O);const Z=hc(U),re=Object.prototype.toString.apply(U);if(z&&U&&Z&&E.indexOf(re)<0&&!(_e(j)&&Array.isArray(U))){if(!r.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const se=this.options.returnedObjectHandler?this.options.returnedObjectHandler(F,U,{...r,ns:h}):`key '${m} (${this.language})' returned an object instead of string.`;return c?(S.res=se,S.usedParams=this.getUsedParamsDetails(r),S):se}if(u){const se=Array.isArray(U),pe=se?[]:{},fe=se?_:F;for(const we in U)if(Object.prototype.hasOwnProperty.call(U,we)){const L=`${fe}${u}${we}`;W&&!A?pe[we]=this.translate(L,{...r,defaultValue:hc(O)?O[we]:void 0,joinArrays:!1,ns:h}):pe[we]=this.translate(L,{...r,joinArrays:!1,ns:h}),pe[we]===L&&(pe[we]=U[we])}A=pe}}else if(z&&_e(j)&&Array.isArray(A))A=A.join(j),A&&(A=this.extendTranslation(A,e,r,s));else{let se=!1,pe=!1;!this.isValidLookup(A)&&W&&(se=!0,A=O),this.isValidLookup(A)||(pe=!0,A=m);const we=(r.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&pe?void 0:A,L=W&&O!==A&&this.options.updateMissing;if(pe||se||L){if(this.logger.log(L?"updateKey":"missingKey",v,f,m,L?O:A),u){const C=this.resolve(m,{...r,keySeparator:!1});C&&C.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let $=[];const te=this.languageUtils.getFallbackCodes(this.options.fallbackLng,r.lng||this.language);if(this.options.saveMissingTo==="fallback"&&te&&te[0])for(let C=0;C{const ie=W&&X!==A?X:we;this.options.missingKeyHandler?this.options.missingKeyHandler(C,f,N,ie,L,r):this.backendConnector?.saveMissing&&this.backendConnector.saveMissing(C,f,N,ie,L,r),this.emit("missingKey",C,f,N,A)};this.options.saveMissing&&(this.options.saveMissingPlurals&&B?$.forEach(C=>{const N=this.pluralResolver.getSuffixes(C,r);oe&&r[`defaultValue${this.options.pluralSeparator}zero`]&&N.indexOf(`${this.options.pluralSeparator}zero`)<0&&N.push(`${this.options.pluralSeparator}zero`),N.forEach(X=>{G([C],m+X,r[`defaultValue${X}`]||O)})}):G($,m,O))}A=this.extendTranslation(A,e,r,S,s),pe&&A===m&&this.options.appendNamespaceToMissingKey&&(A=`${f}${y}${m}`),(pe||se)&&this.options.parseMissingKeyHandler&&(A=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${f}${y}${m}`:m,se?A:void 0,r))}return c?(S.res=A,S.usedParams=this.getUsedParamsDetails(r),S):A}extendTranslation(e,n,s,r,c){if(this.i18nFormat?.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...s},s.lng||this.language||r.usedLng,r.usedNS,r.usedKey,{resolved:r});else if(!s.skipInterpolation){s.interpolation&&this.interpolator.init({...s,interpolation:{...this.options.interpolation,...s.interpolation}});const h=_e(e)&&(s?.interpolation?.skipOnVariables!==void 0?s.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let f;if(h){const v=e.match(this.interpolator.nestingRegexp);f=v&&v.length}let y=s.replace&&!_e(s.replace)?s.replace:s;if(this.options.interpolation.defaultVariables&&(y={...this.options.interpolation.defaultVariables,...y}),e=this.interpolator.interpolate(e,y,s.lng||this.language||r.usedLng,s),h){const v=e.match(this.interpolator.nestingRegexp),b=v&&v.length;fc?.[0]===v[0]&&!s.context?(this.logger.warn(`It seems you are nesting recursively key: ${v[0]} in key: ${n[0]}`),null):this.translate(...v,n),s)),s.interpolation&&this.interpolator.reset()}const u=s.postProcess||this.options.postProcess,m=_e(u)?[u]:u;return e!=null&&m?.length&&s.applyPostProcessor!==!1&&(e=Eg.handle(m,e,n,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...r,usedParams:this.getUsedParamsDetails(s)},...s}:s,this)),e}resolve(e,n={}){let s,r,c,u,m;return _e(e)&&(e=[e]),e.forEach(h=>{if(this.isValidLookup(s))return;const f=this.extractFromKey(h,n),y=f.key;r=y;let v=f.namespaces;this.options.fallbackNS&&(v=v.concat(this.options.fallbackNS));const b=n.count!==void 0&&!_e(n.count),S=b&&!n.ordinal&&n.count===0,A=n.context!==void 0&&(_e(n.context)||typeof n.context=="number")&&n.context!=="",F=n.lngs?n.lngs:this.languageUtils.toResolveHierarchy(n.lng||this.language,n.fallbackLng);v.forEach(_=>{this.isValidLookup(s)||(m=_,!Fm[`${F[0]}-${_}`]&&this.utils?.hasLoadedNamespace&&!this.utils?.hasLoadedNamespace(m)&&(Fm[`${F[0]}-${_}`]=!0,this.logger.warn(`key "${r}" for languages "${F.join(", ")}" won't get resolved as namespace "${m}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),F.forEach(E=>{if(this.isValidLookup(s))return;u=E;const j=[y];if(this.i18nFormat?.addLookupKeys)this.i18nFormat.addLookupKeys(j,y,E,_,n);else{let B;b&&(B=this.pluralResolver.getSuffix(E,n.count,n));const W=`${this.options.pluralSeparator}zero`,I=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(b&&(n.ordinal&&B.indexOf(I)===0&&j.push(y+B.replace(I,this.options.pluralSeparator)),j.push(y+B),S&&j.push(y+W)),A){const ee=`${y}${this.options.contextSeparator||"_"}${n.context}`;j.push(ee),b&&(n.ordinal&&B.indexOf(I)===0&&j.push(ee+B.replace(I,this.options.pluralSeparator)),j.push(ee+B),S&&j.push(ee+W))}}let z;for(;z=j.pop();)this.isValidLookup(s)||(c=z,s=this.getResource(E,_,z,n))}))})}),{res:s,usedKey:r,exactUsedKey:c,usedLng:u,usedNS:m}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e==="")}getResource(e,n,s,r={}){return this.i18nFormat?.getResource?this.i18nFormat.getResource(e,n,s,r):this.resourceStore.getResource(e,n,s,r)}getUsedParamsDetails(e={}){const n=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],s=e.replace&&!_e(e.replace);let r=s?e.replace:e;if(s&&typeof e.count<"u"&&(r.count=e.count),this.options.interpolation.defaultVariables&&(r={...this.options.interpolation.defaultVariables,...r}),!s){r={...r};for(const c of n)delete r[c]}return r}static hasDefaultValue(e){const n="defaultValue";for(const s in e)if(Object.prototype.hasOwnProperty.call(e,s)&&n===s.substring(0,n.length)&&e[s]!==void 0)return!0;return!1}}class Rm{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=fn.create("languageUtils")}getScriptPartFromCode(e){if(e=Ai(e),!e||e.indexOf("-")<0)return null;const n=e.split("-");return n.length===2||(n.pop(),n[n.length-1].toLowerCase()==="x")?null:this.formatLanguageCode(n.join("-"))}getLanguagePartFromCode(e){if(e=Ai(e),!e||e.indexOf("-")<0)return e;const n=e.split("-");return this.formatLanguageCode(n[0])}formatLanguageCode(e){if(_e(e)&&e.indexOf("-")>-1){let n;try{n=Intl.getCanonicalLocales(e)[0]}catch{}return n&&this.options.lowerCaseLng&&(n=n.toLowerCase()),n||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load==="languageOnly"||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let n;return e.forEach(s=>{if(n)return;const r=this.formatLanguageCode(s);(!this.options.supportedLngs||this.isSupportedCode(r))&&(n=r)}),!n&&this.options.supportedLngs&&e.forEach(s=>{if(n)return;const r=this.getScriptPartFromCode(s);if(this.isSupportedCode(r))return n=r;const c=this.getLanguagePartFromCode(s);if(this.isSupportedCode(c))return n=c;n=this.options.supportedLngs.find(u=>{if(u===c)return u;if(!(u.indexOf("-")<0&&c.indexOf("-")<0)&&(u.indexOf("-")>0&&c.indexOf("-")<0&&u.substring(0,u.indexOf("-"))===c||u.indexOf(c)===0&&c.length>1))return u})}),n||(n=this.getFallbackCodes(this.options.fallbackLng)[0]),n}getFallbackCodes(e,n){if(!e)return[];if(typeof e=="function"&&(e=e(n)),_e(e)&&(e=[e]),Array.isArray(e))return e;if(!n)return e.default||[];let s=e[n];return s||(s=e[this.getScriptPartFromCode(n)]),s||(s=e[this.formatLanguageCode(n)]),s||(s=e[this.getLanguagePartFromCode(n)]),s||(s=e.default),s||[]}toResolveHierarchy(e,n){const s=this.getFallbackCodes((n===!1?[]:n)||this.options.fallbackLng||[],e),r=[],c=u=>{u&&(this.isSupportedCode(u)?r.push(u):this.logger.warn(`rejecting language code not found in supportedLngs: ${u}`))};return _e(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?(this.options.load!=="languageOnly"&&c(this.formatLanguageCode(e)),this.options.load!=="languageOnly"&&this.options.load!=="currentOnly"&&c(this.getScriptPartFromCode(e)),this.options.load!=="currentOnly"&&c(this.getLanguagePartFromCode(e))):_e(e)&&c(this.formatLanguageCode(e)),s.forEach(u=>{r.indexOf(u)<0&&c(this.formatLanguageCode(u))}),r}}const Nm={zero:0,one:1,two:2,few:3,many:4,other:5},Dm={select:i=>i===1?"one":"other",resolvedOptions:()=>({pluralCategories:["one","other"]})};class iw{constructor(e,n={}){this.languageUtils=e,this.options=n,this.logger=fn.create("pluralResolver"),this.pluralRulesCache={}}clearCache(){this.pluralRulesCache={}}getRule(e,n={}){const s=Ai(e==="dev"?"en":e),r=n.ordinal?"ordinal":"cardinal",c=JSON.stringify({cleanedCode:s,type:r});if(c in this.pluralRulesCache)return this.pluralRulesCache[c];let u;try{u=new Intl.PluralRules(s,{type:r})}catch{if(!Intl)return this.logger.error("No Intl support, please use an Intl polyfill!"),Dm;if(!e.match(/-|_/))return Dm;const h=this.languageUtils.getLanguagePartFromCode(e);u=this.getRule(h,n)}return this.pluralRulesCache[c]=u,u}needsPlural(e,n={}){let s=this.getRule(e,n);return s||(s=this.getRule("dev",n)),s?.resolvedOptions().pluralCategories.length>1}getPluralFormsOfKey(e,n,s={}){return this.getSuffixes(e,s).map(r=>`${n}${r}`)}getSuffixes(e,n={}){let s=this.getRule(e,n);return s||(s=this.getRule("dev",n)),s?s.resolvedOptions().pluralCategories.sort((r,c)=>Nm[r]-Nm[c]).map(r=>`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${r}`):[]}getSuffix(e,n,s={}){const r=this.getRule(e,s);return r?`${this.options.prepend}${s.ordinal?`ordinal${this.options.prepend}`:""}${r.select(n)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix("dev",n,s))}}const Im=(i,e,n,s=".",r=!0)=>{let c=Qy(i,e,n);return!c&&r&&_e(n)&&(c=jc(i,n,s),c===void 0&&(c=jc(e,n,s))),c},fc=i=>i.replace(/\$/g,"$$$$");class Mm{constructor(e={}){this.logger=fn.create("interpolator"),this.options=e,this.format=e?.interpolation?.format||(n=>n),this.init(e)}init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{escape:n,escapeValue:s,useRawValueToEscape:r,prefix:c,prefixEscaped:u,suffix:m,suffixEscaped:h,formatSeparator:f,unescapeSuffix:y,unescapePrefix:v,nestingPrefix:b,nestingPrefixEscaped:S,nestingSuffix:A,nestingSuffixEscaped:F,nestingOptionsSeparator:_,maxReplaces:E,alwaysFormat:j}=e.interpolation;this.escape=n!==void 0?n:Yy,this.escapeValue=s!==void 0?s:!0,this.useRawValueToEscape=r!==void 0?r:!1,this.prefix=c?ls(c):u||"{{",this.suffix=m?ls(m):h||"}}",this.formatSeparator=f||",",this.unescapePrefix=y?"":v||"-",this.unescapeSuffix=this.unescapePrefix?"":y||"",this.nestingPrefix=b?ls(b):S||ls("$t("),this.nestingSuffix=A?ls(A):F||ls(")"),this.nestingOptionsSeparator=_||",",this.maxReplaces=E||1e3,this.alwaysFormat=j!==void 0?j:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(n,s)=>n?.source===s?(n.lastIndex=0,n):new RegExp(s,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,n,s,r){let c,u,m;const h=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},f=S=>{if(S.indexOf(this.formatSeparator)<0){const E=Im(n,h,S,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(E,void 0,s,{...r,...n,interpolationkey:S}):E}const A=S.split(this.formatSeparator),F=A.shift().trim(),_=A.join(this.formatSeparator).trim();return this.format(Im(n,h,F,this.options.keySeparator,this.options.ignoreJSONStructure),_,s,{...r,...n,interpolationkey:F})};this.resetRegExp();const y=r?.missingInterpolationHandler||this.options.missingInterpolationHandler,v=r?.interpolation?.skipOnVariables!==void 0?r.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:S=>fc(S)},{regex:this.regexp,safeValue:S=>this.escapeValue?fc(this.escape(S)):fc(S)}].forEach(S=>{for(m=0;c=S.regex.exec(e);){const A=c[1].trim();if(u=f(A),u===void 0)if(typeof y=="function"){const _=y(e,c,r);u=_e(_)?_:""}else if(r&&Object.prototype.hasOwnProperty.call(r,A))u="";else if(v){u=c[0];continue}else this.logger.warn(`missed to pass in variable ${A} for interpolating ${e}`),u="";else!_e(u)&&!this.useRawValueToEscape&&(u=Cm(u));const F=S.safeValue(u);if(e=e.replace(c[0],F),v?(S.regex.lastIndex+=u.length,S.regex.lastIndex-=c[0].length):S.regex.lastIndex=0,m++,m>=this.maxReplaces)break}}),e}nest(e,n,s={}){let r,c,u;const m=(h,f)=>{const y=this.nestingOptionsSeparator;if(h.indexOf(y)<0)return h;const v=h.split(new RegExp(`${y}[ ]*{`));let b=`{${v[1]}`;h=v[0],b=this.interpolate(b,u);const S=b.match(/'/g),A=b.match(/"/g);((S?.length??0)%2===0&&!A||A.length%2!==0)&&(b=b.replace(/'/g,'"'));try{u=JSON.parse(b),f&&(u={...f,...u})}catch(F){return this.logger.warn(`failed parsing options string in nesting for key ${h}`,F),`${h}${y}${b}`}return u.defaultValue&&u.defaultValue.indexOf(this.prefix)>-1&&delete u.defaultValue,h};for(;r=this.nestingRegexp.exec(e);){let h=[];u={...s},u=u.replace&&!_e(u.replace)?u.replace:u,u.applyPostProcessor=!1,delete u.defaultValue;const f=/{.*}/.test(r[1])?r[1].lastIndexOf("}")+1:r[1].indexOf(this.formatSeparator);if(f!==-1&&(h=r[1].slice(f).split(this.formatSeparator).map(y=>y.trim()).filter(Boolean),r[1]=r[1].slice(0,f)),c=n(m.call(this,r[1].trim(),u),u),c&&r[0]===e&&!_e(c))return c;_e(c)||(c=Cm(c)),c||(this.logger.warn(`missed to resolve ${r[1]} for nesting ${e}`),c=""),h.length&&(c=h.reduce((y,v)=>this.format(y,v,s.lng,{...s,interpolationkey:r[1].trim()}),c.trim())),e=e.replace(r[0],c),this.regexp.lastIndex=0}return e}}const aw=i=>{let e=i.toLowerCase().trim();const n={};if(i.indexOf("(")>-1){const s=i.split("(");e=s[0].toLowerCase().trim();const r=s[1].substring(0,s[1].length-1);e==="currency"&&r.indexOf(":")<0?n.currency||(n.currency=r.trim()):e==="relativetime"&&r.indexOf(":")<0?n.range||(n.range=r.trim()):r.split(";").forEach(u=>{if(u){const[m,...h]=u.split(":"),f=h.join(":").trim().replace(/^'+|'+$/g,""),y=m.trim();n[y]||(n[y]=f),f==="false"&&(n[y]=!1),f==="true"&&(n[y]=!0),isNaN(f)||(n[y]=parseInt(f,10))}})}return{formatName:e,formatOptions:n}},jm=i=>{const e={};return(n,s,r)=>{let c=r;r&&r.interpolationkey&&r.formatParams&&r.formatParams[r.interpolationkey]&&r[r.interpolationkey]&&(c={...c,[r.interpolationkey]:void 0});const u=s+JSON.stringify(c);let m=e[u];return m||(m=i(Ai(s),r),e[u]=m),m(n)}},rw=i=>(e,n,s)=>i(Ai(n),s)(e);class lw{constructor(e={}){this.logger=fn.create("formatter"),this.options=e,this.init(e)}init(e,n={interpolation:{}}){this.formatSeparator=n.interpolation.formatSeparator||",";const s=n.cacheInBuiltFormats?jm:rw;this.formats={number:s((r,c)=>{const u=new Intl.NumberFormat(r,{...c});return m=>u.format(m)}),currency:s((r,c)=>{const u=new Intl.NumberFormat(r,{...c,style:"currency"});return m=>u.format(m)}),datetime:s((r,c)=>{const u=new Intl.DateTimeFormat(r,{...c});return m=>u.format(m)}),relativetime:s((r,c)=>{const u=new Intl.RelativeTimeFormat(r,{...c});return m=>u.format(m,c.range||"day")}),list:s((r,c)=>{const u=new Intl.ListFormat(r,{...c});return m=>u.format(m)})}}add(e,n){this.formats[e.toLowerCase().trim()]=n}addCached(e,n){this.formats[e.toLowerCase().trim()]=jm(n)}format(e,n,s,r={}){const c=n.split(this.formatSeparator);if(c.length>1&&c[0].indexOf("(")>1&&c[0].indexOf(")")<0&&c.find(m=>m.indexOf(")")>-1)){const m=c.findIndex(h=>h.indexOf(")")>-1);c[0]=[c[0],...c.splice(1,m)].join(this.formatSeparator)}return c.reduce((m,h)=>{const{formatName:f,formatOptions:y}=aw(h);if(this.formats[f]){let v=m;try{const b=r?.formatParams?.[r.interpolationkey]||{},S=b.locale||b.lng||r.locale||r.lng||s;v=this.formats[f](m,S,{...y,...r,...b})}catch(b){this.logger.warn(b)}return v}else this.logger.warn(`there was no format function for ${f}`);return m},e)}}const cw=(i,e)=>{i.pending[e]!==void 0&&(delete i.pending[e],i.pendingCount--)};class dw extends hr{constructor(e,n,s,r={}){super(),this.backend=e,this.store=n,this.services=s,this.languageUtils=s.languageUtils,this.options=r,this.logger=fn.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=r.maxParallelReads||10,this.readingCalls=0,this.maxRetries=r.maxRetries>=0?r.maxRetries:5,this.retryTimeout=r.retryTimeout>=1?r.retryTimeout:350,this.state={},this.queue=[],this.backend?.init?.(s,r.backend,r)}queueLoad(e,n,s,r){const c={},u={},m={},h={};return e.forEach(f=>{let y=!0;n.forEach(v=>{const b=`${f}|${v}`;!s.reload&&this.store.hasResourceBundle(f,v)?this.state[b]=2:this.state[b]<0||(this.state[b]===1?u[b]===void 0&&(u[b]=!0):(this.state[b]=1,y=!1,u[b]===void 0&&(u[b]=!0),c[b]===void 0&&(c[b]=!0),h[v]===void 0&&(h[v]=!0)))}),y||(m[f]=!0)}),(Object.keys(c).length||Object.keys(u).length)&&this.queue.push({pending:u,pendingCount:Object.keys(u).length,loaded:{},errors:[],callback:r}),{toLoad:Object.keys(c),pending:Object.keys(u),toLoadLanguages:Object.keys(m),toLoadNamespaces:Object.keys(h)}}loaded(e,n,s){const r=e.split("|"),c=r[0],u=r[1];n&&this.emit("failedLoading",c,u,n),!n&&s&&this.store.addResourceBundle(c,u,s,void 0,void 0,{skipCopy:!0}),this.state[e]=n?-1:2,n&&s&&(this.state[e]=0);const m={};this.queue.forEach(h=>{Ky(h.loaded,[c],u),cw(h,e),n&&h.errors.push(n),h.pendingCount===0&&!h.done&&(Object.keys(h.loaded).forEach(f=>{m[f]||(m[f]={});const y=h.loaded[f];y.length&&y.forEach(v=>{m[f][v]===void 0&&(m[f][v]=!0)})}),h.done=!0,h.errors.length?h.callback(h.errors):h.callback())}),this.emit("loaded",m),this.queue=this.queue.filter(h=>!h.done)}read(e,n,s,r=0,c=this.retryTimeout,u){if(!e.length)return u(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:n,fcName:s,tried:r,wait:c,callback:u});return}this.readingCalls++;const m=(f,y)=>{if(this.readingCalls--,this.waitingReads.length>0){const v=this.waitingReads.shift();this.read(v.lng,v.ns,v.fcName,v.tried,v.wait,v.callback)}if(f&&y&&r{this.read.call(this,e,n,s,r+1,c*2,u)},c);return}u(f,y)},h=this.backend[s].bind(this.backend);if(h.length===2){try{const f=h(e,n);f&&typeof f.then=="function"?f.then(y=>m(null,y)).catch(m):m(null,f)}catch(f){m(f)}return}return h(e,n,m)}prepareLoading(e,n,s={},r){if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),r&&r();_e(e)&&(e=this.languageUtils.toResolveHierarchy(e)),_e(n)&&(n=[n]);const c=this.queueLoad(e,n,s,r);if(!c.toLoad.length)return c.pending.length||r(),null;c.toLoad.forEach(u=>{this.loadOne(u)})}load(e,n,s){this.prepareLoading(e,n,{},s)}reload(e,n,s){this.prepareLoading(e,n,{reload:!0},s)}loadOne(e,n=""){const s=e.split("|"),r=s[0],c=s[1];this.read(r,c,"read",void 0,void 0,(u,m)=>{u&&this.logger.warn(`${n}loading namespace ${c} for language ${r} failed`,u),!u&&m&&this.logger.log(`${n}loaded namespace ${c} for language ${r}`,m),this.loaded(e,u,m)})}saveMissing(e,n,s,r,c,u={},m=()=>{}){if(this.services?.utils?.hasLoadedNamespace&&!this.services?.utils?.hasLoadedNamespace(n)){this.logger.warn(`did not save key "${s}" as the namespace "${n}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(!(s==null||s==="")){if(this.backend?.create){const h={...u,isUpdate:c},f=this.backend.create.bind(this.backend);if(f.length<6)try{let y;f.length===5?y=f(e,n,s,r,h):y=f(e,n,s,r),y&&typeof y.then=="function"?y.then(v=>m(null,v)).catch(m):m(null,y)}catch(y){m(y)}else f(e,n,s,r,m,h)}!e||!e[0]||this.store.addResource(e[0],n,s,r)}}}const yc=()=>({debug:!1,initAsync:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:i=>{let e={};if(typeof i[1]=="object"&&(e=i[1]),_e(i[1])&&(e.defaultValue=i[1]),_e(i[2])&&(e.tDescription=i[2]),typeof i[2]=="object"||typeof i[3]=="object"){const n=i[3]||i[2];Object.keys(n).forEach(s=>{e[s]=n[s]})}return e},interpolation:{escapeValue:!0,format:i=>i,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),Em=i=>(_e(i.ns)&&(i.ns=[i.ns]),_e(i.fallbackLng)&&(i.fallbackLng=[i.fallbackLng]),_e(i.fallbackNS)&&(i.fallbackNS=[i.fallbackNS]),i.supportedLngs?.indexOf?.("cimode")<0&&(i.supportedLngs=i.supportedLngs.concat(["cimode"])),typeof i.initImmediate=="boolean"&&(i.initAsync=i.initImmediate),i),Ua=()=>{},uw=i=>{Object.getOwnPropertyNames(Object.getPrototypeOf(i)).forEach(n=>{typeof i[n]=="function"&&(i[n]=i[n].bind(i))})};class vi extends hr{constructor(e={},n){if(super(),this.options=Em(e),this.services={},this.logger=fn,this.modules={external:[]},uw(this),n&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,n),this;setTimeout(()=>{this.init(e,n)},0)}}init(e={},n){this.isInitializing=!0,typeof e=="function"&&(n=e,e={}),e.defaultNS==null&&e.ns&&(_e(e.ns)?e.defaultNS=e.ns:e.ns.indexOf("translation")<0&&(e.defaultNS=e.ns[0]));const s=yc();this.options={...s,...this.options,...Em(e)},this.options.interpolation={...s.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator),typeof this.options.overloadTranslationOptionHandler!="function"&&(this.options.overloadTranslationOptionHandler=s.overloadTranslationOptionHandler),this.options.debug===!0&&typeof console<"u"&&console.warn("i18next is maintained with support from locize.com — consider powering your project with managed localization (AI, CDN, integrations): https://locize.com");const r=f=>f?typeof f=="function"?new f:f:null;if(!this.options.isClone){this.modules.logger?fn.init(r(this.modules.logger),this.options):fn.init(null,this.options);let f;this.modules.formatter?f=this.modules.formatter:f=lw;const y=new Rm(this.options);this.store=new Pm(this.options.resources,this.options);const v=this.services;v.logger=fn,v.resourceStore=this.store,v.languageUtils=y,v.pluralResolver=new iw(y,{prepend:this.options.pluralSeparator,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),this.options.interpolation.format&&this.options.interpolation.format!==s.interpolation.format&&this.logger.deprecate("init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting"),f&&(!this.options.interpolation.format||this.options.interpolation.format===s.interpolation.format)&&(v.formatter=r(f),v.formatter.init&&v.formatter.init(v,this.options),this.options.interpolation.format=v.formatter.format.bind(v.formatter)),v.interpolator=new Mm(this.options),v.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},v.backendConnector=new dw(r(this.modules.backend),v.resourceStore,v,this.options),v.backendConnector.on("*",(S,...A)=>{this.emit(S,...A)}),this.modules.languageDetector&&(v.languageDetector=r(this.modules.languageDetector),v.languageDetector.init&&v.languageDetector.init(v,this.options.detection,this.options)),this.modules.i18nFormat&&(v.i18nFormat=r(this.modules.i18nFormat),v.i18nFormat.init&&v.i18nFormat.init(this)),this.translator=new or(this.services,this.options),this.translator.on("*",(S,...A)=>{this.emit(S,...A)}),this.modules.external.forEach(S=>{S.init&&S.init(this)})}if(this.format=this.options.interpolation.format,n||(n=Ua),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const f=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);f.length>0&&f[0]!=="dev"&&(this.options.lng=f[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(f=>{this[f]=(...y)=>this.store[f](...y)}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(f=>{this[f]=(...y)=>(this.store[f](...y),this)});const m=ci(),h=()=>{const f=(y,v)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),m.resolve(v),n(y,v)};if(this.languages&&!this.isInitialized)return f(null,this.t.bind(this));this.changeLanguage(this.options.lng,f)};return this.options.resources||!this.options.initAsync?h():setTimeout(h,0),m}loadResources(e,n=Ua){let s=n;const r=_e(e)?e:this.language;if(typeof e=="function"&&(s=e),!this.options.resources||this.options.partialBundledLanguages){if(r?.toLowerCase()==="cimode"&&(!this.options.preload||this.options.preload.length===0))return s();const c=[],u=m=>{if(!m||m==="cimode")return;this.services.languageUtils.toResolveHierarchy(m).forEach(f=>{f!=="cimode"&&c.indexOf(f)<0&&c.push(f)})};r?u(r):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(h=>u(h)),this.options.preload?.forEach?.(m=>u(m)),this.services.backendConnector.load(c,this.options.ns,m=>{!m&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),s(m)})}else s(null)}reloadResources(e,n,s){const r=ci();return typeof e=="function"&&(s=e,e=void 0),typeof n=="function"&&(s=n,n=void 0),e||(e=this.languages),n||(n=this.options.ns),s||(s=Ua),this.services.backendConnector.reload(e,n,c=>{r.resolve(),s(c)}),r}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return e.type==="backend"&&(this.modules.backend=e),(e.type==="logger"||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type==="languageDetector"&&(this.modules.languageDetector=e),e.type==="i18nFormat"&&(this.modules.i18nFormat=e),e.type==="postProcessor"&&Eg.addPostProcessor(e),e.type==="formatter"&&(this.modules.formatter=e),e.type==="3rdParty"&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].indexOf(e)>-1)){for(let n=0;n-1)&&this.store.hasLanguageSomeTranslations(s)){this.resolvedLanguage=s;break}}!this.resolvedLanguage&&this.languages.indexOf(e)<0&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,n){this.isLanguageChangingTo=e;const s=ci();this.emit("languageChanging",e);const r=m=>{this.language=m,this.languages=this.services.languageUtils.toResolveHierarchy(m),this.resolvedLanguage=void 0,this.setResolvedLanguage(m)},c=(m,h)=>{h?this.isLanguageChangingTo===e&&(r(h),this.translator.changeLanguage(h),this.isLanguageChangingTo=void 0,this.emit("languageChanged",h),this.logger.log("languageChanged",h)):this.isLanguageChangingTo=void 0,s.resolve((...f)=>this.t(...f)),n&&n(m,(...f)=>this.t(...f))},u=m=>{!e&&!m&&this.services.languageDetector&&(m=[]);const h=_e(m)?m:m&&m[0],f=this.store.hasLanguageSomeTranslations(h)?h:this.services.languageUtils.getBestMatchFromCodes(_e(m)?[m]:m);f&&(this.language||r(f),this.translator.language||this.translator.changeLanguage(f),this.services.languageDetector?.cacheUserLanguage?.(f)),this.loadResources(f,y=>{c(y,f)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?u(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(u):this.services.languageDetector.detect(u):u(e),s}getFixedT(e,n,s){const r=(c,u,...m)=>{let h;typeof u!="object"?h=this.options.overloadTranslationOptionHandler([c,u].concat(m)):h={...u},h.lng=h.lng||r.lng,h.lngs=h.lngs||r.lngs,h.ns=h.ns||r.ns,h.keyPrefix!==""&&(h.keyPrefix=h.keyPrefix||s||r.keyPrefix);const f=this.options.keySeparator||".";let y;return h.keyPrefix&&Array.isArray(c)?y=c.map(v=>(typeof v=="function"&&(v=Lc(v,{...this.options,...u})),`${h.keyPrefix}${f}${v}`)):(typeof c=="function"&&(c=Lc(c,{...this.options,...u})),y=h.keyPrefix?`${h.keyPrefix}${f}${c}`:c),this.t(y,h)};return _e(e)?r.lng=e:r.lngs=e,r.ns=n,r.keyPrefix=s,r}t(...e){return this.translator?.translate(...e)}exists(...e){return this.translator?.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,n={}){if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const s=n.lng||this.resolvedLanguage||this.languages[0],r=this.options?this.options.fallbackLng:!1,c=this.languages[this.languages.length-1];if(s.toLowerCase()==="cimode")return!0;const u=(m,h)=>{const f=this.services.backendConnector.state[`${m}|${h}`];return f===-1||f===0||f===2};if(n.precheck){const m=n.precheck(this,u);if(m!==void 0)return m}return!!(this.hasResourceBundle(s,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||u(s,e)&&(!r||u(c,e)))}loadNamespaces(e,n){const s=ci();return this.options.ns?(_e(e)&&(e=[e]),e.forEach(r=>{this.options.ns.indexOf(r)<0&&this.options.ns.push(r)}),this.loadResources(r=>{s.resolve(),n&&n(r)}),s):(n&&n(),Promise.resolve())}loadLanguages(e,n){const s=ci();_e(e)&&(e=[e]);const r=this.options.preload||[],c=e.filter(u=>r.indexOf(u)<0&&this.services.languageUtils.isSupportedCode(u));return c.length?(this.options.preload=r.concat(c),this.loadResources(u=>{s.resolve(),n&&n(u)}),s):(n&&n(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages?.length>0?this.languages[0]:this.language)),!e)return"rtl";try{const r=new Intl.Locale(e);if(r&&r.getTextInfo){const c=r.getTextInfo();if(c&&c.direction)return c.direction}}catch{}const n=["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"],s=this.services?.languageUtils||new Rm(yc());return e.toLowerCase().indexOf("-latn")>1?"ltr":n.indexOf(s.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(e={},n){const s=new vi(e,n);return s.createInstance=vi.createInstance,s}cloneInstance(e={},n=Ua){const s=e.forkResourceStore;s&&delete e.forkResourceStore;const r={...this.options,...e,isClone:!0},c=new vi(r);if((e.debug!==void 0||e.prefix!==void 0)&&(c.logger=c.logger.clone(e)),["store","services","language"].forEach(m=>{c[m]=this[m]}),c.services={...this.services},c.services.utils={hasLoadedNamespace:c.hasLoadedNamespace.bind(c)},s){const m=Object.keys(this.store.data).reduce((h,f)=>(h[f]={...this.store.data[f]},h[f]=Object.keys(h[f]).reduce((y,v)=>(y[v]={...h[f][v]},y),h[f]),h),{});c.store=new Pm(m,r),c.services.resourceStore=c.store}if(e.interpolation){const h={...yc().interpolation,...this.options.interpolation,...e.interpolation},f={...r,interpolation:h};c.services.interpolator=new Mm(f)}return c.translator=new or(c.services,r),c.translator.on("*",(m,...h)=>{c.emit(m,...h)}),c.init(r,n),c.translator.options=r,c.translator.backendConnector.services.utils={hasLoadedNamespace:c.hasLoadedNamespace.bind(c)},c}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const vt=vi.createInstance();vt.createInstance;vt.dir;vt.init;vt.loadResources;vt.reloadResources;vt.use;vt.changeLanguage;vt.getFixedT;vt.t;vt.exists;vt.setDefaultNamespace;vt.hasLoadedNamespace;vt.loadNamespaces;vt.loadLanguages;const pw=(i,e,n,s)=>{const r=[n,{code:e,...s||{}}];if(i?.services?.logger?.forward)return i.services.logger.forward(r,"warn","react-i18next::",!0);Ro(r[0])&&(r[0]=`react-i18next:: ${r[0]}`),i?.services?.logger?.warn?i.services.logger.warn(...r):console?.warn&&console.warn(...r)},Lm={},$g=(i,e,n,s)=>{Ro(n)&&Lm[n]||(Ro(n)&&(Lm[n]=new Date),pw(i,e,n,s))},Og=(i,e)=>()=>{if(i.isInitialized)e();else{const n=()=>{setTimeout(()=>{i.off("initialized",n)},0),e()};i.on("initialized",n)}},$c=(i,e,n)=>{i.loadNamespaces(e,Og(i,n))},$m=(i,e,n,s)=>{if(Ro(n)&&(n=[n]),i.options.preload&&i.options.preload.indexOf(e)>-1)return $c(i,n,s);n.forEach(r=>{i.options.ns.indexOf(r)<0&&i.options.ns.push(r)}),i.loadLanguages(e,Og(i,s))},mw=(i,e,n={})=>!e.languages||!e.languages.length?($g(e,"NO_LANGUAGES","i18n.languages were undefined or empty",{languages:e.languages}),!0):e.hasLoadedNamespace(i,{lng:n.lng,precheck:(s,r)=>{if(n.bindI18n&&n.bindI18n.indexOf("languageChanging")>-1&&s.services.backendConnector.backend&&s.isLanguageChangingTo&&!r(s.isLanguageChangingTo,i))return!1}}),Ro=i=>typeof i=="string",gw=i=>typeof i=="object"&&i!==null,hw=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,fw={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},yw=i=>fw[i],ww=i=>i.replace(hw,yw);let Oc={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:ww,transDefaultProps:void 0};const vw=(i={})=>{Oc={...Oc,...i}},bw=()=>Oc;let Bg;const kw=i=>{Bg=i},Sw=()=>Bg,xw={type:"3rdParty",init(i){vw(i.options.react),kw(i)}},Wg=k.createContext();class Cw{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach(n=>{this.usedNamespaces[n]||(this.usedNamespaces[n]=!0)})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}var wc={exports:{}},vc={};var Om;function Aw(){if(Om)return vc;Om=1;var i=gr();function e(v,b){return v===b&&(v!==0||1/v===1/b)||v!==v&&b!==b}var n=typeof Object.is=="function"?Object.is:e,s=i.useState,r=i.useEffect,c=i.useLayoutEffect,u=i.useDebugValue;function m(v,b){var S=b(),A=s({inst:{value:S,getSnapshot:b}}),F=A[0].inst,_=A[1];return c(function(){F.value=S,F.getSnapshot=b,h(F)&&_({inst:F})},[v,S,b]),r(function(){return h(F)&&_({inst:F}),v(function(){h(F)&&_({inst:F})})},[v]),u(S),S}function h(v){var b=v.getSnapshot;v=v.value;try{var S=b();return!n(v,S)}catch{return!0}}function f(v,b){return b()}var y=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?f:m;return vc.useSyncExternalStore=i.useSyncExternalStore!==void 0?i.useSyncExternalStore:y,vc}var Bm;function _w(){return Bm||(Bm=1,wc.exports=Aw()),wc.exports}var Tw=_w();const Pw=(i,e)=>Ro(e)?e:gw(e)&&Ro(e.defaultValue)?e.defaultValue:Array.isArray(i)?i[i.length-1]:i,Fw={t:Pw,ready:!1},Rw=()=>()=>{},on=(i,e={})=>{const{i18n:n}=e,{i18n:s,defaultNS:r}=k.useContext(Wg)||{},c=n||s||Sw();c&&!c.reportNamespaces&&(c.reportNamespaces=new Cw),c||$g(c,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const u=k.useMemo(()=>({...bw(),...c?.options?.react,...e}),[c,e]),{useSuspense:m,keyPrefix:h}=u,f=i||r||c?.options?.defaultNS,y=Ro(f)?[f]:f||["translation"],v=k.useMemo(()=>y,y);c?.reportNamespaces?.addUsedNamespaces?.(v);const b=k.useRef(0),S=k.useCallback(O=>{if(!c)return Rw;const{bindI18n:U,bindI18nStore:Z}=u,re=()=>{b.current+=1,O()};return U&&c.on(U,re),Z&&c.store.on(Z,re),()=>{U&&U.split(" ").forEach(se=>c.off(se,re)),Z&&Z.split(" ").forEach(se=>c.store.off(se,re))}},[c,u]),A=k.useRef(),F=k.useCallback(()=>{if(!c)return Fw;const O=!!(c.isInitialized||c.initializedStoreOnce)&&v.every(fe=>mw(fe,c,u)),U=e.lng||c.language,Z=b.current,re=A.current;if(re&&re.ready===O&&re.lng===U&&re.keyPrefix===h&&re.revision===Z)return re;const pe={t:c.getFixedT(U,u.nsMode==="fallback"?v:v[0],h),ready:O,lng:U,keyPrefix:h,revision:Z};return A.current=pe,pe},[c,v,h,u,e.lng]),[_,E]=k.useState(0),{t:j,ready:z}=Tw.useSyncExternalStore(S,F,F);k.useEffect(()=>{if(c&&!z&&!m){const O=()=>E(U=>U+1);e.lng?$m(c,e.lng,v,O):$c(c,v,O)}},[c,e.lng,v,z,m,_]);const B=c||{},W=k.useRef(null),I=k.useRef(),ee=O=>{const U=Object.getOwnPropertyDescriptors(O);U.__original&&delete U.__original;const Z=Object.create(Object.getPrototypeOf(O),U);if(!Object.prototype.hasOwnProperty.call(Z,"__original"))try{Object.defineProperty(Z,"__original",{value:O,writable:!1,enumerable:!1,configurable:!1})}catch{}return Z},oe=k.useMemo(()=>{const O=B,U=O?.language;let Z=O;O&&(W.current&&W.current.__original===O?I.current!==U?(Z=ee(O),W.current=Z,I.current=U):Z=W.current:(Z=ee(O),W.current=Z,I.current=U));const re=[j,Z,z];return re.t=j,re.i18n=Z,re.ready=z,re},[j,B,z,B.resolvedLanguage,B.language,B.languages]);if(c&&m&&!z)throw new Promise(O=>{const U=()=>O();e.lng?$m(c,e.lng,v,U):$c(c,v,U)});return oe};function zg({i18n:i,defaultNS:e,children:n}){const s=k.useMemo(()=>({i18n:i,defaultNS:e}),[i,e]);return k.createElement(Wg.Provider,{value:s},n)}const Nw={name:"Sparo OS",version:"Version",loading:"Loading...",welcome:"Welcome to Sparo OS"},Dw={general:{name:"General Assistant",description:"General AI assistant that can answer a wide range of questions"},runno:{name:"Runno",description:"Native general execution agent for planning, automation, implementation, and verification"},coder:{name:"BitFun Coder",description:"Professional coding Product App for implementation, debugging, automation, verification, and handoff"},bitfunCoder:{name:"BitFun Coder",description:"Professional coding Product App for implementation, debugging, automation, verification, and handoff"},projectQa:{name:"Project QA Agent",description:"Project assistant focused on Q&A and codebase exploration"},requirementClarification:{name:"Requirement Clarification Agent",description:"Agent focused on clarifying requirements and gathering details"},core:{name:"Core Agent",description:"Core assistant for general tasks and coordination"}},Iw={initializing:"Initializing core systems..."},Mw={clarificationItemTitle:"Clarification {{index}}",clarificationItemProcessed:"Processed",clarificationBatchCompleted:"Clarification batch completed"},jw={minimize:"Minimize",maximize:"Maximize",restore:"Restore",close:"Close"},Ew={title:"New Project",subtitle:"Create a new workspace directory",parentDirectory:"Parent Directory",parentDirectoryPlaceholder:"Click the button to select parent directory",selectParentDirectory:"Select parent directory for new project",select:"Select",projectName:"Project Name",projectNamePlaceholder:"Enter project name, e.g.: my-project",fullPath:"Full Path",cancel:"Cancel",create:"Create",creating:"Creating...",errorSelectParent:"Please select a parent directory",errorEnterName:"Please enter a project name",errorCreateFailed:"Failed to create project"},Lw={productTitle:"Sparo OS",tagline:"An Agentic OS for building intelligent apps",close:"Close",copy:"Copy",copyDiagnostics:"Copy build info",copied:"Copied",version:"v{{version}}",specSheetTitle:"Build info",buildDate:"Built",commit:"Commit",branch:"Branch",links:{repository:"View source",documentation:"Documentation",issues:"Report an issue"},licenseLabel:"{{type}} License",copyright:"© 2026 Sparo OS Development Team. All rights reserved."},$w={confirm:"Confirm",cancel:"Cancel",save:"Save",delete:"Delete",edit:"Edit",create:"Create",new:"New",add:"Add",remove:"Remove",close:"Close",open:"Open",copy:"Copy",paste:"Paste",cut:"Cut",undo:"Undo",redo:"Redo",refresh:"Refresh",reload:"Reload",search:"Search",filter:"Filter",sort:"Sort",export:"Export",import:"Import",download:"Download",upload:"Upload",submit:"Submit",reset:"Reset",clear:"Clear",select:"Select",selectAll:"Select All",deselectAll:"Deselect All",expand:"Expand",collapse:"Collapse",more:"More",less:"Less",yes:"Yes",no:"No",ok:"OK",apply:"Apply",back:"Back",next:"Next",previous:"Previous",finish:"Finish",skip:"Skip",retry:"Retry",continue:"Continue",stop:"Stop",pause:"Pause",resume:"Resume",start:"Start",end:"End"},Ow={descriptions:{copy:"Copy selected content to clipboard",cut:"Cut selected content to clipboard",paste:"Paste content from clipboard",selectAll:"Select all content",refresh:"Refresh current content",delete:"Delete file or folder",copyPath:"Copy the full path of the file or folder",copyRelativePath:"Copy the path relative to the workspace"},status:{copySuccess:"Copied to clipboard",cutSuccess:"Cut to clipboard",pasteSuccess:"Pasted",selectAllSuccess:"Selected all",refreshTriggered:"Refresh triggered",deleteSuccess:"Deleted",copyPathSuccess:"Path copied to clipboard",copyRelativePathSuccess:"Relative path copied to clipboard"},confirmDeleteFile:'Are you sure you want to delete file "{{name}}"?',confirmDeleteFolder:'Are you sure you want to delete folder "{{name}}" and all its contents?',selectionMenu:{name:"Selection Menu",description:"Provides text selection actions"},terminalMenu:{name:"Terminal Menu",description:"Provides terminal actions",clearTerminal:"Clear Terminal"},editorMenu:{name:"Editor Menu",description:"Provides editor-related actions"},fileExplorerMenu:{name:"File Explorer Menu",description:"Provides file and folder actions"},flowChatMenu:{name:"FlowChat Menu",description:"Provides FlowChat conversation actions"},notificationMenu:{name:"Notification Menu",description:"Context menu for notifications",items:{copyTitle:"Copy Title",copyMessage:"Copy Message",copyAll:"Copy All"}},globalMenu:{name:"Global Menu",description:"Provides global common menu items"},projectContextDocumentMenu:{name:"Project Context Document Menu",description:"Provides deletion for project context documents"}},Bw={loading:"Loading",saving:"Saving",saved:"Saved",unsaved:"Unsaved",success:"Success",error:"Error",warning:"Warning",info:"Info",pending:"Pending",processing:"Processing",completed:"Completed",failed:"Failed",cancelled:"Cancelled",interrupted:"Interrupted",active:"Active",inactive:"Inactive",enabled:"Enabled",disabled:"Disabled",online:"Online",offline:"Offline",connected:"Connected",disconnected:"Disconnected",ready:"Ready",notReady:"Not Ready"},Ww={validationSuccess:{checkbox:"Setting looks good",input:"Input looks good",select:"Selection looks good"}},zw={now:"Now",today:"Today",yesterday:"Yesterday",tomorrow:"Tomorrow",thisWeek:"This Week",lastWeek:"Last Week",nextWeek:"Next Week",thisMonth:"This Month",lastMonth:"Last Month",nextMonth:"Next Month",thisYear:"This Year",lastYear:"Last Year",nextYear:"Next Year",second:"second",seconds:"seconds",minute:"minute",minutes:"minutes",hour:"hour",hours:"hours",day:"day",days:"days",week:"week",weeks:"weeks",month:"month",months:"months",year:"year",years:"years",ago:"ago",later:"later",just_now:"just now",minutesAgo:"{{count}} minutes ago",hoursAgo:"{{count}} hours ago",daysAgo:"{{count}} days ago",monthsAgo:"{{count}} months ago",yearsAgo:"{{count}} years ago"},Uw={file:"File",files:"Files",folder:"Folder",folders:"Folders",newFile:"New File",newFolder:"New Folder",rename:"Rename",delete:"Delete",copy:"Copy",cut:"Cut",paste:"Paste",duplicate:"Duplicate",move:"Move",openWith:"Open With",reveal:"Reveal in Explorer",copyPath:"Copy Path",copyRelativePath:"Copy Relative Path",download:"Download",downloadSaveTitle:"Save file as",transferNeedsDesktop:"Upload and download require the desktop app.",newFileDescription:"Create a new file in the current folder",newFolderDescription:"Create a new folder in the current folder",renameDescription:"Rename a file or folder",revealDescription:"Open this location in the system file manager",createFileSuccess:"Created new file",createFolderSuccess:"Created new folder",renameStarted:"Rename started",revealOpening:"Opening file manager",compressedPathTooltip:`Compressed path: {{compressed}} +Full path: {{full}}`},Hw={formatDocument:"Format Document",goToDefinition:"Go to Definition",goToTypeDefinition:"Go to Type Definition",findAllReferences:"Find All References",renameSymbol:"Rename Symbol",quickFix:"Quick Fix...",goToSymbol:"Go to Symbol...",highlightAllOccurrences:"Highlight All Occurrences",addToChat:"Add to Chat"},qw={delete:"Delete Document"},Vw={noData:"No Data",noResults:"No Results",noFiles:"No Files",noContent:"No Content"},Gw={required:"This field is required",invalid:"Invalid input",tooShort:"Input is too short",tooLong:"Input is too long",invalidEmail:"Invalid email format",invalidUrl:"Invalid URL format",invalidNumber:"Invalid number format",minLength:"Minimum {{min}} characters",maxLength:"Maximum {{max}} characters",minValue:"Minimum value is {{min}}",maxValue:"Maximum value is {{max}}",password:{minLength:"Password must be at least {{min}} characters",lowercase:"Include at least one lowercase letter",uppercase:"Include at least one uppercase letter",number:"Include at least one number",specialCharSuggested:"Consider adding a special character"}},Kw={subtitle:"Hi, what can I help you with today?",greetingMorning:"Good morning, ready to get started?",greetingAfternoon:"Good afternoon, let's keep things moving",greetingEvening:"Good evening, how can I help you?",continueLastWork:"Continue Where We Left Off",openFolder:"Start a New Task",selecting:"Selecting...",recentlyOpened:"Recent Projects",projects:"projects",collapse:"Collapse",showMore:"Show More ({{count}})",noProjectsYet:"No projects opened yet",startYourJourney:"Pick a project folder and I'll take it from there",selectWorkspaceDirectory:"Select Project Directory",pathNotExist:"Path does not exist",invalidWorkspacePath:"Workspace path is invalid or empty",daysAgo:"{{count}} days ago",weeksAgo:"{{count}} weeks ago",unknownTime:"Unknown time"},Qw={configCenter:"Config Center",diff:"Diff",fixPreview:"Fix Preview",gitDiff:"Git Diff",gitSettings:"Git Settings",taskPlanner:"Task Planner",fileBrowser:"File Browser",editor:"Editor",markdown:"Markdown",mermaidChart:"Mermaid Chart",settings:"Settings",settingsWithSection:"Settings - {{section}}"},Jw={greetingMorning:"Good morning, creator",greetingAfternoon:"Welcome back — let's build",greetingEvening:"Good Evening, Creator",greetingNight:"Hello Night Owl, Code Poet",subtitleMorning:`"A new day, new possibilities. Let's create something amazing."`,subtitleAfternoon:'"Here, AI is not a tool, but your intelligent companion. Thoughts flow like water, ideas become reality instantly."',subtitleEvening:'"Golden coding hours. Let your inspiration shine in the twilight."',subtitleNight:'"In the quiet of night, creation awaits. Where AI meets IDE, Magic happens."',featureIntro:"I can help you understand complex code, quickly implement new features, refactor legacy projects, or solve those frustrating bugs...",featureIntroCowork:"I can help organize your desktop, gather information, and create PPT and PDF documents...",lastTimeYouWere:"I remember when you left, you were at...",branch:"Branch: ",aheadCommits:"{{count}} commits ahead",behindCommits:"{{count}} commits behind",unstagedFiles:"{{count}} unstaged files",stagedFiles:"{{count}} staged files",unpushedCommits:"{{count}} unpushed commits",timeSinceLastCommit:"Time since last commit: ",youMightWant:"You might want to...",defaultAction1:"View current code changes",defaultAction1Command:"Show me what files I've modified",defaultAction2:"Continue development work",defaultAction2Command:"Help me continue coding",defaultAction3:"Commit current changes",defaultAction3Command:"Help me commit my code"},Yw={aiAgent:"Session",terminal:"Terminal",git:"Git",settings:"Settings",fileViewer:"Files",fileViewerCollapseNav:"Collapse file navigation",fileViewerExpandNav:"Expand file navigation",memory:"Memory",projectContext:"Profile",apps:"Apps",subagents:"Subagents",skills:"Skills",tools:"Tools",mermaidEditor:"Mermaid",shell:"Shell",panelView:"Panel View",workCenter:"Work Center",dailyLetter:"Daily Letter"},Zw={returnToAgenticOS:"Return to Agentic OS"},Xw={scenes:"Loading scene"},ev={remote:{title:"Remote SSH",connect:"Connect Remote Project",connecting:"Connecting...",connected:"Connected",disconnect:"Disconnect",savedConnections:"Saved Connections",sshConfigHosts:"SSH Config",fillForm:"Use",newConnection:"New Connection",host:"Host",port:"Port",username:"Username",connectionName:"Connection Name",connectionNamePlaceholder:"Leave empty to auto-generate",authMethod:"Authentication Method",password:"Password",privateKey:"Private Key",privateKeyPath:"Private Key Path",browsePrivateKey:"Choose private key file",pickPrivateKeyDialogTitle:"Select SSH private key",passphrase:"Passphrase",passphraseOptional:"Leave empty if none",homeFolder:"Home folder",clickToEditPath:"Click to edit path",selectWorkspace:"Select Workspace Directory",openWorkspace:"Open as Workspace",selected:"Selected",clickToSelect:"Click to select a directory",name:"Name",size:"Size",modified:"Modified",emptyDirectory:"Directory is empty",hostRequired:"Host is required",usernameRequired:"Username is required",portInvalid:"Port must be a number between 1 and 65535",passwordRequired:"Password is required",keyPathRequired:"Private key path is required",enterPassword:"Enter Password",enterKeyPath:"Enter Private Key Path",keyPathDescription:"Enter the private key file path",authPromptTitle:"SSH authentication",disconnectConfirm:"Are you sure you want to disconnect?",disconnectWorkspaceConfirm:"Are you sure you want to close the remote workspace? This will disconnect from the remote server.",newFile:"New File",newFolder:"New Folder",delete:"Delete",deleteTitle:"Confirm Delete",deleteConfirm:"Are you sure you want to delete this file/folder? This action cannot be undone.",rename:"Rename",upload:"Upload to remote",download:"Download to local",uploadDialogTitle:"Select files to upload",downloadDialogTitle:"Save file as",transferFailed:"Transfer failed",transferNeedsDesktop:"Upload and download require the desktop app.",transferring:"Transferring..."}},tv={dialogCompleted:"AI agent has finished the task."},nv={classify:{label:"Classification",immediate:"Immediate",topic:"Topic",tracking:"Tracking",recurring:"Recurring"}},ov={app:Nw,agents:Dw,core:Iw,agentService:Mw,window:jw,newProject:Ew,about:Lw,actions:$w,contextMenu:Ow,status:Bw,form:Ww,time:zw,file:Uw,editor:Hw,document:qw,empty:Vw,validation:Gw,startup:Kw,tabs:Qw,welcome:Jw,scenes:Yw,overlay:Zw,loading:Xw,ssh:ev,notify:tv,newWork:nv},sv={primary:"Primary",secondary:"Secondary",danger:"Danger",ghost:"Ghost"},iv={placeholder:"Enter...",clear:"Clear",show:"Show",hide:"Hide"},av={placeholder:"Select",noOptions:"No options",loading:"Loading...",search:"Search...",emptyText:"No data",selectAll:"Select All",customValueHint:"Press Enter to use custom value",useCustomValue:'Use "{{value}}"'},rv={decrease:"Decrease",increase:"Increase"},lv={exitFullscreen:"Exit fullscreen",exitFullscreenHint:"Exit fullscreen (ESC)",enterFullscreen:"Fullscreen preview"},cv={emptyError:"This field cannot be empty"},dv={copySuccess:"Copied",copyCode:"Copy code",resizeColumn:"Resize column {{index}}",resetColumnWidths:"Double-click or press Enter to reset column widths"},uv={renderFailed:"Diagram render failed",codeIncomplete:"Code incomplete, waiting for more content...",rendering:"Rendering diagram...",openInEditor:"Open in editor",showCode:"Show source",hideCode:"Hide source",copyCode:"Copy code"},pv={completedTitle:"Reproduction steps completed",instructionTitle:"Follow these steps to reproduce the issue",continueButton:"Continue",processing:"Processing...",notified:"AI has been notified to analyze logs, please wait...",instruction:"After completing the above steps, click the button below to let AI continue analyzing logs",userCompleted:"[User completed reproduction] Please collect and analyze logs immediately.",userCompletedShort:"User completed reproduction",operationFailed:"Operation failed, please retry"},mv={todoCard:{title:"Task Management",description:"Manage task list",total:"Total",inProgress:"In Progress",completed:"Completed",noTasks:"No tasks",taskCount:"{{total}} tasks / {{completed}} completed"},webSearchCard:{searchTitle:"Web Search",fetchTitle:"Fetch URL",searchQuery:"Search Query",url:"URL",results:"Search Results",resultsCount:"{{count}} results",resultCount:"Results",noResults:"No results found",searching:"Searching...",searchDesc:"Search web content",fetchDesc:"Fetch web URL content",unspecifiedQuery:"Unspecified query"},snapshotCard:{writeFile:"Write File",editFile:"Edit File",deleteFile:"Delete File",multiEdit:"Multi Edit",accept:"Accept changes",reject:"Reject changes",viewDetails:"View details",viewFullDiff:"View full diff",processing:"Processing file...",linesAdded:"lines added",linesDeleted:"lines deleted",filesCount:"{{count}} files",filePath:"File path",unspecifiedFile:"Unspecified file",file:"File"},taskCard:{title:"Execute Task",description:"Execute specialized AI task",taskType:"Task Type",taskDesc:"Task Description",result:"Task Result",processing:"AI is processing task...",defaultType:"AI Task",unspecifiedTask:"Unspecified task"},searchCard:{grepTitle:"Text Search",globTitle:"File Search",grepDesc:"Search text in files",globDesc:"Search files by pattern",pattern:"Search Pattern",path:"Search Path",matches:"matches",files:"files",matchingFiles:"Matching Files",noTextMatch:"No matching text found",noFileMatch:"No matching files found",unspecifiedPattern:"Unspecified pattern",currentDir:"Current directory",matchCount:"{{count}} occurrences"},contextCompressionCard:{title:"Context Compression",description:"Optimize conversation context to save tokens",compressing:"Compressing context...",analyzing:"Analyzing and compressing context...",triggerBeforeUserMessage:"Before user message",triggerAfterToolBatch:"After tool batch",triggerAfterAiResponse:"After AI response",triggerManual:"Manual trigger",triggerAuto:"Auto trigger",triggerTime:"Trigger: {{trigger}} 路 #{{count}}",duration:"Duration",savedTokens:"Saved {{count}} tokens 路 Ratio {{ratio}}%"},toolConfig:{read:{displayName:"Read File",description:"Read the content of a specified file"},write:{displayName:"Write File",description:"Write or create a file"},edit:{displayName:"Edit File",description:"Edit file content"},delete:{displayName:"Delete File",description:"Delete a specified file"},grep:{displayName:"Text Search",description:"Search text in files"},glob:{displayName:"File Search",description:"Search files by pattern"},webSearch:{displayName:"Web Search",description:"Search web content"},webFetch:{displayName:"Fetch URL",description:"Fetch content from URL"},task:{displayName:"Execute Task",description:"Execute specialized AI tasks"},todoWrite:{displayName:"Task Management",description:"Manage task list"},contextCompression:{displayName:"Context Compression",description:"Intelligently compress conversation context"},default:{description:"Execute {{toolName}} tool"}},baseToolCard:{awaitingConfirmation:"Awaiting confirmation",analyzing:"Analyzing parameters...",running:"Running...",completed:"Completed",cancelled:"Cancelled",failed:"Execution failed",preparing:"Preparing",inputParams:"Input parameters:",confirm:"Confirm",cancel:"Cancel",result:"Result:",viewDetails:"View details"}},gv={alertDemo:{title:"Alert Messages",subtitle:"Minimal alert component",sections:{basic:"Basic Types",withTitle:"With Title",withDescription:"With Description",closable:"Closable",noIcon:"No Icon"},messages:{operationSuccess:"Operation completed successfully",operationFailed:"Operation failed. Please try again.",operationRisk:"This operation carries risk.",infoMessage:"This is an informational message.",deploySuccessTitle:"Deployment succeeded",deploySuccessMessage:"The application was deployed to production.",deployFailedTitle:"Deployment failed",deployFailedMessage:"An error occurred during deployment.",expiringTitle:"Expiring soon",expiringMessage:"Your subscription expires in 7 days.",expiringDescription:"Renew in time to avoid service interruption.",updateTitle:"Version update",updateMessage:"A new version v3.0.0 is available.",updateDescription:"Includes performance improvements and new features.",closableMessage:"Click the button on the right to close this alert.",closableInfoTitle:"Notice",closableInfoMessage:"This alert can also be closed.",noIconMessage:"This is an alert without an icon."}},iconButtonExample:{title:"IconButton Examples",sections:{basic:"Basic style (Default) - transparent background, shows a fill on hover",ghost:"Ghost style - same as Default",primary:"Primary emphasis button - uses CSS variables",shape:"Shape variants - circle",other:"Other variants",usage:"Usage notes"},usage:{defaultGhost:{label:"default/ghost: ",text:"transparent background, shows a fill on hover; suitable for low-priority actions"},primary:{label:"primary: ",text:"emphasis button using the same CSS variables as text buttons; suitable for high-priority actions"},disabled:{label:"disabled: ",text:"use the disabled attribute; opacity is reduced to 0.5"},theme:{label:"theme support: ",text:"the primary variant supports theming via CSS variables"}}},previewApp:{title:"Sparo OS Design System",emptyState:"Select an entry on the left to view design-system guidance",navigationTitle:"Design system",collapseNavigation:"Collapse navigation",expandNavigation:"Expand navigation",theme:{label:"Theme",light:"Light",dark:"Dark",lightDescription:"Light theme",darkDescription:"Dark theme"},tiers:{primitive:"Primitive",pattern:"Pattern",recipe:"Recipe"}},usageGuide:{label:"AI usage guide",recipeLabel:"Recipe",useWhen:"Use when",composeWith:"Compose with",avoid:"Avoid",states:"Preview states"},layouts:{quickJump:"Quick Jump",previewLabel:"Preview",idLabel:"ID:"},markdownPreview:{title:"Markdown Preview",badge:"Content Component",backToLibrary:"鈫?Back to component library",controls:{variantLabel:"Style variant:",modeLabel:"Mode:",preview:"Preview",edit:"Edit",reset:"Reset content"},variants:{default:"Default",bordered:"Bordered",minimal:"Minimal"},editorPlaceholder:"Enter Markdown content here...",sample:`# Markdown Component Full Preview + +Welcome to the Sparo OS Markdown component preview page! + +## Basic Syntax + +### Text Styles + +This is **bold text**, this is *italic text*, and this is ~~strikethrough~~. + +You can also combine styles, like ***bold italic***. + +### Lists + +#### Unordered list + +- Item 1 +- Item 2 + - Subitem 2.1 + - Subitem 2.2 +- Item 3 + +#### Ordered list + +1. Step one +2. Step two +3. Step three + +#### Task list + +- [x] Completed task +- [ ] Pending task +- [ ] Another task + +## Code Examples + +### Inline code + +Run \`npm install\` to install dependencies, then run \`npm run dev\` to start the dev server. + +### Code blocks + +\`\`\`typescript +interface User { + id: string; + name: string; + email: string; +} + +function greetUser(user: User): string { + return \`Hello, \${user.name}!\`; +} + +const user: User = { + id: '1', + name: 'Alice', + email: 'alice@example.com' +}; + +console.log(greetUser(user)); +\`\`\` + +\`\`\`javascript +// JavaScript example +const fetchData = async () => { + try { + const response = await fetch('https://api.example.com/data'); + const data = await response.json(); + return data; + } catch (error) { + console.error('Error:', error); + } +}; +\`\`\` + +\`\`\`python +# Python example +def fibonacci(n): + if n <= 1: + return n + return fibonacci(n-1) + fibonacci(n-2) + +for i in range(10): + print(f"F({i}) = {fibonacci(i)}") +\`\`\` + +## Tables + +| Feature | Description | Supported | +|------|------|---------| +| Headings | H1-H6 headings | Yes | +| Lists | Ordered/unordered lists | Yes | +| Code blocks | Syntax highlighting | Yes | +| Tables | Markdown tables | Yes | +| Links | Hyperlinks | Yes | +| Images | Image rendering | Yes | +| Blockquotes | Blockquotes | Yes | + +## Blockquotes + +> This is a blockquote. +> +> It can be used to emphasize important information or quote someone. +> +> 鈥?Sparo OS Team + +> **Note:** Blockquotes can include other Markdown elements, including **bold**, *italic*, and \`code\`. + +## Links + +Visit the [Sparo OS website](https://sparo.dev) for more information. + +See the [GitHub repository](https://github.com/sparo-os) for the source code. + +Auto link: https://example.com + +## Images + +![Sample image](https://via.placeholder.com/600x300/667eea/ffffff?text=Sparo OS+Markdown) + +## Horizontal Rule + +--- + +## Nested Content + +### Code inside lists + +1. First install dependencies: + \`\`\`bash + npm install react-markdown + \`\`\` + +2. Then use it in code: + \`\`\`jsx + import ReactMarkdown from 'react-markdown'; + + {content} + \`\`\` + +### List inside blockquote + +> #### Notes +> +> - Make sure to properly escape special characters +> - Use appropriate syntax highlighting +> - Keep the document structure clear + +## Special Formats + +
+Click to expand details + +This content is collapsed; click the title to expand. + +- Supports HTML tags +- Can include Markdown content + +
+ +## Summary + +The Sparo OS Markdown component supports: + +1. Full Markdown syntax +2. GitHub Flavored Markdown (GFM) +3. A polished dark theme +4. Code syntax highlighting +5. Responsive tables +6. Custom style variants + +**Get started now!**`}},hv={close:"Close",confirm:"Confirm",cancel:"Cancel"},fv={alert:{title:"Alert",ok:"OK"},confirm:{title:"Confirm",ok:"OK",cancel:"Cancel"},prompt:{title:"Prompt",placeholder:"Enter...",ok:"OK",cancel:"Cancel"}},yv={copy:"Copy",copied:"Copied",close:"Close",expand:"Expand",collapse:"Collapse"},wv={close:"Close Tab",popOut:"Pop out as scene",closeOthers:"Close Other Tabs",closeAll:"Close All Tabs",closeRight:"Close Tabs to the Right",pin:"Pin Tab",unpin:"Unpin Tab",unsaved:"Unsaved",fileDeleted:"Deleted",hiddenTabsCount:"{{count}} hidden tabs",confirmCloseWithDirty:`File "{{title}}" has unsaved changes. + +Discard changes and close?`,confirmCloseAllWithDirty:`{{count}} files have unsaved changes: + +{{fileList}} + +Discard all changes and close?`},vv={expand:"Expand",collapse:"Collapse",loading:"Loading..."},bv={empty:"No Data",loading:"Loading...",rowsPerPage:"Rows per page",totalRows:"{{total}} rows total",page:"Page {{page}}",of:"of {{total}}"},kv={first:"First Page",last:"Last Page",previous:"Previous Page",next:"Next Page",page:"Page {{page}}",of:"of {{total}}"},Sv={noItems:"No items"},xv={cut:"Cut",copy:"Copy",paste:"Paste",delete:"Delete",selectAll:"Select All"},Cv={contextList:{emptyTitle:"No context",emptyHint:"Drag content from the file tree, code editor, or Mermaid diagram here",title:"Context",clearAll:"Clear",clearAllTitle:"Clear all context",clearAllConfirm:"Clear all {{count}} contexts?"},contextCard:{unknownType:"Unknown type: {{type}}",removeContext:"Remove this context",viewFullCode:"View full code",viewLargeImage:"View full image"},contextTypes:{selection:"Text selection",file:"File",folder:"Folder",editor:"Editor",flowChat:"FlowChat",flowChatToolCard:"FlowChat tool card",flowChatTextBlock:"FlowChat text block",tab:"Tab",panelHeader:"Panel header",emptySpace:"Empty space",custom:"Custom",unknown:"Unknown"},webElement:{from:"from"},diagram:{defaultTitle:"Mermaid diagram",types:{flowchart:"Flowchart",sequence:"Sequence diagram",class:"Class diagram",state:"State diagram",er:"ER diagram",gantt:"Gantt chart",other:"Diagram"},codeSize:{chars:"{{count}} chars",kChars:"{{count}}K chars"}},validation:{warnings:{codeLinesLarge:"Selected code has many lines (>{{max}}). Consider reducing.",codeContentLarge:"Selected code is large (>{{maxChars}} characters). Processing may be slower.",fileLarge:"File is large (>{{size}}MB). Processing may be slower.",mermaidCodeLong:"Mermaid code is long (>{{maxChars}} characters). Processing may be slower.",mermaidCodeInvalid:"Mermaid syntax might be invalid."}}},Av={close:"Close",closeAll:"Close All"},_v={title:"Notification Center",actions:{markAllRead:"Mark All as Read",clearAll:"Clear All"},searchPlaceholder:"Search notifications...",filters:{all:"All ({{count}})",placeholder:"Category"},activeTasks:{title:"Active tasks ({{count}})"},empty:{noMatches:"No matching notifications",noNotifications:"No notifications"},groups:{earlier:"Earlier"}},Tv={text:"Loading...",retry:"Retry"},Pv={title:"No Data",description:"No content found"},Fv={title:"Error",description:"An unexpected error occurred",retry:"Retry"},Rv={placeholder:"Search...",noResults:"No results",clear:"Clear search"},Nv={required:"Required",optional:"Optional",submit:"Submit",reset:"Reset",cancel:"Cancel"},Dv={minimize:"Minimize",maximize:"Maximize",restore:"Restore",close:"Close"},Iv={workspaceOpenFailed:"Failed to open workspace",projectRequestMessage:`I want to create a new project: + +{{description}} + +Please design the project structure and start implementing it.`,projectRequestSent:"Project requirements sent to Xiaofang. Collaboration started.",projectRequestSendFailed:"Failed to send project description. Please enter it manually.",flowChatInitFailed:"Initialization failed. Please refresh the page."},Mv={sessions:"Workbench",files:"Files",terminal:"Terminal",projectContext:"Project Context",git:"Git",capabilities:"Capabilities",clickToSelectBranch:"Click to select branch",aiWingExpand:"Expand AI tools",devWingExpand:"Expand dev tools"},jv={noContentOpen:"No content open",filesCount:"{{count}} files",searchPlaceholder:"Search file name or path...",noPreview:"No preview available",groupPrimary:"Primary",groupSecondary:"Secondary",groupTertiary:"Tertiary",groupPrimaryFull:"Primary Group",groupSecondaryFull:"Secondary Group",groupTertiaryFull:"Tertiary Group",mergeAllGroups:"Merge all groups",mergeAll:"Merge All",noMatchingFiles:"No matching files",noOpenFiles:"No open files",clickToSwitch:"Click card to switch file",exit:"Exit",openFileLocation:"Open file location",pinAsTab:"Pin as tab (Enter)",closeEsc:"Close (Esc)",enterToPin:"Enter to pin as tab",escToClose:"Esc to close",dragTabHere:"Drag tab here",dragToResize:"Drag to resize | Double-click to reset",terminal:"Terminal",dropLeft:"Left",dropRight:"Right",dropTop:"Top",dropBottom:"Bottom",dropCenter:"Drop"},Ev={empty:{title:"No Content",description:"Select a file or node to preview content"},unknownContent:{title:"Unsupported Content Type",description:"Cannot preview this type of content",contentType:"Content type: {{type}}"},visualizationDisabled:{title:"Visualization Features Disabled",description:"Project reading mode focuses on file browsing and preview"},errors:{markdownEditorMissingPath:"Cannot load Markdown editor: missing file path or initial content",planViewerMissingPath:"Cannot load Plan viewer: missing file path",terminalMissingSessionId:"Cannot load terminal: missing session ID",productAppRuntimeMissingHost:"Cannot load Product App runtime: missing host surface",productAppRuntimeBootTimeout:"The app did not become ready. Try loading it again.",gitPanelRemoved:"Git integration has been removed from this build."},placeholder:{architectureLayerViewer:"Architecture layer viewer is under development...",noDiffResult:"No diff result to display",noModuleChanges:"No module changes"},actions:{copyContent:"Copy content",downloadContent:"Download content",close:"Close",retry:"Retry"},loading:{gitDiff:"Loading Git diff...",gitGraph:"Loading Git graph...",gitBranchHistory:"Loading branch commit history...",gitSettings:"Loading Git settings...",diffView:"Loading Diff view...",taskDetail:"Loading task detail...",dependencyGraph:"Loading dependency graph...",planViewer:"Loading plan...",terminal:"Loading terminal...",productAppRuntime:"Loading Product App...",productAppRuntimeUpdating:"Updating..."},aiSession:{title:"AI Session: {{sessionId}}",unknown:"Unknown",sessionStatus:"Session Status:",operationsCount:"Operations Count:",operationsValue:"{{count}} operations",startTime:"Start Time:",unknownTime:"Unknown",fileOperations:"File Operations"},fallback:{noCodeContent:"No code content available"}},Lv={button:sv,input:iv,select:av,numberInput:rv,codeEditor:lv,inputDialog:cv,markdown:dv,mermaidBlock:uv,reproductionSteps:pv,flowChatCards:mv,designSystem:gv,modal:hv,dialog:fv,tooltip:yv,tabs:wv,tree:vv,table:bv,pagination:kv,dropdown:Sv,contextMenu:xv,contextSystem:Cv,notification:Av,notificationCenter:_v,loading:Tv,empty:Pv,error:Fv,search:Rv,form:Nv,windowControls:Dv,appLayout:Iv,bottomBar:Mv,canvas:jv,flexiblePanel:Ev},$v="Sparo OS Design System Preview",Ov={designSystem:"Design system",previewTheme:"Preview theme",previewLanguage:"Language"},Bv={lightDescription:"Light preview theme",darkDescription:"Dark preview theme",light:{name:"Light",description:"Clean light preview theme"},slate:{name:"Slate",description:"Soft slate dark preview theme"},dark:{name:"Dark",description:"High-contrast dark preview theme"},"sparo-china-style":{name:"Ink Charm",description:"Light theme inspired by Chinese ink"},"sparo-china-night":{name:"Ink Night",description:"Dark theme inspired by Chinese ink"},"sparo-cyber":{name:"Cyber",description:"High-energy cyber dark preview theme"}},Wv={library:"Library",expandNavigation:"Expand navigation",collapseNavigation:"Collapse navigation",searchPlaceholder:"Search components",searchAriaLabel:"Search design system components",navigationAriaLabel:"Design system library",categoryExamplesAriaLabel:"{{category}} components",shown:"{{count}} shown",searchShortcut:"Press / to search"},zv={noMatches:"No matches",searchSuggestion:"Try a component name or ID.",noPreview:"No preview found",previewSuggestion:"Try another component name or clear the search."},Uv={tiers:{primitive:"Primitive",pattern:"Pattern",recipe:"Recipe"},examplesAriaLabel:"Preview examples",previous:"Previous: {{name}}",next:"Next: {{name}}",usage:"Usage",usageGuidance:"Usage guidance",closeUsage:"Close usage guidance"},Hv={recipe:"Recipe",useWhen:"Use when",composeWith:"Compose with",avoid:"Avoid",states:"States",notes:"{{count}} notes"},qv={categories:{"ds-primitives":{name:"Primitives",description:"Stable low-level controls. Use them inside patterns, not as feature-local UI frameworks."},"ds-patterns":{name:"Patterns",description:"Page and workflow structures that AI agents should prefer before reaching for primitives."},"ds-ai-entry":{name:"AI Entry Rules",description:"Start here before composing any product UI with the design system."}},examples:{"ds-sparo-logo-mark":{name:"Sparo logo mark",description:"Vector brand mark with configurable size, stroke width, and currentColor inheritance."},"ds-sparo-system-icons":{name:"Sparo semantic icon families",description:"First-party system, work-type, navigation, search/filter, file-transfer, and edit/manage icons."},"ds-button-semantics":{name:"Button command semantics",description:"Variant, size, loading, disabled, and icon-only command rules."},"ds-floating-card":{name:"Floating card",description:"Large-radius non-modal surface with a pronounced two-stage elevation shadow and a standard dismiss command."},"ds-popup-menu":{name:"Popup menu",description:"Anchored menu baseline with the shared floating shadow and an intermediate corner radius."},"ds-form-controls":{name:"Form controls",description:"Text, select, switch, and checkbox primitives in realistic settings copy."},"ds-feedback":{name:"Feedback primitives",description:"Status badges and empty states for desktop workflow surfaces."},"ds-search-and-filters":{name:"Search affordances",description:"Search iconography and filter commands for compact desktop surfaces."},"ds-dialog-tabs-alerts":{name:"Dialogs, tabs, and alerts",description:"Keyboard-focused primitives with explicit roles, labels, and recovery states."},"ds-input-variants":{name:"Input variants",description:"Textarea, search, and number field states with labelled controls and descriptions."},"ds-segmented-pagination":{name:"Segmented control and pagination",description:"Navigation controls with selected, disabled, focused, narrow, and long-label states."},"ds-loading-status":{name:"Loading and status primitives",description:"Stable loading placeholders plus text-backed state indicators."},"ds-app-window":{name:"Application window",description:"Non-modal in-app popup window for substantial content without a backdrop."},"ds-scene-panel":{name:"Scene + Panel",description:"Default desktop scene composition with command grouping and bounded work areas."},"ds-list-detail":{name:"List detail workflow",description:"Selectable master list plus a focused detail or inspector surface."},"ds-settings-page":{name:"Settings page",description:"Standard configuration layout for settings, preferences, and provider setup."},"ds-item-card":{name:"Item cards",description:"Reusable card shell for tasks, apps, and other actionable catalog entries."},"ds-tool-card":{name:"Production tool cards",description:"Actual compact and expandable flow-chat cards used by registered Read and Bash tools."},"ds-navigation-empty-status":{name:"Navigation, empty, and status",description:"Supporting patterns for workspace navigation and resilient empty states."},"ds-action-list-row":{name:"Action list rows",description:"Reusable rows for selection, metadata, status, actions, loading, and errors."},"recipe-agent-session-workbench":{name:"Agent session workbench",description:"Real product scene for session triage, task continuation, and live agent activity."},"recipe-workspace-file-operations":{name:"Workspace file operations",description:"Compact navigation plus detail shell for file, diff, and workspace browsing tasks."},"recipe-model-settings":{name:"Model and permission settings",description:"Settings recipe for model defaults, workspace policies, and validation states."},"recipe-tool-execution":{name:"Tool execution cards",description:"Flow-chat execution shell for running, completed, and failed tool output."}}},Vv={documentTitle:$v,header:Ov,themes:Bv,sidebar:Wv,empty:zv,focused:Uv,guide:Hv,catalog:qv},Gv={unknown:"An unknown error occurred",network:"Network error",timeout:"Request timeout",serverError:"Server error",notFound:"Resource not found",unauthorized:"Unauthorized",forbidden:"Access forbidden",badRequest:"Bad request",conflict:"Resource conflict",tooManyRequests:"Too many requests",copyFailed:"Copy failed. Please try again."},Kv={notFound:"File not found: {{path}}",readError:"Failed to read file: {{path}}",writeError:"Failed to write file: {{path}}",deleteError:"Failed to delete file: {{path}}",permissionDenied:"Permission denied: {{path}}",alreadyExists:"File already exists: {{path}}",invalidPath:"Invalid file path: {{path}}",tooLarge:"File is too large: {{path}}",encodingError:"File encoding error: {{path}}",createFileFailed:"Failed to create file",createFolderFailed:"Failed to create folder",renameFailed:"Rename failed",revealFailed:"Failed to open file manager"},Qv={notFound:"Workspace not found",openError:"Failed to open workspace",invalidPath:"Invalid workspace path",alreadyOpen:"Workspace is already open"},Jv={notRepository:"Current directory is not a Git repository",cloneError:"Failed to clone repository",commitError:"Commit failed",pushError:"Push failed",pullError:"Pull failed",mergeConflict:"Merge conflict exists",branchError:"Branch operation failed",stashError:"Stash operation failed",authError:"Authentication failed",remoteError:"Remote repository error"},Yv={connectionError:"Failed to connect to AI service",apiKeyInvalid:"Invalid API key",modelNotFound:"Model not found",contextTooLong:"Context exceeds limit",rateLimited:"Rate limit exceeded",generationError:"Failed to generate content",streamError:"Stream response error",timeout:"AI response timeout",initializeFailedTitle:"AI client initialization failed",configRequired:"Model configuration is required"},Zv={createError:"Failed to create terminal",executeError:"Failed to execute command",killError:"Failed to kill process",shellNotFound:"Shell not found"},Xv={maximizeFailed:"Failed to maximize window: {{error}}",closeFailed:"Failed to close window: {{error}}"},eb={openError:"Failed to open editor",saveError:"Failed to save file",formatError:"Formatting failed",parseError:"Failed to parse file",lspError:"Language server error"},tb={loadError:"Failed to load configuration",saveError:"Failed to save configuration",invalidFormat:"Invalid configuration format",validationError:"Configuration validation failed"},nb={createError:"Failed to create snapshot",restoreError:"Failed to restore snapshot",notFound:"Snapshot not found",corrupted:"Snapshot is corrupted",loadStatsFailed:"Failed to load snapshot stats",loadSessionsFailed:"Failed to load snapshot sessions",loadOperationsFailed:"Failed to load session operations",getDiffFailed:"Failed to get file diff",acceptOperationFailed:"Failed to accept operation",rejectOperationFailed:"Failed to reject operation",rollbackSessionFailed:"Failed to rollback session",cleanupFailed:"Failed to cleanup expired data"},ob={noSelection:"No text selected",notEditable:"Content is not editable",readOnlyEditor:"Editor is read-only",clipboardUnavailable:"Clipboard access is unavailable",clipboardEmpty:"Clipboard is empty",copyFailed:"Copy failed",cutFailed:"Cut failed",pasteFailed:"Paste failed",selectAllFailed:"Select all failed",refreshFailed:"Refresh failed",deleteFailed:"Delete failed",deleteCancelled:"Delete canceled",editorModelUnavailable:"Editor model is unavailable",copyPathFailed:"Copy path failed",copyRelativePathFailed:"Copy relative path failed"},sb={initializationFailed:"Core system initialization failed"},ib={title:"Something went wrong",description:"The interface paused safely. Your project files were not changed.",reload:"Reload",sections:{currentState:"Current state",nextSteps:"Recommended next steps",errorSummary:"Error summary"},actionHint:"Reload first. If this comes back, copy diagnostics or open the log folder.",currentStateBody:"The app shell is still open, but this part of the interface stopped rendering safely. Try reloading first; if the problem comes back, copy the diagnostics or open the log folder before reporting it.",suggestions:{reload:"Reload the app to recover from a temporary rendering problem.",copyDiagnostics:"Copy diagnostics if the same screen appears again.",openLogs:"Open the log folder when you need to attach detailed runtime logs."},actions:{copyDiagnostics:"Copy diagnostics",openLogs:"Open log folder",copied:"Diagnostics copied to clipboard.",copyFailed:"Could not copy diagnostics. Please open the technical details and copy them manually.",logsOpened:"Log folder opened.",openLogsFailed:"Could not open the log folder. You can still copy diagnostics."},technicalDetails:"Technical Details",unknown:"Unknown error"},ab={general:Gv,file:Kv,workspace:Qv,git:Jv,ai:Yv,terminal:Zv,window:Xv,editor:eb,config:tb,snapshot:nb,contextMenu:ob,core:sb,boundary:ib},rb={welcomeBack:"Welcome back!",workingIn:"You are working in {{workspace}}",workingInWithBranch:"You are working in {{workspace}}, on branch {{branch}}",capabilities:"I can help you understand complex code, quickly implement new features,",capabilities2:"refactor legacy projects, or solve those annoying bugs.",readyToHelp:"Tell me your ideas, I'm ready to help",noWorkspace:"Nothing here yet",openProject:"Open a project and let's start coding together"},lb={noTabs:"No tabs open",selectFromLeft:"Select a file or content from the left to create a new tab",dragTabHere:"Drag tabs here",releaseToAdd:"Release to add to this column"},cb={noPanels:"Sparo OS",noPanelsHint:"Use the bottom bar to toggle panels or press Ctrl+\\ Ctrl+] to expand panels",chatHiddenTitle:"Chat is hidden",chatHiddenDesc:"Use the Chat toggle in the top-right to show it again.",chatHiddenAction:"Show Chat",panelCollapseHintLeft:"<- Release to collapse",panelCollapseHintRight:"Release to collapse ->",panelMode:{collapsed:"Collapsed",compact:"Compact",comfortable:"Comfortable",expanded:"Expanded"},resizer:{leftAriaLabel:"Resize left panel",centerAriaLabel:"Resize panel",rightAriaLabel:"Resize right panel",title:"Drag to resize | Double-click to switch mode | Current: {{mode}}"}},db={toBottom:"Back to bottom",toBottomWithCount:"Back to bottom ({{count}} new messages)",toLatest:"Jump to latest message",clickToLatest:"Click to jump to latest",anchorJumpToTurn:"Jump to {{turn}}: {{title}}"},ub={user:"User",assistant:"Assistant",system:"System",thinking:"Thinking...",generating:"Generating...",copy:"Copy Message",copied:"Copied",copyFailed:"Copied!",regenerate:"Regenerate",edit:"Edit Message",editPlaceholder:"Edit your message...",editSubmit:"Save and rerun",editCancel:"Cancel edit",editSuccess:"Message updated and rerun",editHistoryDialogTitle:"Edit turn {{index}} and rerun from here?",editHistoryDialogIntro:"This rewrites the conversation from this message.",editBusyDialogTitle:"Stop the running turn and edit turn {{index}}?",editBusyDialogIntro:"A turn is currently running. Editing will stop it before rewriting history.",editDialogBulletStopRunning:"Stop the currently running task",editDialogBulletFiles:"Restore files to the state before this turn",editDialogBulletHistory:"Delete this turn and all following dialog records",editDialogBulletRerun:"Start a new turn with the edited message",delete:"Delete Message",retry:"Retry",clickToExpand:"Click to expand",clickToCollapse:"Click to collapse",fillToInput:"Fill to input",cannotRollback:"Cannot rollback",rollbackTo:"Rollback to before turn {{index}} (delete this and following turns)",rollbackDialogTitle:"Rollback to before turn {{index}}?",rollbackDialogIntro:"This will:",rollbackDialogBulletFiles:"Undo all file modifications from that turn onwards",rollbackDialogBulletHistory:"Delete that turn and all following dialog records (irreversible)",rollbackPanelDialogTitle:"Roll back to before turn {{index}}?",rollbackPanelDialogIntro:"This will:",rollbackPanelBulletRestore:"Restore files to the state before turn {{index}}",rollbackPanelBulletUndo:"Undo all file changes from that turn onward",rollbackPanelBulletHistory:"Keep the session history (you can roll forward again anytime)",rollbackSuccess:"Rolled back and deleted subsequent dialog records",rollbackFailed:"Rollback failed",sessionStartMarker:"Session started {{time}}"},pb={copySelection:"Copy Selection",selectionCopied:"Copied",copySelectionFailed:"Failed to copy selection",addSelectionToChat:"Add to chat",createSideQuestionFromSelection:"Side question",selectionActions:"Selection actions",copyFullContent:"Copy Full Content",copyContent:"Copy Content",copyDialog:"Copy Entire Dialog",copyToolInput:"Copy Tool Input",copyToolOutput:"Copy Tool Output"},mb={placeholder:"How can I help you...",placeholderWithContext:"Type a message, or drag and drop files to add context...",send:"Send",sendShortcut:"Send (⏎)",queueShortcut:"Add to queue (⏎)",stop:"Stop",stopGeneration:"Stop Generation (Esc)",processingCapsule:"Processing",cancelShortcut:"Cancel",clear:"Clear",attach:"Attach File",collapseInput:"Collapse input",expandInput:"Expand input",retry:"Retry",addImage:"Add image",maxImagesWarning:"Maximum {{count}} images allowed",imagePasteFailed:"Image paste failed",removeImage:"Remove image",context:{textFragment:"Long text: {{preview}}",longTextTitle:"Long text",emptyPreview:"empty",characterCount:"{{count}} chars",skillSuiteDetail:"Skill Suite · {{count}} skills",skillDetail:"Skill · {{suite}}",standaloneSkill:"Standalone",open:"Open {{label}}",remove:"Remove {{label}}"},messageTooLarge:"Message exceeds the maximum length of {{max}} characters ({{count}} provided).",openWorkspaceFolder:"Open workspace folder",openWorkspaceFolderFailed:"Failed to open workspace folder: {{error}}",globalWorkspace:"Global",spaceToActivate:"How can I help? Press Space to start typing",voiceInput:{transcribeOnly:"Transcribe only",transcribeAndSend:"Transcribe and send",start:"Start voice input",stop:"Stop and transcribe",preparing:"Preparing voice input",recording:"Recording",transcribing:"Transcribing",disabled:"Voice input is disabled",modelMissing:"Download the local speech model in Settings",unsupported:"Microphone capture is not available in this environment",permissionDenied:"Microphone permission was denied",failed:"Voice input failed",empty:"No speech text was detected"}},gb={title:"{{count}} queued",edit:"Edit queued message",delete:"Delete queued message",saveEdit:"Save queued message",cancelEdit:"Cancel edit",editAriaLabel:"Queued message draft",dispatching:"sending",resume:"Resume",imageCount:"{{count}} images",updateFailed:"Failed to update queued message",deleteFailed:"Failed to delete queued message",resumeFailed:"Failed to resume queue",pauseReasons:{user_cancelled:"Paused after cancellation",run_failed:"Paused after failure",app_recovered:"Paused after recovery",default:"Paused"},guide:"Guide active turn",guideFailed:"Failed to send guidance"},hb={title:"Context",add:"Add Context",remove:"Remove Context",clear:"Clear Context",file:"File",folder:"Folder",selection:"Selection",codeBlock:"Code Block",image:"Image",url:"URL",dragHint:"Drop files here to add context"},fb={staticContext:"Static context",currentRequest:"Current request",closeDetails:"Close context details",noSegmentData:"No segment data",calculating:"Calculating context budget",segments:{systemPrompt:"System prompt",environment:"Environment",workspace:"Workspace",memory:"Memory",files:"Files",toolDefinitions:"Tool definitions",skills:"Skills",subagentDefinitions:"Subagent definitions",conversation:"Conversation",currentMessage:"Current message",assistant:"Assistant",toolResults:"Tool results",images:"Images",summary:"Summary",overhead:"Overhead"}},yb={title:"Agent",select:"Select Agent",default:"Default Assistant",coding:"BitFun Coder",review:"Code Review",architect:"Architect",custom:"Custom Agent"},wb={title:"Model",select:"Select Model",temperature:"Temperature",maxTokens:"Max Tokens",topP:"Top P",streaming:"Streaming",autoMigrated:{title:"Model auto-switched",description:'Session model "{{previous}}" is no longer available. Switched to "{{next}}".',reason:"Reason: {{reason}}"}},vb={newSession:"New Session",history:"History",settings:"Settings",export:"Export Chat",clear:"Clear Chat",fullscreen:"Fullscreen",exitFullscreen:"Exit Fullscreen"},bb={ready:"Ready",thinking:"Thinking",generating:"Generating",error:"Error Occurred",offline:"Offline",connecting:"Connecting",connected:"Connected"},kb={sendFailed:"Send Failed",connectionError:"Connection Error",timeout:"Request Timeout",modelError:"Model Error",contextTooLong:"Context Too Long",rateLimited:"Rate Limited",unknown:"Unknown error"},Sb={title:"Task Planning",completed:"Completed",completedCount:"{{count}} Completed",inProgress:"In Progress",inProgressCount:"{{count}} In Progress",pending:"Pending",pendingCount:"{{count}} Pending",todoItems:"Todo Items ({{count}})",save:"Save",cancel:"Cancel",sendToModel:"Send changes to model",sending:"Sending...",doubleClickToEdit:"Double-click to edit",percentComplete:"{{percent}}% Complete",currentStatus:"Current status: {{status}}"},xb={searchResults:"Search Results",loading:"Loading...",noMatchingFiles:"No matching files found",emptyDirectory:"Empty directory",rootDirectory:"Root",goBack:"Go back",navHint:"Navigate",enterHint:"Enter",backHint:"Back",selectHint:"Select"},Cb={copy:"Copy",copied:"Copied",copyOutputContent:"Copy output content",copiedOutputContent:"Output content copied",edit:"Edit",openInEditor:"Open in editor",aiReply:"AI Reply {{timestamp}}",toolCall:"🔧 Tool call: {{name}}",unknownTool:"Unknown tool"},Ab={title:"💡 Smart Recommendations",close:"Close"},_b={title:"Side question",shortLabel:"Side",hint:"Not saved · Uses current chat context · No tools",placeholder:"Ask a quick question…",ask:"Ask",asking:"Thinking…",cancel:"Stop",openThread:"Open thread",threadLabel:"Side thread",emptyThreadLabel:"No {{label}} open",origin:"Asked from",parent:"parent session",turnLabel:"turn {{index}}",back:"Back",backToParent:"Back to parent session",empty:"Please provide a question after /btw",nestedDisabled:"A side question cannot start another side question",error:"Failed",close:"Close",noSession:"No active session for /btw"},Tb={title:"Host scan",shortLabel:"Host scan",threadLabel:"Host scan",emptyThreadLabel:"No {{label}} open",origin:"Started from",parent:"source session"},Pb={turnList:"Turn list",timeline:"Timeline",untitledTurn:"Untitled turn",previousTurn:"Previous turn",nextTurn:"Next turn",turnBadge:"Turn {{current}}",btwBackTooltipWithTurn:"Go back to the source session: {{title}} (Turn {{turn}})",btwBackTooltipWithoutTurn:"Go back to the source session: {{title}}",btwCreateTooltip:"Start a quick side question",agentTypeTooltip:"{{type}}: {{path}}",backToAgenticOs:"Back to Agentic OS",searchPlaceholder:"Search in conversation turns",searchResult:"{{current}} / {{total}}",searchNoResults:"No matching turns",searchPrevious:"Previous matching turn",searchNext:"Next matching turn",searchClose:"Close search",searchOpen:"Search in turns",hideCompletedThinkingItems:"Hide completed thinking items",showCompletedThinkingItems:"Show completed thinking items",resetHistory:"Reset history",moreMenu:"More",showCompletedThinkingInConversation:"Show/hide thinking",resetSession:"Reset session",sidecar:{groupLabel:"Session panels",more:"More panels",designs:"Designs",designTokens:"Design Tokens",appBuilder:"App Builder"},goalPanel:{open:"Goal details",close:"Close goal details",title:"Goal",edit:"Edit goal",objective:"Goal",saveEdit:"Save",saving:"Saving",cancelEdit:"Cancel",emptyEditError:"Goal cannot be empty.",updateFailed:"Failed to update goal.",controlFailed:"Goal action failed.",fallbackMessage:"AI goal extraction failed; using your input as the goal.",needsInput:"Needs input",gaps:"Remaining gaps",pause:"Pause goal",resume:"Resume goal",review:"Review goal",clear:"Clear goal",cancelExecution:"Cancel goal execution"}},Fb={timeFilterTooltip:"Filter by time",timeFilterAll:"All time",timeFilterToday:"Today",timeFilterLast7:"Last 7 days",timeFilterThisMonth:"This month",timeFilterCustomRange:"Custom range…",timeFilterCustomTitle:"Custom date range",timeFilterCustomHint:"Click a start date, then an end date.",timeFilterCustomSummary:"{{start}} – {{end}}",timeFilterCustomPickEndHint:"Now choose an end date (start: {{start}}).",timeFilterCustomPickEnd:"Select an end date to complete the range.",timeFilterCustomPrevMonth:"Previous month",timeFilterCustomNextMonth:"Next month",timeFilterCustomApply:"Apply",timeFilterCustomCancel:"Cancel",counterFiltered:"{{shown}} / {{total}}"},Rb={title:"Timeline",toggleTooltip:"Timeline",counter:"{{sessions}} sessions · {{turns}} turns",counterFiltered:"{{sessionsShown}} / {{sessionsTotal}} sessions · {{turnsShown}} / {{turnsTotal}} turns",searchPlaceholder:"Search across sessions",empty:"No conversations yet. Send a message below to start the first chapter.",emptyTimeFilter:"No sessions in this time range. Change the filter or pick All time.",sessionEmpty:"No turns yet",turnCount_one:"{{count}} turn",turnCount_other:"{{count}} turns",newSession:"Start a new chapter",newSessionLabel:"New chapter",selectSessions:"Select sessions",selectionModeActive:"Selecting sessions",selectSession:"Select {{title}}",deselectSession:"Deselect {{title}}",bulkLabel:"Session selection actions",selectAllVisible:"Select all visible sessions",selectedCount:"{{count}} / {{total}} selected",deleteSelected:"Delete selected sessions",clearSelection:"Clear selection",deleteDialogTitle:"Delete selected sessions?",deleteDialogMessage:"This will permanently delete {{count}} selected session(s). This cannot be undone.",deleteConfirm:"Delete sessions",deletePreviewMore:"...and {{count}} more",deleteSuccess:"Deleted {{count}} session(s)",deleteFailed:"Failed to delete {{count}} selected session(s)",bucket:{today:"Today",yesterday:"Yesterday",thisWeek:"Earlier this week",thisMonth:"Earlier this month"}},Nb={files:"files",reviewLabel:"Review",reviewAll:"Review All",loadFailed:"Load failed",clickToViewDiff:"Click to view diff",review:{displayMessage:`Review modified files: +{{files}}`,displayMessageFiltered:`Review filtered files: +{{files}} + +Skipped {{skipped}} excluded files.`,filteredNotice:"Review will analyze {{included}} files and skip {{skipped}} excluded files such as lock, generated, or binary assets.",noEligibleFiles:"No reviewable files remain after excluded files were filtered out.",prompt:`Please review the following files modified in this session: + +{{files}}`,promptFiltered:`Please review the following modified files in this session: + +{{files}} + +Do not review the {{skipped}} skipped files because they matched the excluded lock, generated, or binary file rules.`,threadTitle:"Code review"}},Db={filesCount:"{{count}} files",expandList:"Expand list",collapseList:"Collapse list"},Ib={errors:{refreshSessionFailed:"Failed to refresh session state",acceptFileFailed:"Failed to accept file changes",rejectFileFailed:"Failed to reject file changes",acceptSessionFailed:"Failed to accept session changes",rejectSessionFailed:"Failed to reject session changes",acceptBlockFailed:"Failed to accept change block",rejectBlockFailed:"Failed to reject change block"}},Mb={subtitle:"BitFun Coder · Chat Record",poweredBy:"Powered by",aiAssistant:"BitFun Coder",dialogNotFound:"Dialog data not found",containerNotFound:"Export container not found",generateFailed:"Failed to generate image",fileNamePrefix:"Sparo-Chat",exportSuccess:"Image exported: {{filePath}}",exportSuccessPrefix:"Image exported: ",exportFailed:"Export failed, please try again",exporting:"Exporting...",exportToImage:"Export as Image"},jb={copyDialog:"Copy dialog",copiedDialog:"Copied!",forkDialog:"Fork session from here",forkFailed:"Failed to fork session",like:"Like",dislike:"Dislike",report:"Report",feedbackThanks:"Thank you for your feedback!",feedbackDevVersion:"Feedback is not available in dev version",userLabel:"👤 User:",toolCallLabel:"🔧 Tool call: {{name}}"},Eb={readFiles_one:"Read {{count}} file",readFiles_other:"Read {{count}} files",readFiles:"Read {{count}} file(s)",searchCount_one:"{{count}} search",searchCount_other:"{{count}} searches",searchCount:"{{count}} search(es)",fetchCount_one:"{{count}} fetch",fetchCount_other:"{{count}} fetches",fetchCount:"{{count}} fetch(es)",commandCount_one:"{{count}} command",commandCount_other:"{{count}} commands",commandCount:"{{count}} command(s)",otherToolCount_one:"{{count}} other tool",otherToolCount_other:"{{count}} other tools",otherToolCount:"{{count}} other tool(s)",thinkingCount_one:"Thought {{count}} time",thinkingCount_other:"Thought {{count}} times",thinkingCount:"Thought {{count}} time(s)",exploreCount_one:"{{count}} exploration",exploreCount_other:"{{count}} explorations",exploreCount:"{{count}} exploration(s)",separator:", ",collapse:"Collapse exploration"},Lb={model:"Model",modelExplanation:"Model explanation",modelSelection:"Select Model",currentMode:"Current Mode",primaryModel:"Primary Model",fastModel:"Fast Model",modelNotConfigured:"Not Configured"},$b={title:"Reasoning Effort",tooltip:"Adjust model reasoning depth (Responses API only)",default:"Default",low:"Low",lowDesc:"Fast responses, light reasoning",medium:"Medium",mediumDesc:"Balance speed and reasoning depth",high:"High",highDesc:"Deep reasoning",xhigh:"Extra High",xhighDesc:"Maximum reasoning depth (slower)"},Ob={title:"Choose a Cowork Assistant workspace",description:"Cowork Assistant needs a workspace folder to read/write files. Use the current project, or choose another folder.",recommended:"Recommended",current:{title:"Current workspace",subtitle:"Opened: {{name}}",description:"Artifacts are saved in the current project. Use this when you need to read or change project files."},global:{title:"Other folder",subtitle:"Choose directory",description:"Use a different folder for Cowork Assistant tasks. Outputs will be saved in that folder."},errors:{noWorkspace:"No workspace is currently open",openFailed:"Failed to open Cowork Assistant workspace"}},Bb={title:"Examples",addPlugin:"Add plugin",addPluginDialogTitle:"Select a plugin folder",addPluginSuccess:"Plugin installed: {{name}}",addPluginFailed:"Failed to install plugin: {{error}}",refresh:"Shuffle",close:"Close",items:{desktop_cleanup:{title:"Organize desktop screenshots",description:"Rename, group, and file recent screenshots.",prompt:`Help me organize recent screenshots on my Desktop. + +First, scan my Desktop and count how many screenshots/images are there. Show me: + +- Total count + +- Date range (oldest to newest) + +Then, focus only on screenshots from the last 14 days. For each one: + +- Identify what it shows + +- Suggest a descriptive filename + +- Propose which folder it belongs in (or if it can be deleted) + +Group similar screenshots together. Show me the plan before making any changes. + +After I approve, start by organizing just 10 files as a preview. If there are more than 10 files, check in with me before continuing with the rest.`},vacation_plan:{title:"Plan my vacation",description:"Build a day-by-day itinerary with budget + backups.",prompt:`Plan a vacation for me. + +Basics: +- From: +- Destinations (optional backups): +- Dates / total days: +- Travelers + preferences: +- Budget range: +- Interests (food / nature / museums / shopping / relax): +- Hard constraints (no early mornings, no long drives, etc.): + +Output: +1) 2–3 destination options with pros/cons +2) Best option: day-by-day plan (morning/afternoon/evening) +3) Transport + lodging suggestions +4) Budget breakdown +5) Rainy-day/contingency alternatives`},make_ppt:{title:"Draft a PPT",description:"Outline slides, talking points, and visuals.",prompt:`Help me create a PPT deck. + +Topic: +Audience: +Time limit: +Use case (status update / pitch / training / sharing): +Preferred style (clean / business / playful / minimal): + +Deliverable: +1) Table of contents +2) Slide-by-slide: title + 3–5 bullets +3) Short speaker notes for key slides +4) Visual/chart suggestions (what chart for what message) +5) Export as a PPTX file (save it under artifacts/)`},todo_breakdown:{title:"Break it into todos",description:"Turn a goal into executable tasks with estimates.",prompt:`Break the following goal into an executable todo list with priorities and time estimates. + +Goal: +Deadline: +Current status: +Resources (people/budget/tools): +Risks/unknowns: + +Output: +1) Milestones +2) Task list (owner / ETA / dependencies / acceptance criteria) +3) Critical path + risks +4) Three small things I can start tomorrow`},optimize_week:{title:"Optimize my week",description:"Find patterns across messy notes and transcripts.",prompt:`Help me find patterns and insights across [my voice memos / meeting transcripts / documents / journal entries / specify folder]. I have messy, unstructured files and want to understand what themes are emerging. + +First, scan the folder and show me a summary: + +- Total files + +- Date range (oldest to newest) + +- Types of content + +Before analyzing, ask me: + +- What I'm hoping to discover (recurring themes, contradictions, evolution of thinking, action items, or something else) + +- Whether certain files or time periods should be prioritized + +- What format would be most useful for the final analysis + +If there are more than 20 files, start by analyzing just the 10 most recent files. + +Show me the top 3-5 patterns you found with 2-3 specific examples for each pattern. Once I confirm you're on the right track, analyze the remaining files.`},weekly_plan:{title:"Make a weekly plan",description:"Schedule priorities, meetings, and deep work blocks.",prompt:`Create a practical weekly plan for me. + +Inputs: +- Top goals (max 3): +- Fixed meetings/commitments: +- Deep work windows: +- Must-do tasks: +- Nice-to-have tasks: + +Output: +1) Priority order +2) Day-by-day plan (2–3 core tasks per day) +3) Risk + buffer time suggestions +4) 5-minute daily wrap-up checklist`},meeting_minutes:{title:"Write meeting minutes",description:"Summarize decisions, action items, and open questions.",prompt:`Turn my meeting notes into clear meeting minutes. + +Topic: +Attendees: +Time: +Raw notes (paste here): + +Output: +1) Key outcomes (3–6) +2) Decisions +3) Action items (owner / due date / acceptance criteria) +4) Risks + open questions +5) Suggested agenda for the next meeting`},reply_email:{title:"Reply to an email",description:"Generate a polite, clear email template (two tones).",prompt:`Help me write an email reply. + +Original email (paste here): +My goal (confirm / decline / push forward / clarify): +Tone (formal / friendly / firm but polite): +Key points to include: + +Output: +1) Subject line suggestions +2) Body (2 versions: more formal / more concise) +3) Questions for the recipient to confirm (if any)`},make_docx:{title:"Draft a DOCX",description:"Write a structured document and export as DOCX.",prompt:`Help me write a document and export it as a .docx file. + +Document type (PRD / proposal / meeting summary / report / SOP): +Audience: +Tone (formal / friendly / concise): +Must-include points: +Length target: + +Deliverable: +1) Suggested outline +2) Full content +3) Export as a .docx file (save it under artifacts/)`},make_spreadsheet:{title:"Design a spreadsheet",description:"Define fields and formulas for reusable tracking.",prompt:`Design a spreadsheet schema (columns + example rows) for the following purpose. + +Purpose: +Data sources: +Metrics / aggregation needs: +Preferred output (weekly report / dashboard / checklist): + +Output: +1) Recommended columns (type + notes) +2) Example data (3–5 rows) +3) Useful formulas / pivot suggestions +4) Data validation + filling guidelines`},budget_plan:{title:"Create a budget plan",description:"Allocate by category + timeline with review rules.",prompt:`Help me create a budget plan. + +Context: +- Budget period (monthly / quarterly / project): +- Total budget: +- Fixed costs: +- Variable costs: +- Goal (save money / control spending / save for something): + +Output: +1) Suggested categories + ratios +2) A category budget table (copy-paste friendly) +3) Overrun rules + adjustment plan +4) Weekly/monthly review checklist`}}},Wb={activity:{thinking:"Thinking",usingTools:"Using tools",waitingApproval:"Waiting for approval",writing:"Writing",compacting:"Compacting context",finishing:"Finishing",starting:"Starting",working:"Working",needsInput:"Needs input",needsApproval:"Needs approval",completed:"Completed",interrupted:"Interrupted",failed:"Failed"},menu:{openMain:"Open Sparo OS",openLatestTask:"Open latest task",settings:"Companion settings",hide:"Hide companion"}},zb={emptyState:rb,panel:lb,layout:cb,scroll:db,message:ub,contextMenu:pb,input:mb,inputQueue:gb,context:hb,contextBudget:fb,agent:yb,model:wb,toolbar:vb,status:bb,error:kb,planner:Sb,fileMention:xb,copyOutput:Cb,smartRecommendations:Ab,btw:_b,hostScan:Tb,flowChatHeader:Pb,timelineTimeFilter:Fb,agenticOsTimeline:Rb,sessionFilesBadge:Nb,sessionFileModificationsBar:Db,snapshotSystem:Ib,exportImage:Mb,modelRound:jb,exploreRegion:Eb,modelSelector:Lb,reasoningEffort:$b,coworkScope:Ob,coworkExamples:Bb,agentCompanion:Wb},Ub="Describe how you want Sparo to work",Hb="Add agent, image, or skill",qb="Start side question",Vb="Reference file or folder",Gb="Skills",Kb="Loading skills…",Qb="No enabled skills",Jb="No matching skills",Yb="Search skills and suites…",Zb="Skill Suites",Xb="Standalone Skills",ek="Show suite members",tk="Hide suite members",nk="Selected",ok="Manage skills…",sk="Back to default agent",ik="Quick action",ak="Compact session",rk="No active session for /compact",lk="Wait until the session is idle before using /compact.",ck="Use /compact without extra arguments.",dk="Session compaction failed",uk="Generate AGENTS.md",pk="Goal mode",mk="No active session for /goal",gk="Goal mode is not supported in this session.",hk="Goal command failed",fk="Describe the goal before sending.",yk="No active session for /init",wk="Wait until the session is idle before using /init.",vk="Use /init without extra arguments.",bk="AGENTS.md initialization failed",kk="Please generate or update AGENTS.md based on the current project content",Sk="Please scan this host and update the host overview document with practical routing guidance.",xk="Current agent: {{agent}}",Ck="No matching agent",Ak="No matching command",_k="↑↓ Select · Enter Confirm · Esc Cancel",Tk="Current",Pk="Loading MCP prompts...",Fk="This MCP prompt requires arguments: {{args}}",Rk="MCP prompt failed",Nk="Agent unavailable in this runtime",Dk={title:"Commands",groups:{target:"Target","send-with":"Send with","session-action":"Session action",app:"App action",template:"Prompt template"},btwDescription:"Ask in a focused side thread",contextDescription:"Attach workspace files or folders",imageDescription:"Attach an image to the next message",skillsDescription:"Insert a skill mention",goalDescription:"Track this request until completion",compactDescription:"Compress the current session context",initDescription:"Generate or update workspace instructions"},Ik={remove:"Remove",targetBtwDraft:"Side question",targetBtwThread:"Side session",goalDraft:"Goal mode",goalActive:"Goal active",goalPaused:"Goal paused",goalPending:"Goal pending",promptTemplate:"Prompt"},Mk={included:"Spreadsheet focus included",excluded:"Spreadsheet focus excluded",includeAction:"Include with next message",excludeAction:"Exclude from next message",partialCache:"Selection preview is incomplete; the agent will re-read the range",staleFormulas:"Selected formula results are stale; recalculate before trusting them",modes:{inspect:"Inspect",edit:"Edit",author:"Author"}},jk="Expert Mode",Ek="Designer Mode",Lk="WIP",$k="Send to",Ok="Conversation target",Bk="Main",Wk="Side",zk="Main session: {{title}}",Uk="Side session: {{title}}",Hk={Runno:"Runno: native general execution for planning, automation, implementation, and verification","bitfun-coder":"BitFun Coder: builds, debugs, automates, and verifies software changes","bitfun-plan":"Plan: clarify requirements and create an implementation plan before coding","bitfun-debug":"Debug: diagnose code issues with evidence and focused repair steps","bitfun-team":"Team: coordinate software delivery through a team-style workflow",Cowork:"Cowork Assistant: clarify first, track progress lightly, verify outcomes anytime",Design:"Designer: create HTML prototypes, visual artifacts, and polished design deliverables",ComputerUse:"Dedicated desktop automation agent for perceiving and operating apps, browsers, and OS UI",DeepResearch:"Deep research with parallel sub-agents: dispatches multiple agents to investigate concurrently, producing comprehensive sourced reports",AppBuilder:"App Builder: designs Product Apps with work objects, surfaces, components, and runtime feedback"},qk={Runno:"Runno","bitfun-coder":"BitFun Coder","bitfun-plan":"Plan","bitfun-debug":"Debug","bitfun-team":"Team",Cowork:"Cowork Assistant",Design:"Designer",ComputerUse:"Computer Use",DeepResearch:"Deep Research",AppBuilder:"App Builder"},Vk="Open folder…",Gk="Select workspace directory",Kk="Failed to switch workspace: {{error}}",Qk="Switch agent",Jk={title:"Set up an AI model",message:"This session is ready, but an enabled primary AI model is required before you can send a message.",action:"Open model settings"},Yk={deciding:"Agentic OS is choosing a path",creating_work:"Creating Work",needs_input:"Needs your input before taking over",failed:"Handoff did not complete",cancelled:"Handoff cancelled"},Zk={settingsPlaceholder:Ub,addBoostTooltip:Hb,boostStartBtw:qb,boostAddContext:Vb,boostSkills:Gb,boostSkillsLoading:Kb,boostSkillsEmpty:Qb,boostSkillsNoMatch:Jb,boostSkillsSearch:Yb,boostSkillsSuites:Zb,boostSkillsStandalone:Xb,expandSkillSuite:ek,collapseSkillSuite:tk,skillSelected:nk,openSkillsLibrary:ok,resetToAgentic:sk,quickAction:ik,compactAction:ak,compactNoSession:rk,compactBusy:lk,compactUsage:ck,compactFailed:dk,initAction:uk,goalAction:pk,goalNoSession:mk,goalUnsupported:gk,goalFailed:hk,goalEmpty:fk,initNoSession:yk,initBusy:wk,initUsage:vk,initFailed:bk,initPrompt:kk,scanHostPrompt:Sk,currentAgent:xk,noMatchingAgent:Ck,noMatchingCommand:Ak,selectHint:_k,current:Tk,loadingMcpPrompts:Pk,mcpPromptMissingArgs:Fk,mcpPromptFailed:Rk,agentUnavailable:Nk,composerCommands:Dk,intentChips:Ik,spreadsheetFocus:Mk,professionalMode:jk,designMode:Ek,wip:Lk,sendTarget:$k,conversationTarget:Ok,targetMain:Bk,targetBtw:Wk,sendingToMain:zk,sendingToBtw:Uk,agentDescriptions:Hk,agentNames:qk,openFolder:Vk,selectWorkspaceTitle:Gk,switchWorkspaceFailed:Kk,switchAgent:Qk,modelRequired:Jk,osHandoff:Yk},Xk={time:{justNow:"Just now",minutesAgo:"{{count}} min ago",hoursAgo:"{{count}} h ago"},lockAge:{seconds:"{{count}} s",minutes:"{{count}} min",hours:"{{count}} h"},phase:{scaffold:"Scaffold",finishing:"Finishing",sampling:"Sampling",iterating:"Iterating"},emptyTitle:"Design canvas",emptySubtitle:"No artifact loaded yet. It will appear here after the Design agent makes changes.",loadingFile:"Loading file…",diffFrom:"From",diffTo:"To",diffCurrentWorkingCopy:"Current (working copy)",diffNoSnapshots:"No snapshots yet — Diff compares two saved versions.",historyTitle:"Version history",historyEmpty:"No snapshots yet. Ask the agent to call DesignArtifact.snapshot, or use the camera button for a manual snapshot; 45 seconds after your last edit an auto snapshot is also queued.",lockBanner:{stale:"Lock expired",agentEditing:"Agent is editing this artifact",holderLead:" (holder: ",heldFor:", held for {{duration}}",suffixStale:") — safe to take over",suffixReadOnly:") — code is read-only",takeOver:"Take over",takeOverNote:"Take over expired lock"},notifications:{copyContextOk:"Copied selection context",copyContextFail:"Copy failed",openExternalFail:"Open failed: could not preview in an external app",agentEditingBlocked:"Agent is editing this artifact (holder: {{holder}})",saved:"Saved",versionConflict:"Version conflict: the artifact was updated elsewhere. Refresh and try again.",editLocked:"Artifact is locked. Release the lock before saving.",saveFailed:"Save failed: {{message}}",snapshotOk:"Snapshot created",snapshotFailed:"Snapshot failed: {{message}}",snapshotPathPrefix:"Snapshot created: ",exportToPrefix:"Exported to ",exportDesignFolder:"Exported to .design/",exportingTitle:"Exporting",exportHtmlMessage:"Preparing HTML file…",exportZipMessage:"Packaging Zip…",exportFailed:"Export failed: {{message}}",screenshotInfo:"Screenshot export needs a background renderer; main-thread capture is disabled to avoid freezing the UI.",skillExportInserted:"Inserted {{format}} export instruction into chat",lockReleased:"Lock released",lockAcquired:"Edit lock acquired",lockToggleFailed:"Lock action failed: {{message}}",takeoverLockOk:"Edit lock taken over",takeoverLockFail:"Takeover failed: {{message}}"},snapshot:{autoSummary:"Auto snapshot (debounced edit)",promptMessage:"Snapshot note (optional):",promptDefault:"Manual snapshot",manualSummaryDefault:"Manual snapshot"},lock:{manualAcquireNote:"Manual lock from UI"},savingHint:"Writing {{path}}…",mode:{preview:"Preview",code:"Code",split:"Split",diff:"Diff",history:"History"},pickerTitle:"Pick element",inspectorTitle:"Inspector",snapshotTitle:"Snapshot + thumbnail",continueTitle:"Continue with Agent",continueLabel:"Continue",snapshotLabel:"Snapshot",releaseLockTitle:"Release lock ({{holder}})",acquireLockTitle:"Acquire edit lock",exportTitle:"Export",exportEntryHtml:"Entry HTML",exportZip:"Zip bundle",exportScreenshotPng:"Screenshot PNG",exportPdf:"Export PDF",exportPptx:"Export PPTX",openExternalTitle:"Open in external app",selectedLabel:"Selected",diffLoading:"Loading diff…",diffLoadFailed:"Failed to load diff: {{message}}",diffLabelCurrent:"current"},eS={tabElement:"Element",tabTokens:"Tokens",tabAssets:"Assets",elementHint:"Enable the picker in the toolbar, then click any element in the preview to see computed styles.",path:"Path",text:"Text",box:"Box",computedStyles:"Computed styles",noStyleData:"No style data",copyContext:"Copy selection context",tokensHead:"Design tokens",noCssVariables:"No CSS custom properties found on the document root.",assetKind:{page:"Pages",style:"Styles",script:"Scripts",data:"Data",image:"Images",font:"Fonts",other:"Other"}},tS={searchPlaceholder:"Search artifacts…",showArchived:"Show archived",loading:"Loading artifacts…",emptyTitle:"No design artifacts in this workspace yet",emptyHint:"Ask the Design agent to create one — it will show up here when ready.",fileCount:"{{count}} files",snapshotCount:"{{count}} snapshots",openInCanvas:"Open in canvas",archive:"Archive",unarchive:"Unarchive"},nS={commitOk:"Token set adopted",commitFail:"Adopt failed: {{message}}",saveOk:"Token edits saved",saveFail:"Save failed: {{message}}",empty:"No token proposals yet. Ask the Design agent to generate directions first.",sidebarTitle:"Directions",adoptedBadge:"Adopted",proposalCount:"{{count}} directions",eyebrow:"Design tokens",recommit:"Readopt",adopt:"Adopt this set",editorTitle:"Edit token proposal",editorHint:"Adjust the selected design direction. Saved edits update tokens.json and the preview immediately.",editorName:"Name",editorMood:"Mood",saveEdits:"Save edits",revert:"Revert",typeScale:"Type scale",fontWeight:"Font weight",motionDuration:"Motion duration",palette:"Palette",tokenCount:"{{count}} tokens",typography:"Typography",emptySectionSchemaDefaults:"Preview only: default values from the token schema until this section is filled in the proposal.",typeRole:{display:"Display",headline:"Headline",title:"Title",body:"Body",caption:"Caption"},noTypeScale:"No font size scale defined",radius:"Radius",shadow:"Shadow",spacing:"Spacing",noSpacingScale:"No spacing scale defined",componentPreview:"Component preview",previewPairCaption:"Light surface / Dark surface",nativeLight:"Light canvas (palette native)",nativeDark:"Dark canvas (palette native)",stressDark:"Dark canvas (stress test)",stressLight:"Light canvas (stress test)",previewNativeDesc:"Rendered with the palette as declared in tokens.json.",previewStressDesc:"Stress test on the opposite lightness - check text, borders, and accents still read well.",btnPrimary:"Primary",btnSecondary:"Secondary",btnGhost:"Ghost",fieldEmail:"Email",fieldNotify:"Notifications",pillAccent:"Accent",pillMuted:"Muted",pillOutline:"Outline",statRadius:"Radius",statShadow:"Shadow",statMotion:"Motion",typeSample:"The quick brown fox jumps over the lazy dog",previewNavAria:"Preview navigation",previewNavOverview:"Overview",previewNavDesign:"Design",previewNavSettings:"Settings",previewAppTitle:"Product console",previewMetricHealth:"Health",previewMetricTasks:"Tasks",previewMetricRisk:"Risk",previewActivityTitle:"Workflow",previewFormTitle:"Audience settings",previewStatusSuccess:"Healthy",previewStatusWarning:"Needs review",previewStatusDanger:"Blocked",previewLandingNavAction:"Contact",previewLandingTitle:"Shape the first impression",previewLandingNativeDesc:"A sparse landing-page read of the same tokens: whitespace, headline weight, surface color, and primary action.",previewLandingStressDesc:"The same sparse landing composition on the opposite lightness, useful for checking tone before component density.",previewLandingProofOne:"Primary voice",previewLandingProofTwo:"Accent detail",previewLandingProofThree:"Trust signal",previewBitfunNavAria:"Sparo OS site navigation",previewBitfunNavAgents:"Agents",previewBitfunNavWorkflows:"Workflows",previewBitfunNavDocs:"Docs",previewBitfunNavCta:"Get started",previewBitfunEyebrow:"Sparo OS · Agentic OS",previewBitfunHeadingPrefix:"The operating system for the ",previewBitfunHeadingSuffix:" AI era",previewBitfunNativeDesc:"Sparo OS orchestrates reasoning, execution and memory into one agentic runtime — so every decision becomes a composable action.",previewBitfunStressDesc:"The same brand language at the opposite lightness — sanity-check headline tone, CTA contrast, and orchestration rhythm before density.",previewBitfunCtaPrimary:"Launch an agent",previewBitfunCtaSecondary:"View architecture",previewBitfunTagOne:"Reasoning",previewBitfunTagTwo:"Execution",previewBitfunProofOne:"built-in agents",previewBitfunProofTwo:"Open source",previewBitfunProofThree:"Local-first runtime",previewBitfunRuntimeHealthy:"Runtime healthy",previewBitfunNavConsoleAgents:"Agents",previewBitfunNavConsoleWorkflows:"Workflows",previewBitfunNavConsoleRuntime:"Runtime",previewBitfunConsoleTitle:"Agent orchestration overview",previewBitfunConsoleDesc:"See every live agent, pending approval and runtime signal in a single console.",previewBitfunConsoleDeploy:"Deploy agent",previewBitfunConsoleLogs:"Open logs",previewBitfunMetricActive:"Active agents",previewBitfunMetricTasks:"Tasks today",previewBitfunMetricAlerts:"Alerts",previewBitfunAgentKicker:"Current agent",previewBitfunAgentTitle:"Research · market pulse",previewBitfunFieldEndpoint:"Runtime endpoint",previewBitfunFieldAutoApprove:"Auto-approve",previewBitfunAlertRunning:"Running · 3",previewBitfunAlertQueued:"Queued · 2",previewBitfunAlertReview:"Review · 1",previewBitfunTimelineAria:"Agent runtime timeline",previewBitfunTimelineKicker:"Runtime timeline",previewBitfunTimelineStepOne:"User intent received · routed",previewBitfunTimelineStepTwo:"Research agent · gathering context",previewBitfunTimelineStepThree:"Execution agent · landing workflow",previewBitfunDownloadBrand:"Sparo OS · Downloads",previewBitfunDownloadTitle:"Download Sparo OS",previewBitfunDownloadDesc:"The agentic OS for the AI era — local-first, open source, ready in seconds.",previewBitfunDownloadPlatformsAria:"Available platforms",previewBitfunDownloadCta:"Download",previewBitfunDownloadMetaSigned:"Signed release",previewBitfunDownloadMetaChecksum:"SHA-256 verified",previewBitfunDownloadMetaOss:"MIT · open source"},oS={panel:Xk,inspector:eS,browser:tS,studio:nS},sS="New Runno session",iS="New Cowork Assistant session",aS="New Designer session",rS="New Session {{count}}",lS="New Runno Session {{count}}",cS="New BitFun Coder Session {{count}}",dS="New DeepResearch Session {{count}}",uS="New Cowork Assistant Session {{count}}",pS="New Designer Session {{count}}",mS="App Builder {{count}}",gS="Product App Runtime {{count}}",hS="Agentic OS",fS="Session",yS="Chat with {{name}}",wS="Rename Session",vS="Are you sure you want to delete this session?",bS="No Sessions",kS="Untitled Session",SS="Session History",xS="Restoring conversation…",CS="This conversation could not be restored.",AS="Try again",_S="Preparing workspace…",TS="Current Session",PS="Session Management",FS="Close",RS="{{count}} turns",NS="No Session",DS="Switch Session",IS="Create New Session",MS="More Sessions",jS="Restore Main Window",ES={ariaLabel:"Active goal",label:"Goal",pendingObjective:"Extracting goal...",pause:"Pause",resume:"Resume",review:"Review",clear:"Clear",gap:"{{count}} gap",gap_plural:"{{count}} gaps",budget:"{{used}}/{{max}} turns",revision:"r{{revision}}",status:{active:"Active",judging:"Judging",waiting_user:"Waiting",paused:"Paused",blocked:"Blocked",budget_limited:"Budget limited",completed:"Completed",cancelled:"Cancelled"},phase:{extracting:"Extracting",judging:"Judging",active:"Active",waiting_user:"Waiting",paused:"Paused",blocked:"Blocked",budget_limited:"Budget limited",completed:"Completed",cancelled:"Cancelled",failed:"Failed",needs_clarification:"Needs clarification",rejected:"Rejected"},extractionStatus:{queued:"queued",running:"running",accepted:"accepted",needs_clarification:"needs clarification",rejected:"rejected",failed:"failed"},judgeStatus:{queued:"queued",running:"running",decided:"decided",rejected:"rejected",failed:"failed",pass:"passed",continue:"in progress",needs_user:"needs user",blocked:"blocked"}},LS={new:"New Session",newRunno:sS,newCowork:iS,newDesign:aS,newWithIndex:rS,newRunnoWithIndex:lS,newBitfunCoderWithIndex:cS,newDeepResearchWithIndex:dS,newCoworkWithIndex:uS,newDesignWithIndex:pS,newAppBuilderWithIndex:mS,newProductAppRuntimeWithIndex:gS,agenticOs:hS,title:fS,chatWithAgent:yS,rename:wS,delete:"Delete Session",deleteConfirm:vS,empty:bS,untitled:kS,history:SS,loadingHistory:xS,historyLoadFailed:CS,retryHistory:AS,loadingSurface:_S,current:TS,management:PS,close:FS,dialogTurns:RS,noSession:NS,switchSession:DS,create:IS,more:MS,restoreMain:jS,goal:ES},$S={title:"Agent Handoff",agent:"Agent",agentBadge:"Agent",headerLine:"{{agentType}} agent: {{session}}",createdSession:"{{agentType}} agent: {{session}}",reusingSession:"Reusing session: {{session}}",reusedSession:"Reused session: {{session}}",preparingCreate:"Preparing to create {{agent}}",creatingAgent:"Creating {{agent}}...",createdAgent:"Created {{agent}}",actionFailed:"Agent handoff failed",listingWorkspaces:"Listing workspaces...",foundWorkspaces:"Found {{count}} workspace(s)",checkingStatus:"Checking agent status...",statusSessions:"{{count}} active agent session(s)",sessionId:"Session ID",workspace:"Workspace",sessionCount:"{{count}} session(s)",noWorkspaces:"No recent workspaces found",noSessions:"No sessions created in Agentic OS yet",sessionRunning:"Session running",sessionIdle:"Idle",globalTag:"Global",sessionUnavailable:"This agent session is no longer available. It may have been deleted.",openSessionFailed:"Unable to open this agent session."},OS={title:"Work",untitled:"Untitled Work",ownerDefault:"Agentic OS",open:"Open Work",creating:"Creating Work: {{title}}",continuing:"Continuing Work: {{title}}",controlling:"Updating Work: {{title}}",checking:"Checking Work",started:"Work created: {{title}}",continued:"Work continued: {{title}}",controlled:"Work updated: {{title}}",checked:"Work checked: {{title}}",listedWorks:"Found {{count}} Work item(s)",failed:"Work update failed",cancelled:"Work update cancelled",interrupted:"Work update interrupted",globalWorkspace:"Agentic OS",detail:{objective:"Goal",owner:"Owner",workspace:"Workspace",surface:"Surface",status:"Status",workId:"Work ID",controlAction:"Control"},surface:{os_agent_home:"Agentic OS",work_session:"Work session",agent_session:"Agent session",application_surface:"Application",work_center:"Work Center"},status:{draft:"Draft",active:"Active",running:"Running",waiting_user:"Needs input",blocked:"Blocked",paused:"Paused",completed:"Completed",failed:"Failed",cancelled:"Cancelled",interrupted:"Interrupted",archived:"Archived"}},BS={title:"Goal",untitled:"Active goal",failed:"Goal update failed: {{error}}",unknownError:"Unknown error",cancelled:"Goal update cancelled",interrupted:"Goal update interrupted",accepted:"Accepted",notAccepted:"Not accepted",revision:"r{{revision}}",gapCount:"{{count}} gap",summary:{get:"Checked goal status",note:"Recorded a progress note",blocked:"Reported a blocker"},pending:{get:"Checking goal status...",note:"Recording a note...",blocked:"Reporting a blocker..."},sections:{blocker:"Blocker",progressNote:"Progress note",note:"Note",judgment:"Judgment",remainingGaps:"Remaining gaps"},statuses:{active:"Active",judging:"Judging",waiting_user:"Waiting on user",paused:"Paused",blocked:"Blocked",budget_limited:"Budget limited",completed:"Completed",cancelled:"Cancelled"},judgeStates:{pass:"Passed",continue:"In progress",needs_user:"Needs user",blocked:"Blocked"}},WS={title:"Memory",preparing:"Preparing memory",saving:"Saving memory",saved:"Memory saved",savedWithType:"Saved {{type}}:",failed:"Memory save failed",cancelled:"Memory save cancelled",interrupted:"Memory save interrupted",remembered:"Remembered",appliesTo:"Applies to",scopes:{global:"Global memory",workspace:"This project",unknown:"Memory"},types:{user:"user memory",feedback:"feedback",project:"project memory",reference:"reference",memory:"memory",unknown:"memory"}},zS={title:"Outcome Review",preparing:"Preparing outcome review",receiving:"Receiving review verdict...",submitting:"Submitting review verdict...",submitted:"Outcome review submitted",failed:"Outcome review failed: {{error}}",unknownError:"Unknown error",cancelled:"Outcome review cancelled",interrupted:"Outcome review interrupted",verdict:"Verdict",risk:"Risk",confidence:"Confidence",workId:"Work ID",finalEffect:"Final Effect",nextStep:"Next Step",revisionInstruction:"Revision instruction",acceptanceChecks:"Acceptance Checks",checkSummary:"{{passed}} passed, {{unresolved}} unresolved, {{total}} total",issues:"Issues ({{count}})",verificationGaps:"Verification Gaps",evidence:"Evidence",reasoning:"Reasoning",impact:"Impact",suggestedNextStep:"Next step",unnamedCheck:"Acceptance check",untitledIssue:"Issue",verdictFallback:"Review",riskFallback:"Risk",confidenceFallback:"Confidence",nextActionFallback:"Next Action",checkStatusFallback:"Status",severityFallback:"Severity",verdicts:{pass:"Pass",pass_with_notes:"Pass with notes",needs_revision:"Needs revision",failed:"Failed",inconclusive:"Inconclusive",unknown:"Review"},riskLevels:{low:"Low risk",medium:"Medium risk",high:"High risk",unknown:"Risk"},confidenceLevels:{high:"High confidence",medium:"Medium confidence",low:"Low confidence",unknown:"Confidence"},checkStatuses:{passed:"Passed",failed:"Failed",partial:"Partial",unverified:"Unverified",unknown:"Status"},severities:{blocker:"Blocker",major:"Major",minor:"Minor",unknown:"Severity"},nextActions:{report_to_user:"Report to user",continue_work:"Continue Work",start_specialist_review:"Specialist review",ask_user:"Ask user",stop:"Stop",unknown:"Next Action"}},US={write:"Write File",edit:"Edit File",delete:"Delete File",deletedLabel:"Deleted",failed:"Failed",parsingPath:"Parsing file path...",unknownFile:"Unknown file",receivingParams:"Receiving parameters...",analyzing:"Analyzing...",expandPreview:"Expand preview",collapsePreview:"Collapse preview",viewGitDiff:"View Diff",viewBaselineDiff:"View Baseline Diff",openInEditor:"Open in editor"},HS={action:"File plan",planning:"Planning file operations...",unavailable:"No reviewed plan available",failed:"File operation planning failed",summary:"{{title}} - {{count}} item(s)",highRisk:"{{count}} high risk",conflicts:"{{count}} conflicts",moreItems:"{{count}} more item(s)",reviewInFiles:"Review in Files"},qS={action:"Config plan",planning:"Planning configuration...",unavailable:"No config plan available",failed:"Configuration planning failed",summary:"{{count}} proposed change(s)",applied:"{{count}} change(s) applied",rolledBack:"{{count}} change(s) rolled back",blocked:"{{count}} question(s) before changes",previewOnly:"Preview only",canApply:"Can apply",appliedBadge:"Applied",rolledBackBadge:"Rolled back",patchCount:"{{count}} change(s)",warningCount:"{{count}} warning(s)",questionsPending:"{{count}} question(s) need an answer",requiresConfirmation:"Requires confirmation",effectUnknown:"effect unknown",masked:"masked",morePatches:"{{count}} more change(s)",risk:{low:"Low",medium:"Medium",high:"High"}},VS={summaryLine:"{{action}}: {{summary}}",actions:{query:"Find settings",get:"Read setting",unknown:"Check settings"},status:{searching:"Finding settings related to the request…",reading:"Reading this setting…",matched:"Found {{count}} setting(s) related to the request",readOne:"Read this setting",readOneNamed:"Read the “{{name}}” setting",failed:"Could not find related settings",cancelled:"Stopped finding settings"},results:{listLabel:"Settings found",currentValue:"Current value",unnamed:"Unnamed setting",otherLocation:"Other settings",configured:"Configured",notConfigured:"Not configured",defaultValue:"Using default",notSet:"Not set",enabled:"On",disabled:"Off",itemCount:"{{count}} item(s)"}},GS={title:"Settings change",status:{plan:{running:"Checking the related settings...",confirming:"Reviewing {{count}} proposed change(s)",completed:"Prepared {{count}} setting change(s)",failed:"Could not prepare the settings change",cancelled:"Settings check cancelled"},apply:{running:"Applying {{count}} setting change(s)...",confirming:"Will apply {{count}} change(s)",completed:"Applied {{count}} setting(s)",failed:"Could not apply the settings change",cancelled:"Settings change cancelled"},undo:{running:"Restoring {{count}} setting change(s)...",confirming:"{{count}} setting change(s) will be restored",completed:"Restored {{count}} setting change(s)",failed:"Could not restore the settings",cancelled:"Settings restore cancelled"},unknown:{running:"Preparing the settings change...",confirming:"Settings change is waiting for confirmation",completed:"Settings change completed",failed:"Settings change failed",cancelled:"Settings change cancelled"},result:{applying:"Settings saved and still taking effect",partial:"Some settings could not take effect",restartRequired:"Applied {{count}} change(s); {{restartCount}} require a restart",rolledBack:"Rolled back {{count}} setting change(s)",undone:"Undid {{count}} setting change(s)"}},actions:{viewManual:"View in manual settings",cancel:"Cancel",undo:"Undo",undoing:"Undoing…",confirm:{plan:"Confirm",apply:"Apply changes",undo:"Restore settings",unknown:"Confirm"}},values:{enabled:"On",disabled:"Off",notSet:"Not set",empty:"Empty",updated:"Updated"},comparison:{before:"Current",after:"After change"},sectionFallback:"Other settings",sectionChangeCount:"{{count}} change(s)",secret:{configured:"Configured",unconfigured:"Not configured",willUpdate:"Will be updated"},risks:{safe:"Low risk",elevated:"Confirmation required",destructive:"Not permitted"},effects:{reactive:"Takes effect now",adapter:"Takes effect now",restartRequired:"Takes effect after restart",manualOnly:"Complete manually",mixed:"Mixed activation"},receipts:{pending:"Taking effect",applied:"In effect",restartRequired:"Takes effect after restart",failed:"Could not take effect",superseded:"Replaced by a newer change",rolledBack:"Rolled back"},warningCount:"{{count}} item(s) need attention",previewUnavailable:"The verified change preview is no longer available. Cancel this action and ask the assistant to prepare it again.",partialNotice:"The configuration was saved, but one or more runtime components could not apply it. Review the affected items before retrying.",errors:{config:{manual_draft_conflict:"A related field has an unsaved manual edit. Save or discard it, then try again.",revision_conflict:"The settings changed after this preview was prepared. Ask the assistant to check them again.",catalog_changed:"The settings catalog changed. Ask the assistant to prepare a new preview.",plan_expired:"This change preview expired. Ask the assistant to prepare it again.",confirmation_required:"This change still requires confirmation.",idempotency_conflict:"This settings request conflicts with an earlier request. Please try again.",undo_conflict:"These settings changed after the original update and cannot be restored safely.",undo_token_invalid:"This settings change can no longer be restored.",commit_unknown:"The original settings change is no longer available.",apply_retry_failed:"The settings could not be applied to the running app.",scope_unsupported:"This settings scope is not supported.",setting_unavailable:"One of these settings is no longer available.",setting_managed:"One of these settings is managed elsewhere and cannot be changed here.",recovery_read_only:"Settings are temporarily read-only while configuration recovery is active.",operation_failed:"The settings operation failed. No unverified details were applied."},ai:{model_not_configured:"Configure and enable a primary AI model before using AI settings."}}},KS={diffFile:"Diff",gettingDiff:"Getting diff",preparing:"Preparing diff",failed:"Diff failed"},QS={headerTooltip:"Generative UI",exportFileNamePrefix:"Sparo-GenerativeUI"},JS={title:"Git",commandFailed:"Git command failed",executionFailed:"Git command execution failed",failed:"Failed",confirmExecute:"Confirm execute",cancel:"Cancel",expandOutput:"Expand output",collapseOutput:"Collapse output",noOutput:"(no output)",exitCode:"Exit code: {{code}}",duration:"Duration: {{time}}",directory:"Directory: {{dir}}",output:"Output:",warning:"Warning:",error:"Error:",operation:"Operation: git {{op}}",args:"Args: {{args}}",status:"Status",diff:"Diff",log:"Log",add:"Stage",commit:"Commit",branch:"Branch",checkout:"Checkout",switch:"Switch",pull:"Pull",push:"Push",fetch:"Fetch",merge:"Merge",rebase:"Rebase",stash:"Stash",reset:"Reset",restore:"Restore",show:"Show",tag:"Tag",remote:"Remote",clone:"Clone",init:"Init",blame:"Blame",cherryPick:"Cherry-pick"},YS={title:"Product App Surface",operationInit:"Init",skeletonReady:"Ready",creatingShort:"…",untitled:"(unnamed)",failed:"Failed",createFailed:"Could not create Product App surface",labelAppId:"app_id",labelVersion:"version",labelPrimarySurface:"primary surface",labelSurfaceMode:"surface mode",labelLaunchKind:"launch",labelLockDigest:"lock digest",labelPath:"path",nameLabel:"App: {{name}}"},ZS={title:"Product App Surface",builderTitle:"App Builder",recompile:"Recompile",probe:"Probe",matrix:"Matrix",syncing:"Syncing",compiledSize:"{{size}}",probeSummary:"{{fatal}} fatal · {{warning}} warning · {{noise}} noise",matrixRequested:"Matrix requested",matrixStates:"{{count}} states",openBuilder:"Open App Builder"},XS={title:"Validate",componentTitle:"Validate component",validating:"Validating",package:"Product App package",componentPackage:"Component package",status:"status",failed:"failed",warnings:"warnings",appId:"app_id",componentId:"component_id",componentKind:"component kind",version:"version",path:"path",check:"check",failedMessage:"Product App validation failed"},ex={title:"Preview",running:"Running preview",target:"target",status:"status",mode:"mode",failed:"failed",warnings:"warnings",check:"check",failedMessage:"Builder preview failed"},tx={title:"Component Package",list:"Catalog",inspect:"Inspect",validate:"Validate",createPackage:"Create package",create:"Create",update:"Update",tools:"Tool options",jsTool:"JS tool",testJsTool:"Test JS tool",generic:"Authoring",scanning:"Scanning…",loading:"Loading…",validating:"Validating…",validOk:"Manifest is valid",validFailed:"Validation failed",creatingJsTool:"Creating JS tool…",testing:"Testing…",testingNamed:"Testing {{name}}…",testPass:"passed",testFail:"failed",appsCount:"{{count}} agent components",toolsCount:"{{count}} tools",moreApps:"{{count}} more apps not shown",moreTools:"{{count}} more tools not shown",unnamed:"(unnamed)",readonly:"readonly",fieldName:"name",fieldDescription:"description",fieldKind:"kind",fieldVersion:"version",fieldModel:"model",fieldCategory:"category",fieldReadonly:"readonly",fieldTools:"tools",fieldTags:"tags",fieldExamples:"examples",fieldPath:"path",fieldToolName:"tool name",fieldSummary:"summary",openAppsPanel:"Open Component Center",openBuilderPanel:"Open in App Builder",previewPanelTitle:"App Builder"},nx={title:"Bridge",preparing:"Preparing {{capability}}",running:"Running {{capability}} · {{action}}",completed:"Completed {{capability}} · {{action}}",failed:"Bridge call failed for {{capability}}",unknownCapability:"unknown capability",unknownAction:"action",bridgeId:"Bridge ID",capabilityId:"Capability ID",action:"Action",mode:"Mode",runId:"Run ID",status:"Status",output:"Output",stderr:"stderr"},ox={executeCommand:"Execute command:",commandEmpty:"[Command empty - please edit]",noCommand:"[No command]",receivingCommand:"Receiving command...",commandUnavailable:"Command unavailable",clickToEditCommand:"Click to edit command",inputPlaceholder:"Enter command...",commandEmptyWarning:"Command is empty, cannot execute",commandStillReceivingWarning:"Command is still being received",executeCommandTitle:"Execute command",cancel:"Cancel",interrupt:"Interrupt command",openInPanel:"Open Terminal in panel",expandOutput:"Expand output",collapseOutput:"Collapse output",rejected:"Rejected",cancelled:"Cancelled",completed:"Completed",failed:"Execution failed",receivingParams:"Receiving parameters...",executingCommand:"Executing command...",workingDirectory:"Working directory:",exitCode:"Exit code: {{code}}",commandInterrupted:"Command interrupted",executionFailed:"Command execution failed"},sx={loadingPlan:"Loading plan...",generating:"Generating...",clickToOpenPlan:"Click to open plan file",remainingTodos:"{{count}} Remaining To-dos",viewPlan:"View Plan",build:"Build",building:"Building...",built:"Built"},ix={confirm:"Confirm",cancel:"Cancel",loading:"Loading...",success:"Success",failed:"Failed",error:"Error",expand:"Expand",collapse:"Collapse",collapseContent:"Collapse content",expandContent:"Expand content",copy:"Copy",copied:"Copied",copyJson:"Copy JSON",truncated:"Truncated",inputParams:"Input Parameters",executionResult:"Execution Result",viewDetails:"View Details",interruptedByRestart:"This tool was still running when the app closed last time, so it has been restored as interrupted"},ax={headerAction:"Ask user",completed:"Completed",submittedWaiting:"Submitted, waiting for processing",submitting:"Submitting...",waitingAnswer:"Waiting for answer",questionsCount:"{{count}} questions",answerAllBeforeSubmit:"Please answer all questions before submitting",submit:"Submit",questionsAnswered:"{{count}} questions answered",notAnswered:"Not answered",timeout:"Timeout (10 minutes)",parseError:"Unable to parse question data",validationError:"Validation failed",loadingQuestions:"Receiving questions…",other:"Other",customInputHint:"Provide custom text input",pleaseSpecify:"Please specify..."},rx={analysis:"Thinking Analysis",thinking:"Thinking...",preparing:"Preparing to think",thinkingProcess:"Thinking Process",thinkingComplete:"Thinking complete",thinkingCharacters:"Thought {{count}} characters"},lx={parsingSearchTerm:"Parsing search term...",searchTitle:'Web Search: "{{term}}"',resultsCount:"{{count}} results",searching:'Searching "{{term}}"...',preparingSearch:'Preparing to search "{{term}}"',clickToOpenLink:"Click to open link",noTitle:"No title"},cx={parsingUrl:"Parsing URL...",fetched:"Fetched",fetching:"Fetching",preparing:"Preparing to fetch",openLink:"Open link",copyContent:"Copy content"},dx={tasksCount:"{{count}} tasks",progress:"({{completed}}/{{total}} completed)",allCompleted:"All tasks completed",tasks:"Tasks",collapseList:"Collapse list",expandList:"Expand list"},ux={headerLine:"{{agentType}} agent: {{description}}",defaultAgentKind:"Sub-agent",waitingConfirm:"Waiting for confirmation",executing:"Executing...",subAgentFailed:"Sub-agent task execution failed",subAgentTaskFailed:"Sub-agent task failed",failed:"Failed",confirmDelegate:"Confirm Delegate",cancel:"Cancel",task:"Task",agent:"Agent",collapseDetails:"Collapse details",expandDetails:"Expand details",openInPanel:"Open details in panel"},px={untitled:"Untitled Task",statusLabel:"Status",promptLabel:"Task Prompt",errorLabel:"Error",resultLabel:"Result",noData:"Unable to load task data",executionContent:"Execution Content",duration:"Duration",status:{pending:"Pending",running:"Running",completed:"Completed",failed:"Failed"}},mx={interactive:"Interactive diagram:",preparing:"Preparing",creating:"Creating"},gx={get:"Get Template:",getTemplate:"Get Template",loading:"Loading",loaded:"Loaded",templateDetails:"Template Details",templateId:"Template ID:",templateName:"Template Name:",contentSize:"Content Size:",characters:"{{count}} characters",templateReady:"Template Ready",templateReadyDesc:"Template structure loaded successfully, ready for requirements document creation",templateLoadFailed:"Template loading failed",requirementFramework:"Requirement Framework Overview",productVision:"Product Vision",businessGoals:"Business Goals",userPersonas:"User Personas",userStories:"User Stories",featureList:"Feature List",functionalSpecTemplate:"Functional Specification Template",nonFunctionalRequirements:"Non-functional Requirements",acceptanceCriteria:"Acceptance Criteria"},hx={confirmExecute:"Confirm Execute",cancel:"Cancel",loadingApp:"Loading interactive app...",appLoadError:"Failed to load app",interactiveApp:"interactive app",actionLabel:"MCP:",failedLabel:"MCP failed",executionFailed:"MCP execution failed"},fx={operationFailed:"Design artifact operation failed",defaultTitle:"Design artifact",openInCanvas:"Open in canvas",writing:"Writing",manifestSubtitle:"{{kind}} · {{filesCount}} files · {{versionsCount}} snapshots",listSubtitle:"{{count}} artifacts",actions:{create:"Create",update_file:"Update file",delete_file:"Delete file",set_entry:"Set entry",snapshot:"Snapshot",acquire_lock:"Acquire lock",release_lock:"Release lock",set_thumbnail:"Update thumbnail",zip_export:"Export zip",archive:"Archive",get:"Get",list:"List"},events:{created:"Created","file-changed":"Updated","file-removed":"Removed","manifest-updated":"Manifest updated","snapshot-committed":"Snapshot saved","lock-acquired":"Locked","lock-released":"Unlocked","thumbnail-updated":"Thumbnail updated",exported:"Exported",archived:"Archived",listed:"Listed",ok:"Done"}},yx={generationFailed:"Design token generation failed.",studioPanelTitle:"Design tokens",cardTitle:"Design direction proposals",currentSystemSummary:"Current token system:",documentsSummary:"Design token documents:",documentCountValue:"{{count}} found",awaitingYourChoice:"Waiting for your choice",adopted:"Adopted",statusTimeout:"Timed out",statusCancelled:"Cancelled",statusInvalid:"Invalid selection",openTokensStudio:"Open tokens studio",untitledProposal:"Untitled proposal",defaultMood:"Design direction",streamingHint:"Proposal still streaming; full preview appears when complete.",previewModeNative:"Native",previewModeInverse:"Inverse",previewPrimary:"Primary",previewGhost:"Ghost",previewPlaceholder:"Placeholder",switchAriaLabel:"Toggle",expand:"Expand",collapse:"Collapse",font:"Type",radius:"Radius",shadow:"Shadow",submitting:"Submitting…",adoptThisSystem:"Adopt this system",switchToThisSystem:"Switch to this",openInStudio:"Open in studio",noCommittedSystem:"No token system committed",errorTitle:"Token direction generation failed",preparingDirections:"Preparing directions…",receivingDirections:"Receiving proposals…",streamingSelectHint:"Receiving proposals — select after transfer completes",reopenSelection:"Reopen selection"},wx={unknownSkill:"Unknown skill",unknown:"Unknown",loadSkillFailed:"Load skill failed",skillAction:"Skill:",loadingSkill:"Loading",preparingSkill:"Preparing to load"},vx={parsingParams:"Parsing parameters...",noFileSpecified:"No file specified",readFile:"Read file",readingFile:"Reading",preparingRead:"Preparing to read"},bx={parsingParams:"Parsing parameters...",fallbackDisplayName:"Another session",lineCompleted:"Read history: {{name}}",lineRunning:"Reading history: {{name}}",linePending:"Preparing to read history: {{name}}"},kx={terminatingSession:"Terminating terminal",sessionKilled:"Terminal killed",killFailed:"Failed to kill terminal",preparingKill:"Preparing to kill terminal",interruptingSession:"Interrupting terminal",sessionInterrupted:"Terminal interrupted",interruptFailed:"Failed to interrupt terminal",preparingInterrupt:"Preparing to interrupt terminal"},Sx={title:"Session",agenticScope:"Agentic OS",defaultSessionName:"New Session",unknownSession:"Unknown session",preparingCreate:"Preparing to create session {{session}}",creatingSession:"Creating session {{session}}",createdSession:"Created session {{session}}",preparingCancel:"Preparing to cancel session {{session}}",cancellingSession:"Cancelling session {{session}}",cancelledSession:"Cancellation requested for {{session}}",noActiveTurn:"{{session}} has no active turn to cancel",preparingDelete:"Preparing to delete session {{session}}",deletingSession:"Deleting session {{session}}",deletedSession:"Deleted session {{session}}",preparingList:"Preparing to list sessions",listingSessions:"Listing sessions",listedSessions:"Found {{count}} sessions",actionFailed:"Session operation failed",workspace:"Workspace",sessionId:"Session ID",sessionName:"Session name",agentType:"Agent type",cancelStatus:"Cancel status",cancelRequestedStatus:"Cancel requested",noActiveTurnStatus:"No active turn",cancelledTurnId:"Cancelled turn ID",hadActiveTurn:"Had active turn",booleanYes:"Yes",booleanNo:"No",sessionCount:"Session count",noSessions:"No sessions found"},xx={title:"Session",unknownSession:"Unknown session",preparingSend:"Preparing to message {{session}}",sendingMessage:"Sending message to {{session}}",messageAccepted:"Message accepted for {{session}}",sendFailed:"Failed to message {{session}}",targetSession:"Target session",workspace:"Workspace",agentType:"Agent type",message:"Message"},Cx={parsingAnalysisInfo:"Parsing analysis info...",unknownImage:"Unknown image",clipboardImage:"Clipboard image",analyzeImageContent:"Analyze image content",imageAnalysis:"Image analysis",completed:"Completed",analyzing:"Analyzing",preparing:"Preparing",analysisPrompt:"Analysis prompt",focusAreas:"Focus areas",analysisResult:"Analysis result"},Ax={beforeUserMessage:"Before user message",toolBatchComplete:"Tool batch complete",manualTrigger:"Manual trigger",autoTrigger:"Auto trigger",contextCompressionFailed:"Context compression failed",contextCompression:"Context compression:",localFallbackHeader:"Model request failed; local structured trimming",localFallbackNotice:"Model-based summary was unavailable, so this compression used local structured truncation.",noSummaryNotice:"No additional summary was generated for this compaction pass."},_x={parsingPattern:"Parsing search pattern...",currentDirectory:"Current directory",searchFile:"Search files",searchingFile:"Searching",preparingSearch:"Preparing to search",filesCount:"{{count}} files",directoriesCount:"{{count}} directories",filesAndDirs:"{{files}} files, {{directories}} directories",moreFiles:"{{count}} more files",labelPattern:"Pattern",labelPath:"Path",labelStats:"Stats"},Tx={parsingPattern:"Parsing search pattern...",currentDirectory:"Current directory",searchText:"Search text",searchingText:"Searching",preparingSearch:"Preparing to search",matchesCount:"{{count}} matches",matchesAndFiles:"{{matches}} matches in {{files}} files",labelPattern:"Pattern",labelPath:"Path",labelStats:"Stats"},Px={parsingOperation:"Parsing operation...",configCenter:"Config Center",planner:"Task Planner",terminal:"Terminal",fileViewer:"File Viewer",codeEditor:"Code Editor",navigateToPosition:"Navigate to position",adjustIdeLayout:"Adjust IDE layout",manageTab:"Manage tab",focusView:"Focus view",executeIdeOperation:"Execute IDE operation",operationType:"Operation type",panelType:"Panel type",configSection:"Config section",sessionId:"Session ID",filePath:"File path",workspacePath:"Workspace",panelPosition:"Panel position"},Fx={parsingParams:"Parsing parameters...",checkFailed:"Check failed:",unknownError:"Unknown error"},Rx={parsingPath:"Parsing path...",listDirectory:"List directory",listingDirectory:"Listing",preparingList:"Preparing to list",filesCount:"{{count}} files",directoriesCount:"{{count}} directories",filesAndDirs:"{{files}} files, {{directories}} directories",moreEntries:"{{count}} more entries",labelPath:"Path",labelStats:"Stats",labelSort:"Sort",sortByModifiedTime:"By modified time (newest first)"},Nx={file:"File",dir:"Directory",code:"Code",img:"Image",cmd:"Command",chart:"Chart",link:"Link"},Dx={pending:"Pending",paramsReceiving:"Receiving params",preparing:"Preparing",running:"Running",completed:"Completed",error:"Failed",cancelled:"Cancelled"},Ix={executing:"Executing...",collapseChat:"Collapse chat",expandChat:"Expand chat",aiProcessing:"AI is processing...",inputMessage:"Enter message...",processing:"Processing...",startNewChat:"Start new chat...",openSessionMenu:"Sessions & new",moreMenu:"More",newBitfunCoderSessionItem:"BitFun Coder session",newCoworkSessionItem:"Cowork Assistant session",newDesignSessionItem:"Designer session"},Mx={inputHint:"Enter content..."},jx={planner:"Planner"},Ex={brand:"PPT Live"},Lx={title:"Design Case",awaiting:"Your decision",approved:"Approved",revisionRequested:"Revision requested",preparing:"Preparing three real sample pages",failure:"The Design Case decision could not be recorded.",errorTitle:"Design Case unavailable",direction:"Visual direction",density:"Information density",audienceFit:"Audience fit",inferred:"Inferred from the topic",previewAlt:"Design Case preview: {{title}}",guidance:"Judge the system across all three pages: palette, typography, density, visual grammar, and rhythm. This decision applies to the whole deck.",approveAction:"Approve direction",adjustColor:"Adjust color",adjustDensity:"Adjust density",adjustLanguage:"Change visual language",feedbackPlaceholder:"Describe one systemic change for the whole deck...",submitFeedback:"Request revision",revisionColorFeedback:"Revise the whole Design Case with a more appropriate color direction while preserving the argument and page roles.",revisionDensityFeedback:"Revise the whole Design Case with a more appropriate information density and reading rhythm.",revisionLanguageFeedback:"Revise the whole Design Case with a different visual language and composition grammar.",approvedReceipt:"The Design Case is approved. Full visual production may now continue against this system.",revisionReceipt:"A systemic Design Case revision was requested. Full visual production remains blocked until a new case is approved."},$x={rollback:"Rollback",rollbackTooltip:"Rollback to this turn"},Ox={reviewResult:"Review Result",reviewingCode:"Reviewing code...",preparingReview:"Preparing code review",reviewFailed:"Code review failed: {{error}}",unknownError:"Unknown error",collapseDetails:"Collapse Details",expandDetails:"Expand Details",overallAssessment:"Overall Assessment",riskLevel:"Risk Level",recommendedAction:"Recommended Action",contextLimitations:"Context Limitations",issuesCount:"Issues ({{count}})",suggestion:"Suggestion",codeStrengths:"Code Strengths",riskLevels:{low:"Low Risk",medium:"Medium Risk",high:"High Risk",critical:"Critical Risk"},actions:{approve:"Approve",approve_with_suggestions:"Approve with Suggestions",request_changes:"Request Changes",block:"Block Merge"},severities:{critical:"Critical",high:"High",medium:"Medium",low:"Low",info:"Info"},certainties:{confirmed:"Confirmed",likely:"Likely",possible:"Possible"}},Bx={agentHandoff:$S,work:OS,goal:BS,memory:WS,outcomeReview:zS,file:US,fileOperationPlan:HS,configPlan:qS,settingsCatalog:VS,settingsChange:GS,getFileDiff:KS,generativeWidget:QS,git:JS,createProductApp:YS,appBuilder:ZS,productAppValidation:XS,productAppPreview:ex,componentAuthoring:tx,bridgeCall:nx,terminal:ox,plan:sx,common:ix,askUser:ax,think:rx,webSearch:lx,webFetch:cx,todoWrite:dx,taskTool:ux,taskDetailPanel:px,diagram:mx,template:gx,mcp:hx,default:{waitingConfirm:"Waiting for confirmation",executing:"Executing...",completed:"Completed",cancelled:"Cancelled",failed:"Execution failed",preparing:"Preparing"},designArtifact:fx,designTokens:yx,skill:wx,readFile:vx,sessionHistory:bx,terminalControl:kx,sessionControl:Sx,sessionMessage:xx,imageAnalysis:Cx,contextCompression:Ax,globSearch:_x,grepSearch:Tx,ideControl:Px,linter:Fx,ls:Rx,userMessage:Nx,toolStatus:Dx,toolbar:Ix,chatInput:Mx,plannerButton:jx,pptLive:Ex,pptDesignCase:Lx,turnRollback:$x,codeReview:Ox},Wx="Good morning",zx="A new day, new possibilities. Let's create something together",Ux="Good afternoon",Hx="A new day, new possibilities. Let's create something together",qx="Good evening",Vx="Quiet nights are perfect for immersive coding",Gx="Late night",Kx="Inspiration never sleeps. Let's keep going",Qx="Coding partner",Jx="A single line is plenty for a start.",Yx="Bring it in whatever shape it has. Runno will catch it.",Zx="The light is still on; things can move gently.",Xx="Quiet hours are good for soft landings.",eC="Runno",tC="Morning clarity is the best. Let's shape your ideas and tasks for today",nC="Afternoon check-in — anything to push forward or organize?",oC="Wrap up, reflect, or set the stage for tomorrow — all good here",sC="Late nights are great for planning and clearing your head",iC="Cowork Assistant",aC="Fresh eyes help. Let's turn your concept into something tangible today",rC="Perfect time to refine a flow, prototype an idea, or explore new directions",lC="Let's polish the details, compare options, and make the design feel right",cC="Quiet hours are perfect for visual thinking and careful craft",dC="Designer",uC="Research partner",pC="Clarify the question and scope — I'll run parallel lookups and help synthesize sources",mC="Good window to go deep: map viewpoints, compare evidence, and shape a solid brief",gC="Quiet hours suit careful reading, fact-checking, and writing a trustworthy synthesis",hC="Long research threads don't punch out — resume whenever you're ready",fC="Agentic OS",yC="What do you want to make happen today?",wC="Perfect timing. Don't waste it.",vC="Daytime ideas don't need daylight.",bC="The serious ones work late.",kC="Tell me what you want. I'll make it happen.",SC="App Builder",xC="Turn a goal into a Product App with the right work object, surface, and components",CC="A good time to shape the workflow, data, and interaction model",AC="Turn today's product idea into an app package you can open again",_C="The idea is awake. Let's give it a product boundary that lasts",TC="Describe the Product App you want: who opens it, what work object it manages, which interaction model it needs, and how AI should help. I will keep the app identity separate from its components.",PC="Settings assistant",FC="What would you like to adjust?",RC="Describe your goal. I will check the relevant settings and explain what will change first.",NC="Describe the outcome you want and I'll find the relevant settings.",DC="Skip the menus and tell me how you want Sparo to work.",IC="Let's tune Sparo to fit the way you work.",MC="Describe the change in one line; I'll review it before applying it.",jC="I will read the current settings, explain the change, and ask before protected actions.",EC={heading:"Start a new conversation",tagline:"Share an idea, question, or request below.",narrative:"Messages and progress will appear here once the conversation begins."},LC={title:"Common adjustments",items:{largerText:{title:"Increase text size",description:"Make interface and editor text easier to read",prompt:"Make the interface and editor text larger while keeping the overall layout balanced."},fewerConfirmations:{title:"Reduce low-risk prompts",description:"Reduce interruptions while keeping high-risk safeguards",prompt:"Reduce confirmation for low-risk actions, but keep confirmation for high-risk computer actions."},debugLogging:{title:"Enable debug logging",description:"Change the runtime log level to debug",prompt:"Change the application log level to debug."}}},$C={title:"What Product App do you want to create?",items:{starter:{title:"Start from an idea",description:"Turn a business scenario into a Product App",prompt:"Create a Product App for managing a small team's daily tasks, with a work object for tasks, an interactive workspace surface, owners, due dates, status filters, and a new task form."},dashboard:{title:"Data dashboard",description:"Show metrics, trends, and filterable details",prompt:"Create a Product App for a sales dashboard, with key metric cards, a trend chart, region filters, a customer details table, and an alerts area."},polish:{title:"Polish the experience",description:"Improve layout, states, empty screens, and visual detail",prompt:"Create a Product App for event registration management, focusing on form experience, registration states, empty states, mobile layout, and visual hierarchy."},debug:{title:"Fix issues",description:"Find runtime errors and iterate quickly",prompt:"Check the current Product App surface for runtime issues, fix errors, slow interactions, or incorrect data display, and explain what changed."}}},OC="",BC="",WC="",zC="Last time you were working on:",UC="Branch:",HC="{{count}} commits ahead",qC="{{count}} commits behind",VC="{{count}} unstaged files",GC="{{count}} staged files",KC="{{count}} unpushed commits",QC="Last commit: ",JC="Time",YC="You might want to:",ZC="Review recent changes",XC="Review recent changes",e1="Continue previous work",t1="Continue previous work",n1="Start a new feature",o1="Start a new feature",s1="Workspace",i1="No workspace open",a1="Open other project...",r1="Search workspaces",l1="Clear workspace search",c1="No matching workspaces",d1="No project selected yet",u1="Start with a line, or",p1="Open one",m1="open a workspace",g1="to get started.",h1=".",f1="We are working in",y1="Working in",w1="Designing in",v1="Now in",b1="All clean, ready to get to work ✦",k1="{{count}} file(s)",S1="{{count}} file(s)",x1="{{count}} commit(s)",C1="waiting to stage",A1="staged and ready to commit",_1="to push",T1="Currently there ",P1=", ",F1=".",R1="working.",N1="working in the project.",D1="inside the project.",I1=". Say what you need.",M1={greetingMorning:Wx,subtitleMorning:zx,greetingAfternoon:Ux,subtitleAfternoon:Hx,greetingEvening:qx,subtitleEvening:Vx,greetingNight:Gx,subtitleNight:Kx,aiPartner:Qx,subtitleMorningRunno:Jx,subtitleAfternoonRunno:Yx,subtitleEveningRunno:Zx,subtitleNightRunno:Xx,aiPartnerRunno:eC,subtitleMorningCowork:tC,subtitleAfternoonCowork:nC,subtitleEveningCowork:oC,subtitleNightCowork:sC,aiPartnerCowork:iC,subtitleMorningDesign:aC,subtitleAfternoonDesign:rC,subtitleEveningDesign:lC,subtitleNightDesign:cC,aiPartnerDesign:dC,aiPartnerDeepResearch:uC,subtitleMorningDeepResearch:pC,subtitleAfternoonDeepResearch:mC,subtitleEveningDeepResearch:gC,subtitleNightDeepResearch:hC,aiPartnerAgenticOs:fC,subtitleMorningAgenticOs:yC,subtitleAfternoonAgenticOs:wC,subtitleEveningAgenticOs:vC,subtitleNightAgenticOs:bC,narrativeAgenticOs:kC,aiPartnerAppBuilder:SC,subtitleMorningAppBuilder:xC,subtitleAfternoonAppBuilder:CC,subtitleEveningAppBuilder:AC,subtitleNightAppBuilder:_C,narrativeAppBuilder:TC,aiPartnerSettings:PC,settingsHeading:FC,settingsTagline:RC,subtitleMorningSettings:NC,subtitleAfternoonSettings:DC,subtitleEveningSettings:IC,subtitleNightSettings:MC,narrativeSettings:jC,fallback:EC,settingsPrompts:LC,appBuilderPrompts:$C,featureIntro:OC,featureIntroCowork:BC,featureIntroDesign:WC,lastTimeYouWere:zC,branch:UC,aheadCommits:HC,behindCommits:qC,unstagedFiles:VC,stagedFiles:GC,unpushedCommits:KC,timeSinceLastCommit:QC,timeIcon:JC,youMightWant:YC,defaultAction1:ZC,defaultAction1Command:XC,defaultAction2:e1,defaultAction2Command:t1,defaultAction3:n1,defaultAction3Command:o1,workspace:s1,noWorkspace:i1,openOtherProject:a1,workspaceSearchPlaceholder:r1,clearWorkspaceSearch:l1,workspaceSearchEmpty:c1,noWorkspaceHint:d1,noWorkspaceHintRunno:u1,openOne:p1,openOneRunno:m1,toStart:g1,toStartRunno:h1,workingIn:f1,workingInCowork:y1,workingInDesign:w1,workingInRunno:v1,gitClean:b1,gitUnstaged:k1,gitStaged:S1,gitUnpushed:x1,waitingToStage:C1,stagedReady:A1,toPush:_1,currentlyHas:T1,commaSeparator:P1,period:F1,project:R1,projectCowork:N1,projectDesign:D1,projectRunno:I1},j1={fileSaved:"File saved",fileCreated:"File created",fileDeleted:"File deleted",fileRenamed:"File renamed",folderCreated:"Folder created",folderDeleted:"Folder deleted",copied:"Copied to clipboard",settingsSaved:"Settings saved",configImported:"Configuration imported",configExported:"Configuration exported",gitCommit:"Commit successful",gitPush:"Push successful",gitPull:"Pull successful",gitStash:"Changes stashed",gitStashApply:"Stash applied",snapshotCreated:"Snapshot created",snapshotRestored:"Snapshot restored",languageChanged:"Language changed",themeChanged:"Theme changed",connectionEstablished:"Connection established"},E1={fileSaveFailed:"Failed to save file",fileCreateFailed:"Failed to create file",fileDeleteFailed:"Failed to delete file",operationFailed:"Operation failed",networkError:"Network error",unexpectedError:"An unexpected error occurred"},L1={unsavedChanges:"You have unsaved changes",largeFile:"Large file, loading may be slow",deprecatedFeature:"This feature is deprecated",experimentalFeature:"This is an experimental feature",lowMemory:"Low memory",diskSpace:"Low disk space"},$1={loading:"Loading...",processing:"Processing...",downloading:"Downloading...",uploading:"Uploading...",indexing:"Indexing files...",searching:"Searching...",updating:"Updating...",installing:"Installing...",connecting:"Connecting...",syncing:"Syncing...",assistantBootstrapWaitingForModelConfiguration:"Assistant bootstrap is waiting for AI model configuration."},O1={common:{learn_more:"Learn more",got_it:"Got it",later:"Later",close:"Close",prev:"Prev",next:"Next page",done:"Done",never_show_again:"Don't show again",page:"Page",more_count:"{{count}} more"},welcome:{toast_title:"Welcome to Sparo OS",toast_desc:"Your AI-powered programming environment",modal_title:"Welcome to Sparo OS",modal_body:`Sparo OS is an AI-driven programming environment. + +Through multi-turn conversations and tool collaboration, development becomes more efficient.`}},B1={deleteFile:"Are you sure you want to delete this file?",deleteFolder:"Are you sure you want to delete this folder and all its contents?",discardChanges:"Are you sure you want to discard all changes?",resetSettings:"Are you sure you want to reset all settings?",closeUnsaved:"You have unsaved changes. Are you sure you want to close?",exitApp:"Are you sure you want to exit?"},W1={success:j1,error:E1,warning:L1,info:$1,announcements:O1,confirm:B1},z1="File Explorer",U1={placeholder:"Search workspace...",noResults:"No matching results found",enterKeyword:"Enter a keyword to start searching",modeFiles:"Files",modeContent:"Text",limitReachedFiles:"Showing the first {{count}} file matches. Refine the query to narrow the result set.",limitReachedContent:"Showing the first {{count}} content matches. Refine the query to narrow the result set."},H1={caseSensitive:"Case Sensitive (Aa)",wholeWord:"Whole Word (Ab)",useRegex:"Use Regular Expression (.*)"},q1={switchToSearch:"Switch to Search",switchToTree:"Switch to File Tree",retry:"Retry"},V1={searchingFilename:"Searching file names...",searchingContent:"Searching content...",loadingFileTree:"Loading file tree..."},G1={selectWorkspace:"File tree will be displayed after selecting a workspace"},K1={newFile:{title:"New File",placeholder:"Enter file name",confirm:"Create",cancel:"Cancel"},newFolder:{title:"New Folder",placeholder:"Enter folder name",confirm:"Create",cancel:"Cancel"}},Q1={invalidFilename:"File name contains invalid characters"},J1={downloading:"Downloading",uploading:"Uploading",missingConnection:"Remote workspace has no SSH connection id.",failed:"File transfer failed: {{error}}",dropHint:"Drop files here to upload"},Y1={createFileSuccess:"File created successfully",createFileFailed:"Failed to create file: {{error}}",createFolderSuccess:"Folder created successfully",createFolderFailed:"Failed to create folder: {{error}}",renameSuccess:"Renamed successfully",renameFailed:"Failed to rename: {{error}}",moveFailed:"Failed to move: {{error}}",deleteSuccess:"Deleted successfully",deleteFailed:"Failed to delete: {{error}}",pasteSuccess:"Successfully pasted {{count}} files",pasteFailed:"{{count}} files failed to paste",pasteNoFiles:"No files in clipboard",pastingFiles:"Pasting {{count}} files to {{target}}...",openExplorerFailed:"Failed to open file explorer: {{error}}",selectWorkspaceFirst:"Please open a workspace first"},Z1={title:z1,search:U1,options:H1,actions:q1,status:V1,empty:G1,dialog:K1,validation:Q1,transfer:J1,notifications:Y1},X1="Git",e0={title:"Initialize Git",notRepository:"Current directory is not a Git repository",initButton:"Initialize Repository",hint:"Click the button to initialize with AI assistant",chatPrompt:"Please help me initialize a Git repository in the current workspace."},t0={text:"Loading Git info...",hint:"Click refresh if loading takes too long"},n0={loading:"Loading...",retry:"Retry",refresh:"Refresh",saving:"Saving...",processing:"Processing...",unknown:"Unknown",unknownError:"Unknown error"},o0={refresh:"Refresh Git Status",forceRefresh:"Force Refresh",push:"Push",forcePush:"Force Push",pull:"Pull",stageAll:"Stage All",stageSelected:"Stage {{count}} selected files",selectFilesToStage:"Please select files to stage first",commit:"Commit",commitWithCount:"Commit ({{count}})",aiGenerateCommit:"AI Generate Commit Message",cancelGenerate:"Cancel Generation",aiCodeReview:"AI Code Review",viewAllDiff:"View All Diff",discardFile:"Discard this file",deleteFile:"Delete this file",discardAllChanges:"Discard All Changes",copyCommitHash:"Copy Commit Hash",resetToCommit:"Reset to this Commit",createBranchFromCommit:"Create Branch from Commit",switchBranch:"Switch to this Branch",createBranchFrom:"Create Branch from this",deleteBranch:"Delete Branch",viewBranchHistory:"Click to view commit history",viewBranchGraph:"View Branch Graph"},s0={changes:"Changed Files",commits:"Commit History",branches:"Branches",changeDiff:"Change Diff",branchGraph:"Git Branch Graph",branchCommitHistory:"{{branch}} Commit History"},i0={files:"Search files...",commits:"Search commits...",branches:"Search branches...",clear:"Clear Search"},a0={loading:"Loading commit history for {{branch}}...",loadFailed:"Failed to load commit history",loadFailedWithMessage:"Load failed: {{error}}",retry:"Retry",selection:{selectAll:"Select all",deselectAll:"Deselect all"},allAuthors:"All authors",authorPlaceholder:"Author",cherryPick:"Cherry-pick",cherryPickRunning:"Running...",cherryPickFailed:"Cherry-pick failed",cherryPickOperationFailed:"Cherry-pick operation failed",copied:"Copied",copy:"Click to copy",refresh:"Refresh",details:{fullHash:"Full hash:",commitTime:"Commit time:"},notifications:{cherryPickSuccess:"Cherry-picked {{count}} commits into {{branch}}",cherryPickPartial:"Cherry-picked {{count}} commits, but commit {{hash}} failed: {{error}}",cherryPickFailedWithError:"Cherry-pick commit {{hash}} failed: {{error}}"}},r0={loading:"Loading commit history...",loadFailedWithMessage:"Load failed: {{error}}",empty:"No commit history",title:"Commit History",searchPlaceholder:"Search commit message, author, or hash...",searchPrevious:"Previous result (Shift+Enter)",searchNext:"Next result (Enter)",noResults:"No results",tooltip:{author:"Author",hash:"Hash",time:"Time",refs:"Refs:",currentRefSuffix:"(current)"}},l0={errors:{repositoryPathEmpty:"Repository path cannot be empty",loadFailed:"Failed to load diff"},loading:"Loading diff...",loadFailedTitle:"Failed to load diff",workingTree:"Working Tree",staged:"Staged",collapseAll:"Collapse All",expandAll:"Expand All",loadingData:"Loading diff data...",empty:{title:"No diff found",workingTreeClean:"Working tree has no changes",noDiffBetweenCommits:"No diff between the selected commits",selectRepository:"Select a Git repository to view diff"}},c0={saveFailedWithMessage:"Failed to save file: {{error}}",confirmAcceptAll:`Are you sure you want to accept all changes and stage this file? + +File: {{filePath}} ++{{additions}} lines, -{{deletions}} lines`,acceptFailedWithMessage:"Failed to accept changes: {{error}}",confirmRejectAll:`Are you sure you want to discard all changes? This action cannot be undone. + +File: {{filePath}} +Will discard {{changes}} changes`,rejectFailedWithMessage:"Failed to reject changes: {{error}}",completed:{acceptedTitle:"All changes accepted",rejectedTitle:"All changes rejected",stagedHint:"File staged and ready to commit",rejectedHint:"All changes discarded and file restored"}},d0={noFilesToReview:"No file changes available for code review",displayMessage:`Review Git changed files: +{{files}}`,requestMessage:`Please review the following Git changed files: + +{{files}}`,sendFailed:"Failed to send code review request"},u0={justNow:"just now",minutesAgo:"{{count}} minutes ago",hoursAgo:"{{count}} hours ago",daysAgo:"{{count}} days ago",weeksAgo:"{{count}} weeks ago",monthsAgo:"{{count}} months ago",yearsAgo:"{{count}} years ago"},p0={staged:"Staged",unstaged:"Unstaged",untracked:"Untracked",ahead:"Ahead of Remote",behind:"Behind Remote",modified:"M",added:"A",deleted:"D",renamed:"R",untrackedBadge:"U"},m0={unstaged:"Unstaged",untracked:"Untracked",staged:"Staged",unstagedWithCount:"Unstaged ({{count}})",untrackedWithCount:"Untracked ({{count}})",stagedWithCount:"Staged ({{count}})",unstagedWithFilter:"Unstaged ({{filtered}} / {{total}})",untrackedWithFilter:"Untracked ({{filtered}} / {{total}})",stagedWithFilter:"Staged ({{filtered}} / {{total}})",moreFiles:"{{count}} more files not shown..."},g0={inputPlaceholder:"Enter commit message...",inputPlaceholderNoStaged:"Stage files to enter commit message...",changedFiles:"Changed Files ({{count}})",author:"Author",unknown:"Unknown"},h0={current:"Current"},f0={searchPlaceholder:"Search branches...",loading:"Loading...",notifications:{switchSuccess:"Switched to branch {{branch}}"},errors:{title:"Branch switch failed",switchFailed:"Failed to switch branch",switchFailedWithMessage:"Failed to switch branch: {{error}}",localChanges:"Please commit or stash local changes first",indexConflict:"Please resolve the current index conflicts first",unexpected:"Unexpected error while switching branches"}},y0={title:"Select or Create Branch",inputPlaceholder:"Enter new branch name...",loading:"Loading...",createNewLabel:"Create new branch:",openAfterCreate:{label:"Open after create",description:"Open the new worktree as a workspace immediately after it is created."},badges:{inUse:"In Use"},errors:{loadFailed:"Failed to load branch list"}},w0={selectAll:"Select all unstaged files",deselectAll:"Deselect all",selectFolder:"Select all files in this folder",deselectFolder:"Deselect this folder",selectFile:"Select this file",deselectFile:"Deselect"},v0={noChanges:"No file changes",noMatchingFiles:"No matching files",noCommits:"No commits",noMatchingCommits:"No matching commits",noBranches:"No branches",noMatchingBranches:"No matching branches"},b0={viewDiff:"Click to view diff",expandDetails:"Expand details",collapseDetails:"Collapse details",resizeFileList:"Drag to resize file list and diff area"},k0={createBranch:{title:"Create Branch from Commit",description:"Will create new branch from commit {{hash}}",placeholder:"Enter branch name",confirm:"Create",cancel:"Cancel"},createNewBranch:{title:"Create New Branch",baseBranch:"Based on branch",nameLabel:"New branch name",namePlaceholder:"e.g. feature/new-feature or bugfix/issue-123",namingHintTitle:"Branch naming suggestions:",namingHints:{featureLabel:"Feature branch:",featureExample:"feature/feature-name",bugfixLabel:"Bugfix branch:",bugfixExample:"bugfix/issue-description",hotfixLabel:"Hotfix branch:",hotfixExample:"hotfix/fix-description",releaseLabel:"Release branch:",releaseExample:"release/version"},confirm:"Create Branch",cancel:"Cancel"}},S0={branchNameInvalid:"Branch name can only contain letters, numbers, dots, underscores, hyphens and slashes",branchNameExists:"Branch name already exists",branchNameEmpty:"Branch name cannot be empty",branchNameContainsDoubleDot:'Branch name cannot contain ".."',branchNameContainsDoubleSlash:'Branch name cannot contain "//"',branchNameDotEdge:'Branch name cannot start or end with "."',branchNameSlashEdge:'Branch name cannot start or end with "/"',branchNameSpaces:"Branch name cannot contain spaces",branchNameSpecialChars:"Branch name cannot contain special characters: ^ ~ : ? * [ \\",branchNameAtBrace:'Branch name cannot contain "@{"',branchNameExistsWithName:'Branch "{{name}}" already exists'},x0={addFilesTitle:"Add files",commitChangesTitle:"Commit changes",pushTitle:"Push changes",pushTitleForce:"Push changes (force)",pushProgress:"Pushing to remote repository...",pullTitle:"Pull changes",pullProgress:"Pulling from remote repository...",checkoutTitle:"Switch to branch {{branch}}",createBranchTitle:"Create branch {{branch}}",deleteBranchTitle:"Delete branch {{branch}}",resetFilesTitle:"Reset files"},C0={merge:"Merge branch",rebase:"Rebase branch",stash:"Stash changes",applyStash:"Apply stash",popStash:"Pop stash",dropStash:"Drop stash",cherryPick:"Cherry-pick commit",revert:"Revert commit",resetCommit:"Reset commit"},A0={title:"Git Settings",loading:"Loading Git settings...",loadFailedTitle:"Failed to load settings",retry:"Retry",refresh:"Refresh settings",saving:"Saving...",save:"Save settings",success:{saveConfig:"Settings saved successfully"},errors:{loadConfigFailed:"Failed to load configuration",saveConfigFailed:"Failed to save configuration"},tabs:{user:"User",repository:"Repository",advanced:"Advanced"},sections:{user:{title:"User information",description:"These details are used as the Git commit author identity",nameLabel:"Name",namePlaceholder:"Enter your name",emailLabel:"Email address",emailPlaceholder:"Enter your email"},editor:{title:"Editor settings",defaultEditorLabel:"Default editor"},lineEndings:{title:"Line endings",autocrlfLabel:"Auto CRLF",options:{auto:"Auto (recommended for Windows)",input:"Input (recommended for macOS/Linux)",disabled:"Do not convert"}},remotes:{title:"Remotes",urlLabel:"URL",urlPlaceholder:"Remote URL"},core:{title:"Core settings",ignoreCaseLabel:"Ignore file name case",ignoreCaseDescription:"Enable on case-insensitive file systems"},branch:{title:"Branch settings",branchLabel:"Branch: {{branch}}",remoteLabel:"Remote",mergeLabel:"Merge branch"}}},_0={addFailed:"Failed to add files",commitFailed:"Failed to commit",pushFailed:"Push failed",pushFailedWithCheck:"Push failed. Please check your network connection and permissions.",pullFailed:"Pull failed",pullFailedWithCheck:"Pull failed. Please check your network connection and permissions.",checkoutFailed:"Failed to switch branch",createBranchFailed:"Failed to create branch",deleteBranchFailed:"Failed to delete branch",resetFilesFailed:"Failed to reset files",resetCommitFailed:"Failed to reset to commit",cherryPickFailed:"Cherry-pick failed",cherryPickAbortFailed:"Failed to abort cherry-pick",cherryPickContinueFailed:"Failed to continue cherry-pick",refreshFailed:"Refresh failed",checkoutFailedTitle:"Failed to switch branch",createBranchFailedTitle:"Failed to create branch",deleteBranchFailedTitle:"Failed to delete branch",checkoutLocalChanges:"Please commit or stash local changes first",checkoutIndexConflict:"Please resolve the current index conflicts first (unfinished merge or rebase may exist)",branchNotFound:"Branch {{branch}} not found",branchAlreadyExists:"Branch {{branch}} already exists",branchNotMerged:"Branch {{branch}} is not fully merged. Use force delete if needed.",cannotDeleteCurrentBranch:"Cannot delete the currently checked out branch {{branch}}"},T0={stageSuccess:"Staged {{count}} files",stageFailed:"Failed to stage: {{error}}",commitSuccess:"Committed successfully",commitFailed:"Failed to commit: {{error}}",fileRestored:"File restored",fileRestoreFailed:"Failed to restore file: {{error}}",allChangesRestored:"All changes restored successfully",restoreFailed:"Failed to restore changes: {{error}}",resetSuccess:"Reset to commit {{hash}}",resetFailed:"Failed to reset: {{error}}",aiGenerateFailed:"AI failed to generate commit message: {{error}}",noFilesToGenerate:"No file changes to generate commit message",noStagedFiles:"No staged files to commit",enterCommitMessage:"Please enter commit message",selectFilesToStage:"Please select files to stage first",cannotDeleteCurrentBranch:"Cannot delete current branch",openDiffFailed:"Failed to open file diff: {{error}}",openDiffFailedWithPath:`Failed to open file diff: {{error}} +File: {{file}}`,pushUpstreamSuccess:"Set upstream and pushed to remote",pushSuccess:"Pushed to remote",pushForceSuccess:"Force pushed to remote",pullSuccess:"Pulled latest changes from remote",checkoutSuccess:"Switched to branch {{branch}}",createBranchSuccess:"Created branch {{branch}}",deleteBranchSuccess:"Deleted branch {{branch}}"},P0={discardFile:`Warning: Are you sure you want to discard "{{file}}"? + +This action cannot be undone!`,deleteFile:`Warning: Are you sure you want to delete "{{file}}"? + +This action cannot be undone!`,discardAllChanges:`Warning: This will: + +1. Discard all staged changes +2. Discard all unstaged changes +3. Delete all untracked files + +This action cannot be undone! Are you sure?`,resetToCommit:`Are you sure you want to reset to commit {{hash}}? + +This will move the current branch pointer to this commit.`,deleteBranch:'Are you sure you want to delete branch "{{branch}}"?'},F0={title:X1,init:e0,loading:t0,common:n0,actions:o0,tabs:s0,search:i0,branchHistory:a0,graph:r0,diffView:l0,diffEditor:c0,review:d0,relativeTime:u0,status:p0,fileGroups:m0,commit:g0,branch:h0,quickSwitch:f0,branchSelect:y0,selection:w0,empty:v0,tooltips:b0,dialog:k0,validation:S0,operations:x0,advancedOperations:C0,settingsView:A0,errors:_0,notifications:T0,confirm:P0},R0="Terminal",N0="Create or open a terminal from the list on the left",D0={editTerminal:{title:"Edit Terminal",nameLabel:"Name",namePlaceholder:"Terminal name",workingDirectoryLabel:"Startup Path",workingDirectoryPlaceholder:"Path to open when the terminal starts",workingDirectoryHint:"Used when reopening a saved terminal",startupCommandLabel:"Startup Command (Optional)",startupCommandPlaceholder:"Command to run after the terminal starts",startupCommandHint:"This command runs automatically after the terminal starts",cancel:"Cancel",save:"Save"}},I0={title:R0,emptyState:N0,dialog:D0},M0={title:"App Builder",description:"Build a Product App with a clear goal, work object, surface, and component graph."},j0={title:"App Draft",draftBadge:"Editable Draft",derivedFrom:"Based on Release {{releaseId}}. The source Release is never modified.",newDraft:"A new App Draft. Formal Work only uses a published Release.",tabsLabel:"App Draft workbench",tabs:{preview:"Preview",quality:"Validation",release:"Release"},actions:{refreshPreview:"Refresh preview",validate:"Validate Draft",createRelease:"Create Release",activate:"Use this Release",continueEditing:"Continue from this Release",retry:"Retry",cancel:"Cancel",close:"Close"},empty:{title:"No App Draft is bound",description:"Create or customize an app in Apps Center before opening Builder."},preview:{loading:"Preparing isolated preview…",failed:"This Draft could not be previewed",timeout:"Draft preview timed out while starting.",ready:"Preview ready",starting:"Starting",isolated:"Preview uses an ephemeral artifact. It does not create formal Work or change the active app."},quality:{validation:"Release gate",validationDescription:"Package contracts, capabilities, data migration, and runtime checks must pass.",evaluation:"Independent evaluation",evaluationDescription:"No reliable comparison with the current Release has been produced yet.",notRun:"Not verified",failed:"Failed",warnings:"Warnings",issues:"Issues",cases:"Evaluation cases"},release:{immutable:"Immutable",ready:"Release {{version}} is ready",description:"This artifact will never change. Activation only affects new Work; existing Work stays on its original Release.",releaseId:"Release ID",artifact:"Artifact digest",emptyTitle:"No new Release yet",emptyDescription:"Validate the Draft, then create an immutable Release. Creating it does not change the active app."},publish:{title:"Create immutable Release",description:"Enter the user-facing version. The system rejects publication when a Release gate has not passed.",invalidVersion:"Enter a valid semantic version such as 1.0.0."},capabilities:{title:"Review app capabilities",description:"This Release requests the capabilities below. Review them before activation.",scopeNote:"Approval is bound to this app and capability fingerprint. Capability changes require a new review.",approveAndActivate:"Approve and activate",count:"{{count}} items",columns:{capability:"Capability",permission:"Allowed action",usedBy:"Used by"},permissionLabels:{ai:"Use AI capabilities",modelInvoke:"Invoke the configured model",sessionRead:"Read the current session",toolInvoke:"Invoke application tools",componentRun:"Run application components",filesystem:"Access the file system",network:"Access the network",appData:"Access application data",networkAny:"Access external networks"},sources:{app:"App",system:"System"},groups:{ai:{title:"AI and models",description:"Use the app agent and invoke the configured model."},files:{title:"App files",description:"Access the app's own data directory."},network:{title:"Network access",description:"Access user-provided sources or external resources."},session:{title:"Session context",description:"Read the context required from the current work session."},tools:{title:"Tool invocation",description:"Invoke capabilities declared by the app."},runtime:{title:"Component runtime",description:"Start and coordinate components within the app."},other:{title:"Other capabilities",description:"Other system capabilities declared by the app."}}},messages:{validationStarted:"Validation was sent to App Builder",releaseCreated:"Release {{version}} created",activated:"The new Release is now active"}},E0={title:"App Builder",reload:"Reload preview",openInApps:"Open Product App",emptyTitle:"Builder is drafting for you",emptyDescription:"The first runnable version will appear here automatically.",loading:"Loading preview",loadFailed:"Failed to load preview",retry:"Retry",updating:"Updating preview…",menu:{recompile:"Recompile",installDeps:"Install deps",openInApps:"Open in Apps",reload:"Reload preview",viewPermissions:"Permissions",copyAppId:"Copy App ID",moreActions:"More actions",theme:"Theme: {{theme}}",language:"Language: {{lang}}"},actions:{restartWorker:"Restart worker",stop:"Stop"}},L0={tabsLabel:"App Builder workbench sections",tabs:{blueprint:"Blueprint",preview:"Preview",issues:"Issues",components:"Components",agent:"Agent",data:"Data",eval:"Eval",validation:"Validation",versions:"Versions",permissions:"Permissions",share:"Share"},sections:{userBlueprint:"User blueprint",userBlueprintDesc:"What the app promises in ordinary product terms.",technicalBlueprint:"Technical blueprint",technicalBlueprintDesc:"Stable package, surface, runtime, and component facts.",issueSummary:"Builder issues",issueSummaryDesc:"Runtime facts captured from preview, worker, and backend events.",components:"Component graph",componentsDesc:"Primary surface and backend bindings currently known to App Builder.",agent:"Agent backend",agentDesc:"AI actions exposed through declared backend bindings.",data:"Data and memory",dataDesc:"What the app can read, save, remember, or fetch externally.",eval:"Agent eval",evalDesc:"Behavioral reliability checks. Missing evidence stays marked as unverified.",validation:"Validation gate",validationDesc:"Package, preview, runtime, permissions, data, and eval readiness.",versions:"Versions",versionsDesc:"Draft, revision, lock, checkpoint, and release facts.",permissions:"Permissions",permissionsDesc:"Minimum access currently declared by the package.",share:"Share",shareDesc:"Where the app can be installed and what private data stays out."},facts:{primarySurface:"Primary surface",surfaceMode:"Surface mode",sourceFiles:"Source files",backend:"Component",launchKind:"Launch kind",whatItDoes:"What it does",howIUseIt:"How I use it",whatAiDoes:"What AI does",whatData:"What data it uses",howReady:"How readiness is proven",appId:"App ID",componentId:"Component ID",componentKind:"Component kind",packageRoot:"Package root",version:"Version",category:"Category",tags:"Tags",runtimeRevision:"Runtime revision",fatalIssues:"Fatal issues",warnings:"Warnings",runtimeLogs:"Runtime logs",backendActions:"Backend actions",memoryScope:"Memory scope",sessionPolicy:"Session policy",inputData:"Input data",workingState:"Working state",externalFacts:"External facts",retention:"Retention",deletion:"Deletion",migration:"Migration",sharePolicy:"Share policy",currentDraft:"Current draft",sourceRevision:"Source revision",lockDigest:"Lock digest",releaseStatus:"Release status",latestRelease:"Latest release",releaseId:"Release ID",releaseCreated:"Release created",releasePackage:"Release package",releaseNotes:"Release notes",latestPublishedRelease:"Latest published release",releasePublished:"Published",evalStatus:"Eval status",evalCases:"Eval cases",evalDetail:"Eval detail",visibility:"Visibility",installLocation:"Install location",privateData:"Private data"},permissions:{workspaceRead:"Workspace read",workspaceWrite:"Workspace write",shell:"Shell",network:"Network",ai:"AI",worker:"Worker",reviewElevated:"Review permissions",recordReview:"Record permission review",reviewRecorded:"Permission review recorded."},versions:{openRelease:"Open",copyRelease:"Copy",compareRelease:"Compare",useAsTemplate:"Use as template",restoreRelease:"Rollback to release",restoreTitle:"Rollback to Release",restoreMessage:"Ask App Builder to restore package source from release {{releaseId}}. This does not roll back installed user data, Work history, runtime storage, or private memory.",restoreConfirm:"Request rollback",restoreCancel:"Cancel",restoreDisplay:"Rollback to release {{releaseId}}",restoreSent:"Rollback request sent to App Builder.",releaseCopied:"Release details copied.",compareDisplay:"Compare release {{releaseId}}",compareSent:"Release comparison request sent to App Builder.",templateDisplay:"Use release {{releaseId}} as template",templateSent:"Template request sent to App Builder."},validation:{package:"Package",criticalPath:"Critical path",validation:"Validation",preview:"Preview",runtime:"Runtime",runtimeReady:"Runtime ready",runtimeStorage:"Runtime storage",runtimeDependencies:"Runtime dependencies",surfaceMode:"Surface mode",hostFrame:"Host frame",visualRoot:"Visual root",viewport:"Viewport",interactionSurface:"Interaction surface",issues:"Issues",permissions:"Permissions",permissionReview:"Permission review",data:"Data boundary",dataLifecycle:"Data lifecycle",dataSummary:"Data summary",userPath:"User path",userPathContract:"User path contract",componentSchema:"Component schema",componentContract:"Component contract",capabilities:"Capabilities",capabilitySchema:"Capability schema",capabilityCall:"Capability call",capabilityLogs:"Capability logs",capabilityTrace:"Capability trace",dependencies:"Dependencies",implementation:"Implementation",consumerCompatibility:"Consumer compatibility",agentEval:"Agent eval",evalLogs:"Eval logs",evalTrace:"Eval trace",releaseGate:"Release gate"},values:{standalone:"standalone",enabled:"Enabled",disabled:"Disabled",loaded:"Loaded",waiting:"Waiting",failing:"Failing",running:"Running",needsAttention:"Needs attention",ready:"Ready",notVerified:"Not verified",blocked:"Blocked",notSpecified:"Not specified",sidecarPreview:"Chat plus sidecar panel",agentPreview:"Agent session",fullPreview:"Runnable app preview",noBackendActions:"No backend actions declared",packageAndRuntimeState:"Package metadata and runtime state",componentConsumerUse:"Reference from a Product App package",componentCapability:"Reusable component capability",componentPackageState:"Component package metadata and contract files",componentReadiness:"Contract and consumer validation are still required",runtimeIssues:"Runtime issues are blocking readiness",previewLoaded:"Preview loaded with no fatal issue captured",uncategorized:"Uncategorized",none:"None",unknown:"Unknown",workspaceReadable:"Workspace files may be read",userProvidedOnly:"User-provided input only",runtimeScoped:"Scoped to the running Product App work",externalAccess:"External access declared",noExternalAccess:"No external access declared",appStorage:"App package and runtime storage",lifecycleWorkRuntimeScoped:"Work runtime scoped",lifecycleSessionScoped:"Session scoped",lifecycleUserManaged:"User managed",lifecycleExternalSystem:"External system",lifecycleDeleteWithWork:"Delete with work",lifecycleDeleteOnUserRequest:"Delete on request",lifecycleNoDurableData:"No durable data",lifecycleNotSupported:"Not supported",lifecycleExportImport:"Export/import",lifecycleSchemaVersioned:"Schema versioned",lifecycleExcludeRuntimePrivateData:"Exclude runtime private data",lifecycleDeclaredWorkObjectsOnly:"Declared work objects only",lifecycleExternalReferenceOnly:"External references only",notAvailable:"Not available yet",privateDraft:"Private draft",privateRelease:"Private release",catalogSource:"Catalog source",workspaceInstall:"Current workspace",systemInstall:"System app storage",privateDataExcluded:"Private data is not part of the share payload"},empty:{noApp:"No Product App is bound to this Builder session yet.",noAgent:"No agent backend is declared yet."}},$0={readWorkspace:"Can read workspace",noWorkspaceRead:"No workspace read",writeWorkspace:"Can write workspace",noWorkspaceWrite:"No workspace write",shellEnabled:"Shell enabled",shellDisabled:"Shell disabled",netEnabled:"Network enabled",netDisabled:"Network disabled",aiEnabled:"AI enabled",aiDisabled:"AI disabled",nodeEnabled:"Worker enabled",nodeDisabled:"Worker disabled"},O0={toggleOn:"Inspect preview element",toggleOff:"Stop inspecting",inspecting:"Inspecting elements",hovering:"Inspecting {{target}}",contextLabel:"Element",addContext:"Add context",added:"Selected preview element added to chat context",alreadyAdded:"Selected preview element is already in chat context",clear:"Clear selection"},B0={title:"Runtime",ok:"Runtime OK",empty:"No runtime errors yet",logsEmpty:"No runtime logs yet",issuesTab:"Issues",logsTab:"Logs",fatalCount:"{{count}} errors",warningCount:"{{count}} warnings",sendToAi:"Send to AI for fix",sendDisplay:"Fix Product App runtime issue",sent:"Sent to AI",clear:"Clear",expand:"Expand",collapse:"Collapse",copy:"Copy",copied:"Copied",copyAppId:"App ID copied",filterAll:"All",filterError:"Error",filterWarn:"Warn",filterInfo:"Info",followTail:"Follow",pauseTail:"Paused",newMessages:"{{count}} new",searchPlaceholder:"Filter…",permissionsTitle:"Permissions",showStack:"Stack",hideStack:"Hide stack",fixWithAi:"Fix",truncatedHint:"Last {{max}} entries shown · Full log at {{path}}",buildMarker:"— Built at {{time}} —",groups:{fatal:"Fatal errors",warning:"Warnings",logs:"Runtime logs"},hints:{"runtime-unavailable":"Install a JS runtime to enable worker features.","deps-install":"Run Install deps to resolve missing packages.",permission:"Check the app's permission policy.","workspace-access":"Grant workspace path in the app's permissions.","unknown-method":"The called bridge method is not supported by the host runtime."}},W0={entry:M0,draftWorkbench:j0,panel:E0,workbench:L0,permissions:$0,previewSelection:O0,diagnostics:B0},z0={files:"Files",coding:"Coding",documents:"Documents",analysis:"Analysis",testing:"Testing",creative:"Creative",operations:"Operations",productivity:"Productivity",automation:"Automation",data:"Data",gui:"GUI",cli:"CLI",sdk:"SDK",service:"Service",mcp:"MCP",daemon:"Daemon"},U0=JSON.parse(`{"eyebrow":"App System","title":"Apps","subtitle":"Resume product work, launch installed Product Apps, and inspect the component graph behind every runtime.","searchLabel":"Search Product Apps","searchPlaceholder":"Search apps, active work, components, or tags...","loading":"Loading Product Apps...","meta":{"apps":"{{count}} apps","components":"{{count}} components"},"navigation":{"label":"App Center view","home":"App Center","manage":"Manage","components":"Components"},"launch":{"title":"Intelligent Apps","subtitle":"Your dual-domain app desk, connecting knowledge with action.","searchPlaceholder":"Search apps, capabilities, or active work...","continueDescription":"Pick up work already in motion.","emptyTitle":"No apps or work match your search","emptyDescription":"Try another app name, capability, tag, or work title."},"homeRail":{"label":"App runtime status","running":"Running","idle":"No running apps","closeRunningApp":"Close {{name}}","previousRunningApps":"Show previous running apps","nextRunningApps":"Show more running apps","workStates":"App task status","pinnedApps":"Pinned apps","states":{"waiting":"Needs attention","running":"In progress","paused":"Paused"}},"homeViews":{"label":"App Center content","installed":"My apps","discover":"Discover"},"manage":{"title":"App management","subtitle":"Maintain installed apps, creations, and components","railTitle":"Management","railSubtitle":"Apps and components","sections":{"apps":"All apps","updates":"Updates","disabled":"Disabled","creations":"My intelligent apps","drafts":"Drafts","components":"Components"},"sectionTitles":{"apps":"All apps","updates":"Available updates","disabled":"Disabled apps","creations":"My intelligent apps","drafts":"Drafts","components":"Components"},"sectionDescriptions":{"apps":"Review and maintain every installed app.","updates":"Install available updates and review release notes.","disabled":"Re-enable or remove disabled apps.","creations":"Manage intelligent apps you built or generated with AI.","drafts":"Continue creations that have not been published.","components":"Inspect shared and app-private building blocks."},"drafts":{"updated":"Updated {{time}}","missingApp":"The app for this draft could not be found.","emptyTitle":"No drafts","emptyDescription":"Drafts appear here after you create or edit an intelligent app.","actions":{"open":"Open draft {{name}}","delete":"Delete draft {{name}}"},"deleteDialog":{"title":"Delete this draft?","message":"This permanently deletes the unpublished changes in \\"{{name}}\\" and cannot be undone. Published releases are not affected, but App Builder work using this draft can no longer continue.","confirm":"Delete draft"},"messages":{"deleted":"Draft \\"{{name}}\\" deleted","deleteFailed":"Failed to delete draft \\"{{name}}\\": {{error}}"}},"searchLabel":"Search managed apps","searchPlaceholder":"Search by app, category, description, tag, or component summary...","emptyTitle":"No apps match this view","emptyDescription":"Adjust search or filters to review another app group.","listLabel":"Managed apps list","install":"Install","update":"Update","updateAvailable":"Update available","updateAvailableVersion":"Update to {{version}}","updateTitle":"Update App","updateMessage":"Use the published release below for new Work in \\"{{name}}\\". Existing Work keeps its bound release and remains available.","updateConfirm":"Update","updateCloseLabel":"Close update dialog","updateCurrentVersion":"Current version","updateTargetVersion":"After update","updatePreviewVersion":"Version","updatePreviewRelease":"Release","updatePreviewReleaseId":"Release ID","updatePreviewPublished":"Published","updatePreviewNotes":"Release notes","updatePreviewNoNotes":"No release notes were provided.","updatePreviewComponentLock":"Component lock","updatePreviewPackage":"Package digest","enable":"Enable","disable":"Disable","moreActions":"More actions","uninstall":"Uninstall","uninstallTitle":"Uninstall App","uninstallMessage":"This will remove \\"{{name}}\\" from the app catalog and prevent new launches. Existing Work remains in Work Center.","uninstallConfirm":"Uninstall","installedToast":"{{name}} installed","updatedToast":"{{name}} updated","uninstalledToast":"{{name}} uninstalled","enabledToast":"{{name}} enabled","disabledToast":"{{name}} disabled","packageIssue":"Issue","updateFailed":"Failed to update {{name}}: {{error}}","installFailed":"Failed to install {{name}}: {{error}}","uninstallFailed":"Failed to uninstall {{name}}: {{error}}","sortLabel":"Sort managed apps","sortBy":"Sort by","sortOptions":{"attention":"Needs attention","name":"Name","status":"Status"},"categoriesLabel":"Filter apps","viewModeLabel":"View mode","viewMode":{"list":"List","cards":"Cards"}},"actions":{"pin":"Pin {{name}}","unpin":"Unpin {{name}}","components":"Components","createComponent":"Create Component","createApp":"Create App","refresh":"Refresh","retry":"Retry","openComponentCenter":"Open Component Center","details":"Details","work":"Work","launch":"Launch","stop":"Stop","newWork":"New","continue":"Continue","back":"Back","close":"Close","cancel":"Cancel","inspect":"Inspect","customize":"Customize a copy","edit":"Edit Draft","syncUpstream":"Review upstream update"},"capabilities":{"title":"Review app capabilities","description":"{{name}} requests the capabilities below. Review them before activating this Release.","scopeNote":"Approval is bound to this App and capability fingerprint. A capability change requires a new review.","approveAndActivate":"Approve and activate","count":"{{count}} items","columns":{"capability":"Capability","permission":"Allowed action","usedBy":"Used by"},"permissionLabels":{"ai":"Use AI capabilities","modelInvoke":"Invoke the configured model","sessionRead":"Read the current session","toolInvoke":"Invoke application tools","componentRun":"Run application components","filesystem":"Access the file system","network":"Access the network","appData":"Access application data","networkAny":"Access external networks"},"sources":{"app":"App","system":"System"},"groups":{"ai":{"title":"AI and models","description":"Use the app agent and invoke the configured model."},"files":{"title":"App files","description":"Access the app's own data directory."},"network":{"title":"Network access","description":"Access user-provided sources or external resources."},"session":{"title":"Session context","description":"Read the context required from the current work session."},"tools":{"title":"Tool invocation","description":"Invoke capabilities declared by the app."},"runtime":{"title":"Component runtime","description":"Start and coordinate components within the app."},"other":{"title":"Other capabilities","description":"Other system capabilities declared by the app."}}},"messages":{"installBeforeLaunch":"Install {{name}} before launching it.","noLaunch":"{{name}} has no launch target.","launchFailed":"Failed to launch {{name}}: {{error}}","stopped":"{{name}} stopped","stopFailed":"Failed to stop {{name}}: {{error}}","closeWorkFailed":"Failed to close work {{name}}: {{error}}","catalogPartialFailureTitle":"Product App issue","catalogPartialFailureOne":"Could not load {{target}}: {{error}}","catalogPartialFailureMany":"{{count}} Product App packages could not be loaded. First issue: {{target}}: {{error}}"},"surfaceFallback":"Product App surface","filters":{"label":"Product App filter","all":"All","installed":"Installed","discover":"Discover","conversation":"Conversation","interactive":"Interactive"},"continue":{"title":"Continue Work","count":"{{count}} active","description":"Return to what is already in motion.","viewAll":"All","closeWork":"Close work \\"{{title}}\\"","expandRelated":"Choose related work","relatedLabel":"Related work","emptyTitle":"No active work","emptyDescription":"Launch a Product App to create the first work instance."},"myApps":{"title":"My Apps","count":"{{count}} installed","description":"Open a familiar app or choose one to start new work.","syncing":"Syncing","syncingRemaining":"Syncing {{count}}","loadingProductApps":"Loading installed Product Apps","loadingProductAppsDetail":"Native apps are ready; package apps are still syncing.","revealingProductAppsDetail":"{{count}} apps are still joining the page.","emptyTitle":"No installed Product Apps","emptyDescription":"Install or create a Product App to make it available here."},"discover":{"emptyTitle":"No new apps","emptyDescription":"New installable apps will appear here when available.","title":"Discover","description":"Add a new capability when your current apps are not enough.","count":"{{count}} available","loadingBadge":"Loading","syncingRemaining":"Syncing {{count}}","loading":"Loading discoverable apps","loadingDetail":"Marketplace and package sources are still being checked.","revealingDetail":"{{count}} discoverable apps are still joining the page."},"components":{"title":"Advanced Components","noDependencies":"No component dependencies","searchLabel":"Search components","searchPlaceholder":"Search components, capabilities, owners, or implementations...","filterLabel":"Component kind","allKinds":"All kinds","emptyTitle":"No components found","emptyDescription":"Adjust the search or filter to inspect another component group.","listTitle":"Component packages","listDescription":"Shared and app-private building blocks used by Product Apps.","summaryTitle":"Component Summary","summaryDescription":"Select a component to inspect its package identity, capabilities, and usage.","health":"Health","healthChecking":"Checking component health...","healthUnavailable":"Health status is not available.","healthFailed":"Component health check failed.","healthStatus":{"available":"Available","degraded":"Degraded","checking":"Checking"},"healthCheck":{"contract":"Contract","dependencies":"Dependencies","runtime":"Runtime","healthAction":"Health action"},"actionStatus":{"available":"Available","blocked":"Blocked","empty":"Empty","degraded":"Degraded"},"diagnosticAction":{"installDependency":"Install dependency","runHealthAction":"Run health action","openRuntimeLogs":"Review runtime logs","inspectRuntimeUsage":"Inspect runtime usage"},"actionTooltip":{"installDependency":"Inspect or restore this dependency","runHealthAction":"Run the health check again","openRuntimeLogs":"Open the latest Work with runtime logs","inspectRuntimeUsage":"Open the latest Work using this component"},"runtimeRuns":"{{count}} runs","runtimeFailures":"{{count}} failed","runtimeErrors":"{{count}} errors","runtimeWarnings":"{{count}} warnings","recentFailures":"Recent Failures","recentLogs":"Recent Logs","runtimeUsage":"Runtime usage","runtimeUsageDetail":"Work {{workId}}: {{runs}} runs, {{issues}} issues.","openOwningWork":"Open owning Work","capabilities":"Capabilities","dependenciesTab":"Capabilities & dependencies","noCapabilities":"No declared capabilities","usedBy":"Used By","noUsage":"No Product App usage yet","categoriesLabel":"Component types","inspect":"Inspect","usedByCount":"Used by {{count}} apps","unusedHint":"No Product App currently depends on this component"},"workStack":{"continueLabel":"Continue \\"{{title}}\\"","moreCount":"View all {{count}} works","collapse":"Collapse","relatedLabel":"Related work for {{name}}","attentionBadge":"{{count}} need attention"},"inspector":{"emptyTitle":"Select an app","emptyDescription":"The inspector shows launch scope, recent work, component graph, and maintenance actions.","launchPlan":"Launch plan","recentWork":"Recent work","noRecentWork":"No active work for this app.","componentGraph":"Component graph","noComponents":"This app has no resolved component references.","permissions":"Permissions","maintenance":"Maintenance"},"componentKinds":{"surface":"Surface","agent":"Agent","bridge":"Bridge","runtime":"Runtime","tool":"Tool","skill":"Skill"},"interaction":{"conversation":"Conversation","interactiveWorkspace":"Interactive workspace"},"owner":{"system":"System app","user":"My app","organization":"Organization app"},"componentSource":{"appPrivate":"App private","shared":"Shared"},"catalogSource":{"installedPackage":"Installed package","builtinMarketplace":"Marketplace source","publishedRelease":"Published release"},"componentRefSource":{"private":"Private","shared":"Shared"},"status":{"draft":"Draft","active":"Active","running":"Running","waiting_user":"Waiting","blocked":"Blocked","paused":"Paused","completed":"Completed","cancelled":"Cancelled","failed":"Failed","archived":"Archived"},"detail":{"enabled":"Enabled","disabled":"Disabled","dialogLabel":"{{name}} details","topBar":{"backToApps":"App Center"},"header":{"chooseWorkspace":"Choose workspace","installed":"Installed","native":"Native","notInstalled":"Not installed","workCount":"{{count}} works","workMode":"Work mode"},"sectionsLabel":"Details","journeys":{"overview":{"label":"Overview","description":"Understand its value and the best next step."},"work":{"label":"Work","description":"Continue existing Work or start something new."},"customize":{"label":"Customize & evolve","description":"Edit, fork, and review upstream changes."},"control":{"label":"Manage & trust","description":"Versions, permissions, data, and technical composition."}},"overview":{"recentWork":"Recent work","recentWorkDescription":"Pick up where you left off without starting over.","viewAllWork":"View all {{count}}"},"customize":{"systemTitle":"Make it yours without changing the system app","systemDescription":"Create a personal fork from this Release. System updates remain separate until you choose to review them.","userTitle":"Continue evolving your app","userDescription":"Open an editable Draft based on the active Release. Existing Work keeps using its original Release.","upstreamBadge":"Upstream update","upstreamTitle":"The source app has moved forward","upstreamDescription":"Review the upstream Release in a rebase Draft, resolve differences, then publish only when you are satisfied.","versionTitle":"Release and recovery","versionDescription":"Publishing creates an immutable Release. Activation changes only new Work.","activeRelease":"Active Release","availableRelease":"Available Release","owner":"Ownership"},"control":{"componentsTitle":"Components and capabilities","technicalTitle":"Technical and package details","technicalHint":"Advanced"},"tabs":{"summary":"Summary","work":"Work","package":"Package","overview":"Overview","start":"Start & Work","workObjects":"Work Objects","components":"Components","permissions":"Permissions","source":"Version & Source","technical":"Component Graph"},"sectionDescription":{"work":"Start new work or resume an existing Work from the same place.","package":"Installed package, catalog release, update, dependency, and component graph facts.","start":"Start new work or resume an existing Work from the same place.","components":"The surface, agent, bridge, runtime, tool, and skill packages this app depends on.","permissions":"The app-level permissions, component capabilities, and data lifecycle policy.","source":"Installed package, catalog release, update, and dependency facts.","technical":"Component composition and dependency calls derived from app.json and component.json."},"advanced":{"launchConfig":"Launch configuration"},"sections":{"permissions":"Permissions"},"summary":{"availability":"Availability","permissionCount":"{{enabled}} / {{total}} enabled","permissions":"Permissions","status":"Status"},"start":{"bestAction":"Best next action","launchHint":"This app can start from the current system context or continue an existing Work.","launchTitle":"Launch target","continueTitle":"Continue work","workTitle":"Related work","noWorkTitle":"No work yet","noWorkDescription":"Work created from this app will appear here.","workspaceRequiredHint":"This app needs a workspace before new work can start."},"workObjects":{"emptyTitle":"No work objects","emptyDescription":"This Product App has not declared durable work object kinds."},"components":{"capabilityCount":"{{count}} capabilities","graphSummary":"Component graph","unresolved":"Component package is not installed or not resolved."},"permissions":{"appTitle":"App permissions","componentTitle":"Component capabilities","dataTitle":"Data lifecycle"},"source":{"catalogSource":"Catalog source","dependencySummary":"Dependencies","installedStatus":"Installed status"},"runtime":{"identityTitle":"Runtime identity"},"technical":{"appNode":"Product App","canvasDescription":"A JSON-derived graph: app.components compose the first layer, component.dependencies continue the call chain.","canvasTitle":"Component relationship graph","dependencyEdges":"Dependency calls","dependencyNode":"Dependency","directComponents":"Direct components","directNode":"Direct","edgeKind":{"appComposition":"Composes","componentDependency":"Calls"},"edgesDescription":"Edges are read from app.components and component.dependencies.","edgesTitle":"Composition and calls","emptyDescription":"This entry does not expose Product App component JSON.","emptyTitle":"No component graph","filter":{"all":"All","composition":"Composition","dependencies":"Calls","permissions":"Permissions","unresolved":"Unresolved"},"filterLabel":"Component graph filters","from":"From","implementation":"Implementation","incoming":"Incoming","inspectorTitle":"Selected JSON","nodesDescription":"Direct app components and dependency-only components are shown together.","nodesTitle":"Components","outgoing":"Outgoing","primarySurface":"Primary surface","relation":"Relation","role":"Role","selectApp":"Inspect app {{name}}","selectComponent":"Inspect component {{name}}","selectRelation":"Inspect relation {{from}} to {{to}} as {{role}}","selectedAppTitle":"Selected app","selectedComponentTitle":"Selected component","selectedEdgeTitle":"Selected relation","to":"To","unresolved":"Unresolved"}},"workMultiplicity":{"multiple":"Multiple works","singleton":"Single work"},"dataLifecycle":{"fields":{"retention":"Retention","deletion":"Deletion","migration":"Migration","share":"Sharing"},"retention":{"workRuntimeScoped":"Work runtime scoped","sessionScoped":"Session scoped","userManaged":"User managed","externalSystem":"External system"},"deletion":{"deleteWithWork":"Delete with Work","deleteOnUserRequest":"Delete on request","noDurableData":"No durable data","externalSystem":"External system"},"migration":{"notSupported":"Not supported","exportImport":"Export / import","schemaVersioned":"Schema versioned","externalSystem":"External system"},"share":{"excludeRuntimePrivateData":"Exclude runtime-private data","declaredWorkObjectsOnly":"Declared work objects only","externalReferenceOnly":"External reference only"}},"launchKind":{"agentSession":"Start an agent-backed work session.","applicationSurface":"Open an interactive app surface.","appBuilder":"Open App Builder.","none":"No launch target"},"launchScope":{"systemAllowed":"System allowed","workspaceOptional":"Workspace optional","workspaceRequired":"Workspace required"},"fields":{"id":"ID","kind":"Kind","version":"Version","author":"Author","authors":"Authors","target":"Target","surface":"Surface","agent":"Agent","scope":"Scope","appId":"App ID","surfaceMode":"Surface mode","truthSource":"Truth source","visibility":"Visibility","componentLockId":"Component lock ID"},"workObjectScope":{"global":"Global","workspace":"Workspace","project":"Project","asset":"Asset","device":"Device","runtime":"Runtime"},"permission":{"fs":"Filesystem","net":"Network","shell":"Shell","gui":"GUI","secrets":"Secrets","ai":"Model access"},"catalogVisibility":{"discoverable":"Discoverable","installedOnly":"Installed only","hidden":"Hidden"},"surfaceMode":{"chatPrimary":"Chat primary","sidecarLinked":"Sidecar linked","immersivePrimary":"Immersive primary","embeddedObject":"Embedded object"},"truthSource":{"ownedObjectState":"Owned object state","runtimeFact":"Runtime fact"}}`),H0={badges:{multiAgentComponent:"Multi-Agent",standaloneAgentComponent:"Single Agent",evolutionLab:"Evolution Lab"},agenticOs:{name:"Sparo OS",description:"System control plane for orchestration and lifecycle coordination; not shown as an app entry."},runno:{name:"Runno",description:"Sparo OS's general execution unit: flexible, efficient, and strongly goal-oriented for handling all kinds of tasks."},bitfunCoder:{name:"BitFun Coder",description:"An efficient, high-completion Code Agent from the open-source community for implementation, debugging, refactoring, troubleshooting, and other software development work."},cowork:{name:"Cowork Assistant",description:"An office delivery Agent for documents, spreadsheets, slides, and material organization, turning everyday work into polished output."},design:{name:"Designer",description:"A product and UI design Agent that turns ideas, requirements, and references into prototypes, interfaces, and visual directions."},deepResearch:{name:"Deep Research",description:"A deep research Agent for finding sources, comparing viewpoints, organizing evidence, and turning complex questions into clear conclusions."},productAppRuntime:{name:"Product App Runtime",description:"Runs Product Apps with FlowChat, app-owned tools, runtime state, and issue feedback bound to the active Work."},appBuilder:{name:"App Builder",description:"Build a personal intelligent app around your way of working by understanding your needs or existing apps, then recomposing features, workflows, and methods."}},q0={scene:{loading:"Loading...",updating:"Updating preview...",loadFailed:"Load failed: {{error}}",retry:"Retry",reload:"Reload"},messages:{recompiled:"Product App runtime recompiled.",recompileFailed:"Failed to recompile Product App runtime: {{error}}",installDepsFailedGeneric:"Failed to install runtime dependencies.",installDepsOk:"Runtime dependencies installed.",installDepsFailed:"Failed to install runtime dependencies: {{error}}",workerStopped:"Product App worker stopped.",workerStopFailed:"Failed to stop Product App worker: {{error}}"}},V0={toolUpdateFailed:"Tool update failed",componentStatusUpdateFailed:"Component status update failed",toolResetFailed:"Tool reset failed",skillUpdateFailed:"Skill update failed",subagentUpdateFailed:"Subagent update failed"},G0={appCategories:z0,productSystem:U0,apps:H0,productAppRuntime:q0,messages:V0},K0="Skills",Q0="Agents",J0="MCP",Y0="Refresh capability states",Z0="Reconnect",X0="{{count}} MCP server(s) need attention",eA="Failed to load capabilities",tA="Failed to update capability switch",nA="{{name}} reconnected",oA="Failed to reconnect {{name}}",sA="No skills configured",iA="No agents available",aA="No agents available",rA="No MCP servers configured",lA="Path",cA="Tools",dA="Type",uA="Click to copy path",pA="Path copied",mA="Failed to copy path",gA={skills:K0,subagents:Q0,mcp:J0,refresh:Y0,reconnect:Z0,mcpWarning:X0,loadFailed:eA,toggleFailed:tA,mcpReconnectSuccess:nA,mcpReconnectFailed:oA,emptySkills:sA,emptySubagents:iA,emptyAgents:aA,emptyMcp:rA,path:lA,toolCount:cA,serverType:dA,clickToCopy:uA,pathCopied:pA,pathCopyFailed:mA},hA="Daily Letter",fA={label:"Daily letter navigation",eyebrow:"Letters",today:"Today",todayEmpty:"No letter yet",empty:"No letters yet",allLetters:"All letters",filteredEmpty:"No letters match these filters.",total:"{{count}} letter(s)"},yA={loading:"Loading letters",generating:"Writing...",noDate:"No date selected"},wA={loadFailed:"Failed to load daily letters.",generateFailed:"Failed to write today's letter.",generateDisabled:"Daily Letter is turned off in settings.",generateNoResult:"No new letter was written this time. Please try again later.",receiptFailed:"Failed to submit receipt.",sealFailed:"Failed to seal today's letter."},vA={chip:"Writing",title:"Gathering today",body:"Quietly collecting what today really left behind, and writing it into a letter you can read slowly.",hint:"The letter will unfold here once it is ready. Feel free to keep working.",elapsed:"Writing for {{seconds}}s",elapsedMinutes:"Writing for {{minutes}}m {{seconds}}s"},bA={label:"Full letter",eyebrow:"Daily Letter",writtenAt:"Written at {{time}}",pending:"{{count}} memory suggestion(s) await your receipt",signature:"Your letter"},kA={generate:"Summon the letter",full:"Unfold the letter",receipt:"Give receipt",seal:"Seal today",close:"Close"},SA={label:"Dates",title:"Choose dates",from:"From",to:"To",clear:"Clear dates",hint:"Click a start date, then an end date.",summary:"{{start}} - {{end}}",pickEndHint:"Now choose an end date (start: {{start}}).",pickEndError:"Select an end date to complete the range.",previousMonth:"Previous month",nextMonth:"Next month",cancel:"Cancel",apply:"Apply"},xA={agenticOs:"Global",workspace:"Workspace"},CA={title:"No letter has arrived yet",body:"Sparo writes one letter every day. Today's is still on its way.",loadingBody:"Looking for today's letters."},AA={ready:"Ready",insufficient_context:"Quiet day",needs_receipt:"Receipt",sealed:"Sealed"},_A={label:"Receipt suggestions",title:"For your receipt",empty:"Nothing needs your receipt in this letter.",accept:"Keep",edit:"Edit",dismiss:"Skip",editPrompt:"Adjust this memory before keeping it",editTitle:"Edit before keeping",status:{pending:"Waiting",accepted:"Kept",edited:"Edited",dismissed:"Skipped"}},TA={label:"App idea",title:"P.S."},PA={label:"Daily letter arrival",title:"A letter has arrived",later:"Later",chipLabel:"Today's letter is waiting"},FA={title:hA,rail:fA,states:yA,messages:wA,writing:vA,paper:bA,actions:kA,date:SA,scope:xA,empty:CA,status:AA,receipt:_A,app:TA,arrival:PA},RA="File Manager",NA={aria:"File Manager navigation",home:"Home",workspaces:"Workspaces",system:"This PC",pinned:"Pinned",recent:"Recent"},DA={addToChat:"Add to Chat",ask:"Wake Sparo",back:"Back",collapseSidebar:"Collapse sidebar",copyPath:"Copy Path",expandSidebar:"Show sidebar",forward:"Forward",openExternally:"Open Externally",openInSparo:"Open in Sparo",openInExcelLive:"Open in Excel Live",openAsWorkspace:"Open as Workspace",pin:"Pin",refresh:"Refresh",up:"Up"},IA={placeholder:"Type a path, for example D:\\\\Projects or ~/Downloads"},MA={recentWorkspaces:"Recent Workspaces",welcomeTitle:"Browse, organize, and act on files",welcomeDescription:"Pick a workspace, drive, or pinned folder on the left, or ask Filer to organize, find, or clean up your files."},jA={title:"Try asking Filer",organize:{label:"Organize this folder",hint:"Group by type and date",prompt:"Organize this location: group files by type and date, and show me a preview plan before moving anything."},duplicates:{label:"Find duplicates",hint:"Spot redundant copies",prompt:"Find duplicate or near-duplicate files in this location and suggest which copy to keep."},space:{label:"Free up space",hint:"Find large or stale files",prompt:"Show what is taking up the most space here, and flag large or stale files that are safe to remove or archive."},summarize:{label:"Summarize this folder",hint:"See what is inside",prompt:"Summarize what is in this location: file types, notable items, and how it is organized."}},EA={drives:"Drives",quickFolders:"Quick Folders"},LA={folder:"Folder",loading:"Loading directory...",noPath:"No path selected",noResults:"No matching files",searchPlaceholder:"Search this location...",sortBy:"Sort files",toggleSortOrder:"Toggle sort order"},$A={modified:"Modified",name:"Name",size:"Size",type:"Type"},OA={archive:"Archive",audio:"Audio",document:"Document",folder:"Folder",image:"Image",other:"Other",text:"Text",video:"Video"},BA={ask:"Ask Sparo about this",open:"Open",openAsWorkspace:"Open as Workspace",pin:"Pin",reveal:"Reveal in OS"},WA={addToChat:"Add selection to chat",askSparo:"Ask Sparo with this context",copyPath:"Copy path",findDuplicates:"Find duplicates",openAsWorkspace:"Open as workspace",openExternal:"Open externally",openInSparo:"Open in Sparo",operationPlan:"Create operation plan",organize:"Organize with Filer",preview:"Preview",reveal:"Reveal in OS",summarize:"Summarize"},zA={items:"{{count}} items",selected:"{{count}} selected",disk:"{{free}} free of {{total}}"},UA={actions:"Actions",emptyDescription:"Select files or folders to preview them, add them to chat, or hand the selection to Sparo.",emptyTitle:"Nothing selected",items:"Items",preview:"Preview",previewLoading:"Loading preview...",previewUnavailable:"Preview unavailable",plan:"Operation plan",planDraftDescription:"File changes are prepared as a reviewed, recoverable plan first. Nothing is executed until you confirm the plan.",planDraftReason:"Move selected files to the File Workbench trash with a restore path.",planDraftTitle:"Recoverable file cleanup",planExecuting:"Executing...",planExecuted:"Plan executed",planPartiallyFailed:"Plan partially failed",planResultItems:"{{count}} results",confirmExecute:"Confirm and execute",planNeedsTarget:"Not recoverable",planLoading:"Planning...",planUnavailable:"Plan unavailable",planHighRisk:"{{count}} high risk",planConflicts:"{{count}} conflicts",planItems:"{{count}} planned items",requiresPlan:"plan",selectionCount:"{{count}} selected",title:"Workbench",totalSize:"Total size",unknown:"Unknown"},HA={aria:"View mode",grid:"Grid",list:"List"},qA={today:"Modified today at {{time}}",week:"Modified {{weekday}}"},VA={brand:RA,activity:NA,actions:DA,address:IA,home:MA,suggestions:jA,system:EA,browser:LA,columns:$A,categories:OA,context:BA,recommendations:WA,status:zA,workbench:UA,view:HA,recency:qA},GA="Memory Library",KA="Review what Agentic OS remembers about preferences, collaboration feedback, and workspace context.",QA="Loading memories...",JA="Search memories, types, or content...",YA={category:"Type",status:"Status"},ZA={showing:"{{shown}} of {{total}} memories"},XA={scope:"Scope",settings:"Settings",storage:"Storage location",noWorkspace:"No workspace open",workspaceUnavailable:"Workspace memory is unavailable"},e_={all:"All memories",global:"Agentic OS",workspace:"Current workspace",workspace_overview:"Workspace overview"},t_={both:"All scopes",global:"Global memory",workspace:"Workspace memory"},n_={active:"Active",archived:"Archived",tentative:"Tentative",confirmed:"Confirmed",consolidated:"Consolidated"},o_={normal:"Normal",private:"Private",secret:"Secret"},s_={all:"All",memory:"Memory",soul:"Soul",user:"User",milestone:"Milestones",host_overview:"Host overview",memory_log:"Memory log",workspace_overview:"Workspace overview",unknown:"Unclassified"},i_={title:"Auto memory",loading:"Loading auto-memory status...",summary:"Global: {{global}}; workspace: {{workspace}}.",enabledEvery:"every {{count}} turns",disabled:"off"},a_={openSettings:"Auto-memory settings",refresh:"Refresh",openStorage:"Open",edit:"Edit",save:"Save",cancel:"Cancel",reveal:"Open location",forget:"Forget",archive:"Archive",pin:"Pin",triggerConsolidation:"Trigger consolidation",forgetByTag:"Forget by tag",consolidation:{memory_consolidation:"Run memory consolidation",host_scan:"Run host scan",workspace_overview:"Refresh workspace overviews",milestone:"Refresh milestones"}},r_={memory:"The main canonical memory file for this scope.",soul:"Assistant persona and durable global behavior anchors.",user:"This memory shapes how the agent understands the user's identity, preferences, and communication style.",milestone:"Long-lived global milestones distilled from daily reports.",host_overview:"This memory helps Agentic OS understand where directories, tools, and work should live on the current host machine.",memory_log:"Recent append-only memory journal entries collected automatically.",workspace_overview:"This memory helps Agentic OS decide which workspace a task should route to.",unknown:"This memory has no clear type. Add frontmatter so future use can be more precise."},l_={noResults:"No matching memories",noSelection:"Select a memory to view details",emptyFile:"This memory file is empty.",unavailable:"Unavailable"},c_={loadFailed:"Failed to load memories",saveSuccess:"Memory saved",saveFailed:"Failed to save memory",revealFailed:"Failed to open location",deleteSuccess:"Memory forgotten",deleteFailed:"Failed to forget memory",archiveSuccess:"Memory archived",archiveFailed:"Failed to archive memory",consolidationTriggered:"Consolidation triggered",consolidationFailed:"Failed to trigger consolidation"},d_={title:"Forget this memory?",message:'"{{name}}" will be removed from the memory library and the agent will no longer use it proactively.'},u_={title:"Archive this memory?",message:'"{{name}}" will be moved to the archive and excluded from active context.'},p_={modes:{graph:"Constellation",list:"List"},summary:"{{total}} memories · {{global}} global · {{workspaces}} workspace orbit(s)",workspaceCount:"{{count}} workspace orbit(s)",hint:"Click a node for details · Scroll to zoom · Drag to pan"},m_={tabs:{summary:"Summary",content:"Content",relations:"Relations"},stats:{updated:"Last updated",words:"Words",lines:"Lines",related:"Related"},sections:{description:"Description"},sourceSession:"Source session",relations:{empty:"No related memories yet",reasons:{index:"Index in same scope","same-folder":"Same folder","cross-scope":"Cross-scope bridge"}}},g_={title:GA,subtitle:KA,loading:QA,searchPlaceholder:JA,filters:YA,results:ZA,sidebar:XA,scopeFilters:e_,scopes:t_,statuses:n_,sensitivity:o_,types:s_,autoMemory:i_,actions:a_,usageHints:r_,empty:l_,messages:c_,deleteDialog:d_,archiveDialog:u_,overview:p_,drawer:m_},h_={title:"Skills"},f_={titleAll:"Skill Library",summary:"{{count}} packages available in this environment"},y_={listLabel:"Skill packages",detailLabel:"Selected package details"},w_={searchPlaceholder:"Search packages or members...",addPackage:"Add package"},v_={typeLabel:"Package type",sourceLabel:"Source",type:{all:"All",suite:"Suites",standalone:"Standalone"},source:{all:"All sources",builtin:"Built-in",user:"User",project:"Project"}},b_={runtime:"Invocation details",command:"Command",type:"Type",status:"Status",level:"Location",path:"Path",router:"Router",tags:"Tags",members:"Members",member:"Suite member",memberCount:"{{count}} members",missingMembers:"Missing members",noMembers:"This suite has no available members.",healthReady:"Ready",healthMissing:"{{count}} missing",reveal:"Open package folder",deletePackage:"Delete package",backToSuite:"Back to suite",emptyTitle:"Select a Skill package",emptyDescription:"Choose a suite or standalone Skill to inspect its runtime command, source, and contents."},k_={title:"Management",agentLabel:"Apply to Agent",availabilityLabel:"Allow this Agent to use it",availabilityEnabled:"{{agent}} can invoke this package at runtime.",availabilityDisabled:"This package is blocked for {{agent}}.",noAgents:"No configurable Agents",filesTitle:"Files and installation",builtinDescription:"Built-in packages can be blocked or restored, but cannot be deleted.",removableDescription:"Open the package folder or permanently remove it from this library.",openFolder:"Open folder",delete:"Delete"},S_={title:"Skill Marketplace",subtitle:"Find reusable Skills and install them into the current project.",searchPlaceholder:"Search marketplace Skills...",resultsInfo:"{{count}} results for “{{query}}”",empty:{noMatch:"No marketplace Skills match this search.",noSkills:"No marketplace Skills are available."},item:{sourceLabel:"Source",downloadProject:"Install to project",installed:"Installed",downloading:"Installing..."},pagination:{info:"{{current}} / {{total}}",infoMore:"Page {{current}}"},detail:{linkLabel:"Link"}},x_={title:"Add Skill package",level:{label:"Install location",user:"User library (global)",project:"Project library (current workspace)",projectDisabled:" — open a workspace first",selectedProjectPath:"Current project: {{path}}"},path:{label:"Package folder",placeholder:"Select a Skill or suite folder",browseTooltip:"Browse folders",hint:"A Skill contains SKILL.md. A suite contains suite.json and its member folders."},validating:"Validating package...",actions:{close:"Close add package card",cancel:"Cancel",add:"Add package",adding:"Adding..."}},C_={empty:{noMatch:"No packages match the current filters.",noSkills:"No Skill packages are installed."}},A_={title:"Delete Skill package",message:"Delete the {{type}} package “{{name}}”? Its entire package folder will be removed.",cancel:"Cancel",delete:"Delete package"},__={invalidPath:"Select a valid Skill package folder.",noWorkspace:"Open a workspace before adding a project-level package.",addSuccess:"Package “{{name}}” added.",addFailed:"Could not add package: {{error}}",deleteSuccess:"Package “{{name}}” deleted.",deleteFailed:"Could not delete package: {{error}}",disableSuccess:"Package “{{name}}” blocked for this Agent.",enableSuccess:"Package “{{name}}” restored for this Agent.",availabilityUpdateFailed:"Could not update Agent availability: {{error}}",marketDownloadSuccess:"Skill “{{name}}” installed.",marketDownloadFailed:"Could not install Skill: {{error}}",revealPathFailed:"Could not open package folder: {{error}}"},T_={nav:h_,installed:f_,library:y_,toolbar:w_,filters:v_,detail:b_,management:k_,market:S_,form:x_,list:C_,deleteModal:A_,messages:__},P_={title:"SubAgents",subtitle:"Browse, manage, and maintain the SubAgents that top-level Agents can call.",searchPlaceholder:"Search name, description, or model",clearSearch:"Clear search",newSubagent:"New SubAgent",refresh:"Refresh"},F_={Explore:{name:"Explore",description:"Read-only subagent for wide codebase exploration. Prefer search-first workflows with Grep and Glob, then read only the relevant files."},FileFinder:{name:"File Finder",description:"Finds files and directories from semantic descriptions when exact paths are unknown."},ComputerUse:{name:"Computer Use",description:"Automates desktop apps, browsers, and OS UI by perceiving and operating the local environment."},DesignReview:{name:"Design Review",description:"Read-only reviewer for HTML/CSS/JS design deliverables, focused on syntax, references, tokens, and layout risks."}},R_={all:"All",ready:"Callable",readonly:"Readonly",sources:"Sources",builtin:"Built-in",user:"User",project:"Project"},N_={resultCount:"{{count}} results",empty:"No SubAgents match the current filters",noDescription:"No description yet"},D_={empty:"Select a SubAgent to view details",noDescription:"This SubAgent does not have a role description yet.",edit:"Edit",delete:"Delete",availabilityHint:"When enabled, top-level Agents and orchestration flows can keep referencing it. When disabled, the definition stays but should not be scheduled.",readonlyHint:"This is a readonly SubAgent, better suited for search, analysis, and organization tasks.",writeHint:"This SubAgent can run write-capable tasks and is better suited for execution-heavy work.",toolCount:"{{count}} tools configured",defaultToolsFallback:"No custom tool set is configured. The default tool set will be used.",callReady:"This SubAgent is currently ready to be called by higher-level Agents.",callBlocked:"This SubAgent is currently disabled and should not be called by higher-level Agents.",sections:{availability:"Availability",positioning:"Positioning",tools:"Tool Scope",calling:"Calling Status"}},I_={createTitle:"Create SubAgent",createSubtitle:"Define the minimum setup first, then refine it after creation.",editTitle:"Edit SubAgent",editSubtitle:"Update description, prompt, tool scope, and availability.",cancel:"Cancel",create:"Create",save:"Save",readonlyOn:"Readonly tasks only",readonlyOff:"Write-capable tasks allowed",enabledOn:"Enabled",enabledOff:"Disabled",noTools:"No tool choices are available right now. The default tool set will be used after save.",fields:{name:"Name",level:"Level",readonly:"Readonly Mode",enabled:"Enabled",description:"Role Description",prompt:"System Prompt",tools:"Tool Scope"},levels:{user:"User",project:"Project"},placeholders:{name:"Start with a letter, then use letters, numbers, underscores, or hyphens",description:"Describe what this SubAgent is responsible for",prompt:"Describe what it is good at, where its boundaries are, and how it should collaborate"},validation:{nameRequired:"Please enter a name",nameFormat:"The name must start with a letter and contain only letters, numbers, underscores, or hyphens",descriptionRequired:"Please enter a role description",promptRequired:"Please enter a system prompt",projectWorkspaceRequired:"Project-level SubAgents require an open workspace"}},M_={builtin:"Built-in",user:"User",project:"Project",readonly:"Readonly",disabled:"Disabled"},j_={ready:"Ready to call",incomplete:"Needs more definition",disabled:"Not callable"},E_={title:"Delete SubAgent",message:'Are you sure you want to delete "{{name}}"? This cannot be undone.',confirm:"Delete",cancel:"Cancel"},L_={loadDetailFailed:"Failed to load detail: ",toggleFailed:"Failed to change status: ",enabledSuccess:"{{name}} enabled",disabledSuccess:"{{name}} disabled",deleteSuccess:"{{name}} deleted",deleteFailed:"Delete failed: ",createSuccess:"{{name}} created",createFailed:"Create failed: ",updateSuccess:"{{name}} saved",updateFailed:"Save failed: "},$_={loading:"Loading..."},O_={page:P_,builtin:F_,sidebar:R_,list:N_,detail:D_,editor:I_,badges:M_,readiness:j_,deleteDialog:E_,messages:L_,status:$_},B_={title:"Tools",subtitle:"Browse the actions agents can call and their permission boundaries",learnMore:"How agents use tools"},W_={builtin:"Built-in",mcp:"MCP",manageServers:"Manage MCP",noServers:"No MCP servers",toolsUnder:"{{count}} tools"},z_={all:"All",file:"File",navigate:"Navigate",shell:"Shell",web:"Web",desktop:"Desktop",plan:"Plan",session:"Session",interact:"Interact",delegate:"Delegate",mcpMeta:"MCP Meta"},U_={read:"Read",write:"Write",danger:"Dangerous"},H_={sourceLabel:"Tool source",categoryLabel:"Tool category",connectedServers:"{{count}} server connected",allPermissions:"All levels",enabledOnly:"Enabled only"},q_={placeholder:"Search tools…"},V_={listLabel:"Tool list",detailLabel:"Tool details",countSuffix:"{{count}} tools",pagination:"Tool list pagination",emptyAll:"No tools match your filters.",emptyCategory:"No tools in this category."},G_={selectHint:"Select a tool on the left to see its documentation.",languageToggle:"Documentation language",langToggleZh:"中文",langToggleEn:"EN",sections:{what:"What it does",when:"When to use",whenNot:"When not to use",inputs:"Inputs",outputs:"Outputs",related:"Related tools",notes:"Notes"},sourceBuiltin:"Built-in",sourceMcp:"MCP · {{server}}",inputsNone:"No explicit inputs.",outputsNone:"Returns a structured result.",relatedNone:"No directly related tools.",notesNone:"No additional notes."},K_={header:{serversTotal:"{{count}} servers",toolsTotal:"{{count}} tools",errors:"{{count}} error"},actions:{add:"Add Server",refresh:"Refresh",editConfig:"Edit Config"},empty:{title:"No MCP servers yet",hint:"Add an MCP server to extend available tools.",cta:"Add MCP Server"},server:{toolsSection:"Tools ({{count}})",configSection:"Configuration",noTools:"This server has not exposed any tools yet.",start:"Start",stop:"Stop",restart:"Restart",delete:"Delete",deleteConfirmTitle:"Delete MCP server?",deleteConfirmMessage:'"{{id}}" will be removed. This cannot be undone.',transport:"Transport",url:"URL",command:"Command"},editor:{title:"MCP JSON Configuration",hint:"Use the standard mcpServers format. Saving will restart affected servers.",examples:{localProcess:"Local process (stdio)",remoteService:"Remote service (sse)"},save:"Save",cancel:"Cancel",saveSuccess:"MCP configuration saved.",saveFailed:"Failed to save MCP configuration: {{error}}",loadFailed:"Failed to load MCP configuration: {{error}}"}},Q_=JSON.parse(`{"AgentHandoff":{"name":"AgentHandoff","summary":"Hand work to an appropriate agent session.","what":"Creates or reuses a focused agent session when OSAgent decides a specialist should own the work. Returns the target session and workspace context.","when":["A specialist agent should own a bounded piece of work","A task belongs in an existing focused session"],"whenNot":["OSAgent can answer or act well in-place","A quick clarification is enough"],"related":[{"name":"Task","note":"Actually hand off a bounded sub-task to a subagent."}],"notes":"Available as an OSAgent handoff tool; ordinary worker agents usually do not need it."},"LS":{"name":"LS","summary":"List entries in a directory.","what":"Lists files and subdirectories at a given path. Useful as the first step of project exploration.","when":["Getting a quick overview of a folder","Before deciding which files to read"],"whenNot":["Searching by name pattern — use Glob","Searching by content — use Grep"],"related":[{"name":"Glob","note":"Match paths by pattern (**/*.ts)."},{"name":"Grep","note":"Search inside file contents."}]},"Read":{"name":"Read","summary":"Read the content of a file.","what":"Reads a file from the workspace and returns its content with line numbers. Supports offset/limit for large files.","when":["Inspecting source before editing","Citing exact code in responses"],"whenNot":["Binary files are best previewed by the file viewer","Full-tree search — use Grep"],"related":[{"name":"Edit","note":"Modify precise regions after reading."},{"name":"Grep","note":"Search first to locate the lines to read."}]},"Glob":{"name":"Glob","summary":"Find files by glob pattern.","what":"Matches paths using glob syntax such as **/*.tsx. Returns files sorted by modification time.","when":["Finding files by name/extension","Narrowing the search space before Grep"],"whenNot":["Searching file contents — use Grep"],"related":[{"name":"Grep","note":"Run content search on the matched subset."}]},"Grep":{"name":"Grep","summary":"Search file contents with ripgrep.","what":"Runs a ripgrep search across the workspace. Supports regex, file filters, case options, and context lines.","when":["Locating symbols or keywords","Auditing usages before a refactor"],"whenNot":["You only need filenames — use Glob","Single-file quick scan — use Read"],"related":[{"name":"Glob","note":"Limit the file set first."},{"name":"Read","note":"Open a specific match to see full context."}]},"Write":{"name":"Write","summary":"Create or fully overwrite a file.","what":"Writes the given content to a file, creating it if necessary. Previous content is replaced.","when":["Creating a new file","Generating a file from scratch"],"whenNot":["Editing an existing file partially — use Edit","Modifying binaries"],"related":[{"name":"Edit","note":"Safer for local edits to existing files."},{"name":"GetFileDiff","note":"Review changes after writing."}],"notes":"Destructive by design — always confirm intent before use."},"Edit":{"name":"Edit","summary":"Apply exact string replacement to a file.","what":"Replaces an exact, unique string inside a file. Preserves surrounding content and original line endings.","when":["Precise local edits","Renaming or patching a specific region"],"whenNot":["Rewriting large portions — prefer Write","Changes where anchors are not unique"],"related":[{"name":"Read","note":"Read first to craft a unique anchor."},{"name":"GetFileDiff","note":"Inspect the change set."}]},"Delete":{"name":"Delete","summary":"Delete a file from the workspace.","what":"Removes a file path. Fails gracefully if the path does not exist.","when":["Removing generated or obsolete files"],"whenNot":["Uncertain whether the file is still referenced"],"related":[{"name":"Grep","note":"Search for references before deleting."}],"notes":"Irreversible — prefer a commit before batch deletes."},"Bash":{"name":"Bash","summary":"Run a shell command in a workspace terminal.","what":"Executes a shell command and streams stdout/stderr. Supports background mode for long-running processes.","when":["Running build/test commands","Invoking CLIs (git, pnpm, cargo)"],"whenNot":["File operations available as dedicated tools — prefer Read/Edit/LS"],"related":[{"name":"TerminalControl","note":"Manage running terminal sessions."}],"notes":"Can affect the host system — treat as dangerous and confirm destructive commands."},"TerminalControl":{"name":"TerminalControl","summary":"Manage long-running terminal sessions.","what":"Reads output, writes input, and terminates background terminals started by Bash.","when":["Interacting with a dev server","Polling a long-running process"],"whenNot":["One-shot commands — just use Bash"],"related":[{"name":"Bash","note":"Start the terminal first."}]},"SessionControl":{"name":"SessionControl","summary":"Control flow of the current agent session.","what":"Pauses, resumes, or ends the current session under well-defined conditions.","when":["Explicit user hand-back","Terminating after a final answer"],"whenNot":["Ordinary turns — the coordinator handles flow automatically"]},"SessionMessage":{"name":"SessionMessage","summary":"Post a structured message to the session transcript.","what":"Emits a first-class message (status, notice, summary) into the current session for the user to see.","when":["Publishing intermediate milestones","Sharing a structured summary"],"whenNot":["Normal assistant replies — just answer"]},"SessionHistory":{"name":"SessionHistory","summary":"Recall earlier turns in the session.","what":"Returns a condensed view of earlier messages in the current session.","when":["Context compaction","Referring to a past decision"],"whenNot":["Looking outside the current session — use project search tools"]},"TodoWrite":{"name":"TodoWrite","summary":"Maintain a structured todo list for the current task.","what":"Creates or updates an ordered list of todos with states (pending / in_progress / completed / cancelled).","when":["Tasks with 3+ steps","Long multi-file refactors"],"whenNot":["Trivial single-step tasks"],"related":[{"name":"CreatePlan","note":"For larger plans that deserve a document."}]},"Cron":{"name":"Cron","summary":"Schedule recurring or delayed jobs.","what":"Creates, lists and deletes scheduled jobs that fire prompts into a session at a given time or interval.","when":["Daily briefings","Interval-based polling tasks"],"whenNot":["One-off immediate actions"]},"Task":{"name":"Task","summary":"Delegate a bounded sub-task to a subagent.","what":"Launches a specialized subagent with its own prompt and scope. Returns the subagent's final result.","when":["Parallelizable research","Clearly scoped sub-problems"],"whenNot":["Work that needs tight back-and-forth with the user"],"related":[{"name":"AgentHandoff","note":"Hand work to a specialist session when ownership is clear."}]},"Skill":{"name":"Skill","summary":"Invoke an installed skill (recipe).","what":"Runs a registered skill profile that bundles prompts, tool policies and knowledge.","when":["Repeatable workflows that already have a skill"],"whenNot":["One-off work that does not justify a skill"]},"AskUserQuestion":{"name":"AskUserQuestion","summary":"Ask the user a multiple-choice question.","what":"Prompts the user with a structured question and discrete options; blocks further tool calls until answered.","when":["Ambiguous requirements","Choosing between alternatives"],"whenNot":["You can safely make an assumption and proceed"]},"WebSearch":{"name":"WebSearch","summary":"Search the web.","what":"Runs a web search and returns a list of results with titles and snippets.","when":["Fresh external information","Library or API references"],"whenNot":["Project-internal questions — use Grep"]},"WebFetch":{"name":"WebFetch","summary":"Fetch a URL as readable text.","what":"Downloads a webpage and returns it as markdown. Useful after WebSearch picks the best link.","when":["Reading an article or docs page","Extracting structured text from a URL"],"whenNot":["Binary assets or files behind auth"],"related":[{"name":"WebSearch","note":"Find the URL first, then fetch it."}]},"ListMCPResources":{"name":"ListMCPResources","summary":"List resources exposed by an MCP server.","what":"Discovers the resources (files, datasets, documents) an MCP server exposes for reading.","when":["Exploring what an MCP server offers"]},"ReadMCPResource":{"name":"ReadMCPResource","summary":"Read an MCP resource's content.","what":"Fetches the content of a resource exposed by an MCP server."},"ListMCPPrompts":{"name":"ListMCPPrompts","summary":"List prompt templates exposed by an MCP server.","what":"Discovers the prompt templates an MCP server offers for use by the agent."},"GetMCPPrompt":{"name":"GetMCPPrompt","summary":"Render an MCP prompt template.","what":"Renders a server-supplied prompt template with the given arguments."},"GenerativeUI":{"name":"GenerativeUI","summary":"Render a live interactive widget in the chat.","what":"Produces a small interactive UI (form, choice widget, progress card) directly inline in the conversation.","when":["Asking for structured input beyond yes/no","Showing progress of a long operation"]},"GetFileDiff":{"name":"GetFileDiff","summary":"Get the unified diff for a file.","what":"Returns the unified diff between the workspace version and a given baseline for a file."},"Log":{"name":"Log","summary":"Append a structured log entry.","what":"Writes a structured log entry for later inspection. Useful for debugging complex agent runs."},"CreatePlan":{"name":"CreatePlan","summary":"Create a plan document for a task.","what":"Creates or updates a plan markdown document describing the goals, steps and risks of a task.","related":[{"name":"TodoWrite","note":"Convert plan steps into runtime todos."}]},"CodeReview":{"name":"CodeReview","summary":"Submit a code review against recent changes.","what":"Runs a code review pass over the recent diff and returns findings."},"CreateProductApp":{"name":"CreateProductApp","summary":"Initialize a new Product App scaffold.","what":"Bootstraps a new Product App project with a default template."},"CreateProductAppComponent":{"name":"CreateProductAppComponent","summary":"Create an app-private Product App component scaffold.","what":"Adds a Surface, Agent, Bridge, Runtime, Tool, or Skill component scaffold to an existing Product App package and refreshes the lock."},"GetProductAppPackage":{"name":"GetProductAppPackage","summary":"Read a Product App package.","what":"Reads app.json, app.lock.json, private components, resolved components, and package plans without modifying files."},"UpdateProductAppPackage":{"name":"UpdateProductAppPackage","summary":"Update Product App package metadata.","what":"Updates structured Product App metadata, launch, primary surface, interaction model, and work multiplicity, then refreshes the component lock."},"RefreshProductAppLock":{"name":"RefreshProductAppLock","summary":"Refresh a Product App component lock.","what":"Resolves a Product App package, updates app.json with the latest component lock digest, and rewrites app.lock.json."},"ResolveBuilderPreviewTarget":{"name":"ResolveBuilderPreviewTarget","summary":"Resolve a Builder preview target.","what":"Resolves Product App preview identity, mode, Workbench placement, and evidence boundary without claiming runtime execution."},"ComputerUse":{"name":"ComputerUse","summary":"Automate the desktop (mouse, keyboard, screenshots).","what":"Unified desktop automation: click, mouse move, scroll, drag, screenshot, locate-on-screen, key chord, type text, wait.","when":["Driving a GUI app that has no API","Taking screenshots as evidence"],"whenNot":["Anything reachable via CLI or filesystem"],"notes":"Can affect any application on the host — treat as dangerous and confirm before destructive actions."}}`),J_={page:B_,sidebar:W_,categories:z_,permissions:U_,filters:H_,search:q_,list:V_,detail:G_,mcp:K_,builtin:Q_},Y_="Welcome",Z_="Welcome back to",X_="Welcome",eT="Start",tT="Sparo OS Workspace",nT="A real workspace, not just a chat box",oT="An AI assistant with personality, memory, and real execution power. Sessions and Product Apps all work around the same workflow, so AI is doing work, not just replying.",sT="New BitFun Coder Session",iT="Turn a goal into a verified result with flexible execution, debugging, automation, and delivery",aT="New Cowork Assistant Session",rT="Great for clarifying requests, moving tasks forward, drafting content, and everyday collaboration",lT="Projects and Workspaces",cT="Open a project to start Code or Cowork Assistant, or switch to one of your recent workspaces.",dT="No recent workspaces yet",uT={message1:"Welcome back. Let's turn another idea into something real.",message2:"Hi. Feels like a good day to build something fun.",message3:"Your creative partner is online and ready to work.",message4:"Welcome to Sparo OS. Let's make something interesting."},pT={workspace:{title:"AI in action",description:"Thinking chains, terminal commands, code diffs, and planning all show up live so the process stays transparent."},team:{title:"Your AI team",description:"Set up Code, Cowork Assistant, and other agents for different jobs, then let them collaborate on more complex tasks."},assistant:{title:"A workspace that keeps growing",description:"The shared runtime workspace keeps context for ongoing collaboration."}},mT="Coming Soon",gT="Switch Workspace",hT="Open",fT="Remove from recent",yT="New",wT="No other workspaces",vT="Pick a scene and let's build something great",bT={title:"Welcome to Sparo OS",subtitle:"BitFun Coder — your default execution partner for turning goals into results.",noWorkspaceHint:"No workspace opened yet",openProject:"Open Project",openProjectDesc:"Select an existing project directory to start your AI-powered coding journey.",newProject:"New Project",newProjectDesc:"Create a brand new project from scratch."},kT={tabLabel:Y_,welcomeBack:Z_,welcomeTabTitle:X_,quickStart:eT,heroBadge:tT,heroTitle:nT,heroDescription:oT,newBitfunCoderSession:sT,newBitfunCoderSessionDesc:iT,newCoworkSession:aT,newCoworkSessionDesc:rT,workspaceSectionTitle:lT,workspaceSectionHint:cT,noRecentWorkspaces:dT,messages:uT,features:pT,comingSoon:mT,recentWorkspaces:gT,openOtherProject:hT,removeFromRecent:fT,newProject:yT,noOtherWorkspaces:wT,emptyHint:vT,firstTime:bT},ST="Work Center",xT={eyebrow:"SPARO OS",quiet:"Nothing in flight"},CT={placeholder:"Search work..."},AT={label:"Work scopes",actionSection:"Action",todaySection:"Queue",continuitySection:"Ongoing",librarySection:"Library",typeSection:"Work types",systemSection:"System",workspaceSection:"Workspaces",attention:"Needs you",openWork:"Ready to Continue",openWorkCount:"{{count}} ready",allWork:"Unarchived Work",unarchivedWork:"Unarchived Work",unarchivedWorkCount:"{{count}} unarchived",completedWork:"Completed",completedWorkCount:"{{count}} completed",archivedWork:"Archived",archivedWorkCount:"{{count}} archived",activeWorkspaces:"Active Workspaces",workspaces:"Workspaces",system:"Global Work",running:"{{count}} running",runningWorks:"Running Work",needsAttention:"{{count}} need attention",allWorkHint:"View every unarchived work",openWorkspaces:"{{count}} open",historyWorkspaces:"{{count}} history",total:"{{count}} total",workspace:"Workspace",backgroundProcesses:"System matters"},_T={immediate:"Immediate",long_term:"Long-term",topic:"Topic",recurring:"Recurring",system:"System matters"},TT={foreground:"Foreground",background:"Background run"},PT={emptyValue:"--",columns:{name:"Name",type:"Type",status:"Status",scope:"Scope",kind:"Kind",phase:"Phase",runtime:"Elapsed",updated:"Updated",actions:"Actions"}},FT={newWork:"New work",clearFilters:"Clear filters",cancelWork:"Cancel run",removeWork:"Archive work"},RT={label:"Work board"},NT={label:"Bulk work actions",selectAllVisible:"Select all visible work",selectWork:"Select {{title}}",selectHint:"Select work from {{count}} shown",selectedCount:"{{count}} of {{total}} selected",archive:"Archive {{count}}",reopen:"Reopen {{count}}",cancel:"Cancel {{count}}",delete:"Delete",clearSelection:"Clear selection",deleteDialog:{title:"Delete {{count}} work item",description:"This removes the selected work from Work Center. Artifacts and memories are retained.",deleteLinkedSessionsLabel:"Also delete linked sessions",deleteLinkedSessionsDescription:"Uses Work lifecycle cleanup hooks to delete linked agent sessions with the work.",cancel:"Cancel",confirm:"Delete work",deleting:"Deleting..."}},DT={title:"Background processes",subtitle:"{{running}} running · {{attention}} attention · {{total}} total",searchPlaceholder:"Search processes...",emptyValue:"--",duration:{seconds:"{{count}}s",minutes:"{{count}}m",hours:"{{count}}h"},filters:{railLabel:"Background process filters",status:{all:"All processes",attention:"Needs attention",running:"Running",queued:"Queued",scheduled:"Scheduled",idle:"Idle"},category:{all:"All categories"}},rail:{eyebrow:"Process classes",summary:"{{running}} running · {{attention}} attention"},columns:{process:"Process",status:"Status",scope:"Scope",trigger:"Trigger",phase:"Phase",lastRun:"Last run",runtime:"Runtime",nextRun:"Next run",result:"Last result",actions:"Actions"},kinds:{auto_memory_extraction:"Auto memory extraction",memory_consolidation:"Memory consolidation",host_scan:"Host scan",workspace_overview_refresh:"Workspace overview refresh",global_daily_report:"Global daily report",daily_letter:"Daily letter",global_milestone:"Global milestone"},categories:{memory:"Memory",workspace:"Workspace",report:"Reports",system:"System"},status:{idle:"Idle",disabled:"Disabled",scheduled:"Scheduled",queued:"Queued",running:"Running",succeeded:"Succeeded",failed:"Failed",cancelled:"Cancelled",skipped:"Skipped",cooling_down:"Cooling down"},trigger:{auto:"Auto",manual:"Manual",startup_catch_up:"Startup",post_turn:"Post-turn",retry:"Retry",scheduled:"Scheduled",system:"System"},phase:{idle:"Idle",waiting_schedule:"Waiting schedule",waiting_retry:"Waiting retry",queued:"Queued",running_hidden_agent:"Hidden agent",scanning_host:"Scanning host",refreshing_workspace_overview:"Refreshing overview",consolidating_memory:"Consolidating memory",extracting_memory:"Extracting memory",generating_report:"Generating report",writing_daily_letter:"Writing daily letter"},scopeLabel:{system:"System"},actions:{runNow:"Run now",retry:"Retry",openOutput:"Open output",openSettings:"Settings",refresh:"Refresh",clearSearch:"Clear search"},empty:{noProcesses:"No background processes",noMatches:"No matching processes"},messages:{runStarted:"Process started",runSkipped:"{{reason}}",runSkippedDefault:"Process was not started",runFailed:"Failed to run process",loadFailed:"Failed to load background processes",noOutput:"No output path recorded",openOutputFailed:"Failed to open output"},footer:{generatedAt:"Updated {{time}}",notLoaded:"Not loaded"}},IT={noMatches:"No matching work",clearSearch:"Clear search",showAllWork:"Show unarchived Work",noRunning:"Nothing is running right now"},MT={label:"Work detail",close:"Close detail",openPrimary:"Open primary surface",openSurface:"Open surface",openArtifact:"Open artifact",copyReference:"Copy reference",copied:"Copied",openDetailsFor:"Show details for {{title}}",loading:"Loading Work details",navigation:{position:"Work {{current}} of {{total}}",positionCompact:"{{current}} / {{total}}",previous:"Previous Work",next:"Next Work"},tabs:{overview:"Overview",outputs:"Outputs & links",runtime:"Run history"},currentState:{title:"Right now",fallback:"Open this Work to review the latest context.",systemManaged:"Sparo OS maintains this automatically. No action is needed.",memorySourcesTracked:"Sparo OS organized memory from {{count}} sources.",systemHealthy:"The latest run completed. Sparo OS will continue maintaining it automatically.",systemRunning:"This is running in the background and will update when complete.",systemScheduled:"The next run is scheduled. No action is needed.",systemAttention:"The latest run did not complete. Review Run history for details.",systemDisabled:"This system task is currently disabled."},systemStatus:{healthy:"Running normally",running:"Running",scheduled:"Scheduled",attention:"Needs attention",disabled:"Disabled"},systemOverview:{title:"Automatic run",automatic:"Automatic maintenance",trigger:"Run method",lastFinished:"Last completed"},systemActivity:{running:"Running now",lastRun:"Latest run: {{status}}"},primaryAction:{handle:"Take action",inspectProgress:"Enter workspace",viewResult:"View result",enter:"Enter workspace",resume:"Resume Work",reopen:"Reopen Work",openAndHandle:"Open and resolve"},appendInstruction:{label:"Add instruction",placeholder:"Tell this Work what to do next...",send:"Send instruction",cancel:"Cancel"},more:{label:"More actions",collapse:"Hide actions",changeType:"Change type",reopen:"Reopen Work"},context:{title:"Work context"},outputs:{artifacts:"Outputs",destinations:"Places to continue",primary:"Primary"},runtimeEvents:"Run events",technical:{show:"Show technical details",hide:"Hide technical details",workId:"Work ID",runtimeInstanceId:"Runtime instance ID"},empty:{outputs:"No outputs or links yet",activity:"No recent activity",runtime:"No run history yet"},command:{open:"Open",advance:"Continue",cancel:"Cancel",archive:"Archive"},brief:"Brief",objective:"Objective",emptyObjective:"No objective recorded",editObjective:"Edit objective",objectivePlaceholder:"Describe what this work should accomplish...",saveObjective:"Save objective",cancelEdit:"Cancel",summary:"Summary",noSummary:"No summary yet",advance:"Continue",advancePlaceholder:"Tell this work what to do next...",sendAdvance:"Send instruction",workspace:"Workspace",globalWorkspace:"Global",created:"Created",updated:"Updated",updatedAt:"Updated {{time}}",links:"Links",activity:"Recent activity",surfaces:"Surfaces",execution:"Execution",executionGraph:"Execution graph",graphLoading:"Loading execution graph",graphArtifacts:"{{count}} graph artifacts",noRuntimeRuns:"No runtime runs yet",noExecution:"No execution binding yet",lifecycle:"Lifecycle",noLifecycle:"No lifecycle events yet",artifacts:"{{count}} artifacts",memories:"{{count}} memories",sessions:"{{count}} sessions",runtimeInstanceCount:"{{count}} runtime instances",runtimeInstances:"Runtime instances",runtimeRuns:"{{count}} runtime runs",runtimeIssues:"{{count}} diagnostics",runtimeLogs:"{{count}} runtime logs",runtimeRunMeta:"{{component}} · {{action}}",runtimeLogMeta:"{{category}} · {{component}}",runtimeVersion:"v{{version}} · {{lock}}",runtimeRelease:"Release {{release}} · config {{config}}",runtimeSurface:"{{surface}} · {{component}}",runtimeLogLevel:{debug:"Debug",info:"Info",warn:"Warning",error:"Error"},surface:{workSession:"Work session",agentSession:"Agent session",application:"Application surface",agentHome:"Agentic OS home"},assignment:{label:"Owner",unassigned:"Unassigned",unknown:"Unknown",agent:"Agent: {{label}}",assistant:"Assistant: {{label}}",application:"App: {{label}}",human:"Human: {{label}}",external:"External: {{label}}"},executionStatus:{queued:"Queued",running:"Running",waiting_user:"Needs you",completed:"Completed",failed:"Failed",cancelled:"Cancelled",interrupted:"Interrupted"},executionSource:{agentSessionRun:"Agent session run",delegatedWorkRun:"Delegated work",applicationAction:"Application action",runtimeInstanceRun:"Runtime instance run",runtimeSubagentRun:"Runtime subagent",external:"External execution"},runtimeStatus:{idle:"Idle",running:"Running",waiting_user:"Needs you",completed:"Completed",degraded:"Degraded"},runtimeRunStatus:{pending:"Pending",running:"Running",waiting_user:"Needs you",completed:"Completed",failed:"Failed",cancelled:"Cancelled"},runtimeIssueSeverity:{fatal:"Runtime error",warning:"Runtime warning",noise:"Runtime note"},lifecycleEvent:{created:"Work created",advanced:"Instruction sent",paused:"Work paused",resumed:"Work resumed",archived:"Work archived",reopened:"Work reopened",statusUpdated:"Status updated",applicationSurfaceWorkflowStarted:"Application surface workflow started",currentExecutionCancelled:"Current run cancelled",agentSessionContinued:"Agent session continued",agentSessionTurnCompleted:"Agent turn completed",agentSessionTurnCancelled:"Agent turn cancelled",agentSessionFailed:"Agent session failed",agentSessionFailedWithReason:"Agent session failed: {{reason}}",agentSessionWaitingUser:"Waiting for you",agentSessionResumed:"Agent session resumed"},classify:{title:"Classification",asTopic:"Mark as Topic",asTracking:"Mark as tracking",asLongRunning:"Mark as long-running",asRecurring:"Mark as recurring",asImmediate:"Mark as immediate",updated:"Classification updated"},attachments:{title:"Attachments",topic:"Topic",systemProcess:"System process",none:"No topic attachment"},systemRuntime:{title:"Run & schedule",nextRun:"Next run",runNow:"Run now",unavailable:"Process runtime unavailable"}},jT={all:"All workspaces",searchPlaceholder:"Find workspace"},ET={all:"All apps",searchPlaceholder:"Find app",kind:{product_app:"{{count}} Product App work"}},LT={searchPlaceholder:"Search workspaces...",empty:"No workspaces",noMatches:"No matching workspaces",activeSection:"Active workspaces",historySection:"History",noActive:"No active workspaces",noHistory:"No history yet",openWorkspace:"Open workspace",openingWorkspace:"Opening...",openDialogTitle:"Open workspace",switchWorkspace:"Make current",openHistoryWorkspace:"Open",closeWorkspace:"Close workspace",removeHistoryWorkspace:"Remove from history",workCount:"{{count}} work",runningCount:"{{count}} running",attentionCount:"{{count}} need you",quiet:"Quiet",drillIn:"Show work",openWorkFor:"Show work in {{title}}",status:{attention:"Needs you",running:"Running",active:"Active",quiet:"Quiet"}},$T={label:"Group work",priority:"Focus",kind:"Kind",status:"Status",time:"Time"},OT={immediate:"Immediate",long_term:"Long-term",recurring:"Recurring"},BT={needs_attention:"Needs you",running:"Running now",recurring:"Recurring",long_term:"Long-term",immediate:"Immediate",done:"Done"},WT={draft:"Draft",active:"Open",running:"Running",waiting_user:"Needs you",blocked:"Blocked",paused:"Paused",completed:"Completed",failed:"Failed",cancelled:"Cancelled",interrupted:"Interrupted",archived:"Archived"},zT={"one-shot":"Normal work","multi-step":"Multi-step work","long-running-session":"Long-running work",recurring:"Recurring work",tracking:"Tracking work",topic:"Topic work","app-workflow":"Intelligent app work","delegated-work":"Delegated work",system:"System work"},UT={today:"Today",week:"This week",older:"Earlier"},HT={unknown:"Unknown",versionIncompatible:"This work was created by {{appId}} {{createdWithVersion}} with data schema {{workDataSchemaVersion}}. The installed version {{installedVersion}} (schema {{installedDataSchemaVersion}}) cannot accept its data or runtime contract. The historical app version has been removed.",appUnavailable:"This work cannot run because {{appId}} is not installed. Its historical app version is not retained.",appDisabled:"This work cannot run because {{appId}} is disabled.",appSelectionChanged:"This work belongs to {{appId}}, but this app slot now selects {{installedAppId}}. Historical app versions are not used."},qT={openFailed:"Failed to open work",openSurfaceFailed:"Failed to open surface",openArtifactFailed:"Failed to open artifact",cancelFailed:"Failed to cancel work",pauseFailed:"Failed to pause work",resumeFailed:"Failed to resume work",reopenFailed:"Failed to reopen work",removeFailed:"Failed to remove work",objectiveRequired:"Objective cannot be empty",updateObjectiveFailed:"Failed to update objective",advanceRequired:"Write an instruction first",advanceFailed:"Failed to send instruction",openWorkspaceFailed:"Failed to open workspace",switchWorkspaceFailed:"Failed to switch workspace",closeWorkspaceFailed:"Failed to close workspace",removeWorkspaceFailed:"Failed to remove workspace history",bulkActionFailed:"Failed to update {{count}} selected work",bulkDeleteFailed:"Failed to delete {{count}} selected work",reclassifyFailed:"Failed to update classification"},VT={objectiveSaved:"Objective updated",advanceSent:"Instruction sent",paused:"Work paused",resumed:"Work resumed",reopened:"Work reopened",archived:"Work archived",bulkArchived:"Archived {{count}} work item",bulkReopened:"Reopened {{count}} work item",bulkCancelled:"Cancelled {{count}} work run",bulkDeleted:"Deleted {{count}} work item",bulkDeletedWithSessions:"Deleted {{count}} work item and {{sessions}} linked session",bulkDeletedWithCleanupWarnings:"Deleted {{count}} work item, but {{failed}} linked session cleanup item failed"},GT={title:ST,header:xT,search:CT,scope:AT,rail:_T,runtime:TT,runningTable:PT,actions:FT,board:RT,bulk:NT,background:DT,emptyState:IT,detail:MT,workspaceFilter:jT,appFilter:ET,workspaceOverview:LT,grouping:$T,category:OT,priority:BT,status:WT,kind:zT,time:UT,compatibility:HT,errors:qT,messages:VT},KT="Settings",QT={title:"General",language:{title:"Language",description:"Select interface language",auto:"Auto Detect"},theme:{title:"Theme",description:"Select interface theme",light:"Light",dark:"Dark",system:"Follow System"},startup:{title:"Startup",restoreSession:"Restore Previous Session",showWelcome:"Show Welcome Page"}},JT={title:"Editor",font:{title:"Font",family:"Font Family",size:"Font Size",lineHeight:"Line Height"},display:{title:"Display",wordWrap:"Word Wrap",minimap:"Show Minimap",lineNumbers:"Show Line Numbers",breadcrumbs:"Show Breadcrumbs",whitespace:"Show Whitespace"},behavior:{title:"Behavior",autoSave:"Auto Save",autoSaveDelay:"Auto Save Delay",formatOnSave:"Format on Save",formatOnPaste:"Format on Paste"},indentation:{title:"Indentation",type:"Indentation Type",spaces:"Spaces",tabs:"Tabs",size:"Indentation Size"}},YT={title:"AI Settings",model:{title:"Model",select:"Select Model",provider:"Provider",apiKey:"API Key",baseUrl:"Base URL",add:"Add Model",edit:"Edit Model",delete:"Delete Model"},behavior:{title:"Behavior",streaming:"Streaming",temperature:"Temperature",maxTokens:"Max Tokens",contextLength:"Context Length"},agent:{title:"Agent",defaultAgent:"Default Agent",customAgents:"Custom Agents"}},ZT={title:"Terminal",shell:{title:"Shell",default:"Default Shell",profiles:"Shell Profiles"},display:{title:"Display",fontSize:"Font Size",fontFamily:"Font Family",cursorStyle:"Cursor Style",scrollback:"Scrollback Lines"}},XT={title:"Workspace",files:{title:"Files",exclude:"Exclude Files",watcherExclude:"Exclude from Watcher",associations:"File Associations"},search:{title:"Search",exclude:"Exclude from Search",useIgnoreFiles:"Use Ignore Files"}},eP={title:"Advanced",experimental:{title:"Experimental Features",description:"These features may be unstable"},debug:{title:"Debug",logging:"Enable Logging",developerTools:"Developer Tools"},data:{title:"Data",export:"Export Settings",import:"Import Settings",reset:"Reset All Settings",resetConfirm:"Are you sure you want to reset all settings? This action cannot be undone."}},tP={title:"About",version:"Version",checkUpdate:"Check for Updates",changelog:"Changelog",license:"License",openSource:"Open Source Licenses",feedback:"Feedback",reportIssue:"Report Issue",documentation:"Documentation"},nP={title:"Model Configuration",subtitle:"Configure AI models and API keys",addModel:"Add Model",editModel:"Edit Model Configuration",newModel:"New Model Configuration",editSubtitle:"Basic Model Parameters",deleteModel:"Delete Model",confirmDelete:"Are you sure you want to delete this configuration?",modelName:"Model Name",modelId:"Model ID",provider:"Request Format",providerPlaceholder:"Select request format",apiKey:"API Key",apiKeyPlaceholder:"Enter your API Key",baseUrl:"API URL",baseUrlPlaceholder:"Enter API URL (optional)",configName:"Configuration Name",configNamePlaceholder:"Give this configuration a name",maxTokens:"Max Output Tokens",maxTokensHint:"Maximum tokens for model output per request (affects response length)",contextWindow:"Context Window Size",contextWindowHint:"Maximum context window size supported by the model (for calculating token usage percentage)",temperature:"Temperature",streaming:"Streaming",enabled:"Enabled",test:"Test Connection",testing:"Testing...",testSuccess:"Connection successful",testFailed:"Connection failed",noModels:"No model configurations",noModelsHint:"Click the button above to add your first AI model",createFirst:"Create First Configuration",noMatchingModels:"No matching models found",searchPlaceholder:"Search model name, provider...",newConfig:"New Configuration",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",description:"Description",descriptionPlaceholder:"Configuration description (optional)",tabs:{api:"API Configuration",proxy:"Proxy Configuration"},categories:{all:"All",text:"Text",multimodal:"Image",other:"Utility"},category:{label:"Model Category",placeholder:"Select model category",general_chat:"Text Generation",multimodal:"Image Understanding",image_generation:"Image Generation",speech_recognition:"Speech Recognition"},categoryHints:{general_chat:"Text Generation: Generate text responses, code, etc. for most conversation scenarios",multimodal:"Image Understanding: Understand image content and have mixed text-image conversations",image_generation:"Image Generation: Generate images from text descriptions",speech_recognition:"Speech Recognition: Convert speech to text (e.g., GLM-ASR)"},modelNameHint:"GLM-ASR uses glm-asr, other speech models use their corresponding model names",thinking:{enable:"Enable Thinking",enableHint:"Requires model to support thinking mode"},details:{basicInfo:"Basic Information",modelName:"Model Name",provider:"Request Format",apiUrl:"API URL",contextWindow:"Context Window",maxOutput:"Max Output",description:"Description",tokens:"tokens"},proxy:{enable:"Enable Proxy",enableHint:"When enabled, all AI requests will be sent through proxy (requires IDE restart)",url:"Proxy URL",urlPlaceholder:"http://127.0.0.1:7890 or socks5://127.0.0.1:1080",urlHint:"Supports HTTP/HTTPS/SOCKS5 proxy, format: protocol://address:port",username:"Username (optional)",usernamePlaceholder:"Proxy authentication username",password:"Password (optional)",passwordPlaceholder:"Proxy authentication password",save:"Save Proxy Configuration",saveSuccess:"Proxy configuration saved, restart IDE to take effect"},messages:{fillRequired:"Please fill in required fields",fillModelName:"Please fill in model name",saveFailed:"Save failed",deleteFailed:"Failed to delete configuration",loadFailed:"Failed to load AI configuration",errorDetails:"Error details"},capabilities:{text_chat:"Chat",image_understanding:"Vision",image_generation:"Image",search:"Search",function_calling:"Tools",speech_recognition:"Speech"}},oP={title:"Super Agent",subtitle:"Configure main agent model assignments",textChat:"Text Chat",textChatDesc:"Handle daily conversations and Q&A",codeGeneration:"Code Generation",codeGenerationDesc:"Generate and complete code",codeReview:"Code Review",codeReviewDesc:"Review and optimize code",planning:"Task Planning",planningDesc:"Decompose and plan complex tasks",selectModel:"Select Model",notConfigured:"Not Configured",configured:"Configured",modelUpdated:"{{capability}} updated to {{modelName}}",capabilities:{text_chat:"Text Chat Model",image_understanding:"Image Understanding Model",image_generation:"Image Generation Model",search:"Search API Model",speech_recognition:"Speech Recognition Model"},capabilityDescs:{text_chat:"Handles all text conversations, code generation, tool calls, etc.",image_understanding:"Analyzes and understands image content, supports mixed text-image conversations",image_generation:"Generates images from text descriptions (e.g., DALL-E, Stable Diffusion)",search:"Real-time web search for latest data support",speech_recognition:"Converts speech to text, supports voice input (e.g., GLM-ASR)"}},sP={title:"AI Features",subtitle:"Configure AI enhancement features",codeCompletion:"Code Completion",codeCompletionDesc:"Intelligent code completion suggestions",inlineChat:"Inline Chat",inlineChatDesc:"Chat with AI directly in the editor",semanticSearch:"Semantic Search",semanticSearchDesc:"Semantic-based code search",autoFix:"Auto Fix",autoFixDesc:"Automatically fix code errors and warnings"},iP={title:"Modes",subtitle:"Configure different working modes",agentMode:"Agent Mode",agentModeDesc:"AI can execute code and use tools",chatMode:"Chat Mode",chatModeDesc:"Pure conversation, no actions",askMode:"Ask Mode",askModeDesc:"Read-only mode, only answer questions"},aP={title:"Tool Settings",subtitle:"Configure Agentic tool permissions and behavior",fileOperations:"File Operations",fileOperationsDesc:"Allow AI to read and write files",terminalAccess:"Terminal Access",terminalAccessDesc:"Allow AI to execute terminal commands",webSearch:"Web Search",webSearchDesc:"Allow AI to search the web",browserControl:"Browser Control",browserControlDesc:"Allow AI to control the browser"},rP={title:"Skills",subtitle:"Manage AI skill extensions",addSkill:"Add Skill",noSkills:"No skills",noSkillsHint:"Skills can extend AI capabilities"},lP={title:"Agents",subtitle:"Configure agents",addAgent:"Add Agent",noAgents:"No sub-agents",noAgentsHint:"Sub-agents can handle specific types of tasks"},cP={title:"MCP",subtitle:"Manage MCP server connections",addServer:"Add Server",serverName:"Server Name",serverUrl:"Server URL",connected:"Connected",disconnected:"Disconnected",noServers:"No MCP servers",noServersHint:"Add MCP servers to extend functionality"},dP={title:"Editor",subtitle:"Configure code editor",fontSize:"Font Size",fontFamily:"Font Family",lineHeight:"Line Height",tabSize:"Tab Size",wordWrap:"Word Wrap",minimap:"Show Minimap",lineNumbers:"Show Line Numbers"},uP={title:"LSP",subtitle:"Configure language servers",installedServers:"Installed Language Servers",noServers:"No language servers",noServersHint:"Language servers provide code intelligence features"},pP={title:"Debug",subtitle:"Configure debug options",enableLogging:"Enable Logging",logLevel:"Log Level",developerTools:"Developer Tools"},mP={title:"Terminal",subtitle:"Configure integrated terminal",shell:"Default Shell",fontSize:"Font Size",fontFamily:"Font Family",cursorStyle:"Cursor Style",scrollback:"Scrollback Lines"},gP={basic:{title:"Basic Settings"},apiNetwork:{title:"API & Network",subtitle:"Configure and manage AI models, including API keys and default model settings"},learning:{title:"Learning & Knowledge",subtitle:"Manage AI memory, knowledge bases, and skills",import:"Import",addMemory:"Add Memory"},agents:{title:"Agent Configuration",subtitle:"Configure and manage agents, including function agents and super agents",create:"Create Agent"},theme:{title:"Theme Settings",subtitle:"Customize the app appearance and theme colors",import:"Import Theme",export:"Export Current Theme"}},hP={title:KT,general:QT,editor:JT,ai:YT,terminal:ZT,workspace:XT,advanced:eP,about:tP,aiModel:nP,superAgent:oP,aiFeatures:sP,modes:iP,agenticTools:aP,skills:rP,agents:lP,mcp:cP,editorConfig:dP,lspConfig:uP,debugConfig:pP,terminalConfig:mP,configPageHeaderExample:gP},fP="Tool Settings",yP="Tool execution configuration and available tool list",wP={config:{title:"Execution Behavior",description:"Control confirmation and timeout policies for tool calls."},list:{title:"Tool List",description:"{{count}} tools available."}},vP={autoExecute:"Auto Execute",autoExecuteDesc:"Skip user confirmation before tool execution.",confirmTimeout:"Confirm Timeout",confirmTimeoutDesc:"Maximum time (seconds) to wait for user confirmation of tool calls.",executionTimeout:"Execution Timeout",executionTimeoutDesc:"Maximum time (seconds) for tool execution.",seconds:"sec"},bP={all:"All",readonly:"Read-only",writable:"Writable"},kP={placeholder:"Search tools..."},SP={readonly:"Read-only",writable:"Writable",concurrent:"Concurrency Safe",permission:"Requires Permission"},xP={title:"Tool Properties",readonlyMode:"Read-only Mode",concurrencySafe:"Concurrency Safe",needsPermission:"Requires Permission",yes:"Yes",no:"No"},CP={title:"Input Parameter Schema"},AP={loading:"Loading...",loadFailed:"Load failed",retry:"Retry",noTools:"No available tools",noMatchingTools:"No matching tools found",autoExecuteEnabled:"Auto execute enabled",autoExecuteDisabled:"Auto execute disabled",saveFailed:"Save failed"},_P={title:fP,subtitle:yP,section:wP,config:vP,filters:bP,search:kP,badges:SP,properties:xP,schema:CP,messages:AP},TP="Agents",PP="Manage user-level and project-level agents",FP={searchPlaceholder:"Search Agents...",refreshTooltip:"Refresh Agent list",refreshSuccess:"Agent list refreshed",addTooltip:"Add Agent"},RP={all:"All",builtin:"Built-in",user:"User",project:"Project"},NP={builtin:{description:"Built-in AI sub-agents and modes."},user:{description:"Your custom agents."},project:{description:"Project-level agents for the selected workspace path."},customAgents:{title:"Custom Agents",description:"User-level and project-level agents. Switch between them using the tabs below."}},DP={titleEdit:"Edit Agent",titleCreate:"Add Agent",fields:{level:"Level",levelUser:"User-level (Global)",levelProject:"Project-level (Workspace Path)",levelProjectDisabled:" - Need to open workspace first",selectedProjectPath:"Selected project path: {{path}}",name:"Agent Name *",namePlaceholder:"e.g., code-writer",description:"Description *",descriptionPlaceholder:"Brief description of Agent function",tools:"Tools",toolsOptional:"optional",toolsPlaceholder:"e.g., FileReadTool, FileWriteTool, BashTool",color:"Color",colors:{blue:"Blue",red:"Red",green:"Green",purple:"Purple",orange:"Orange",yellow:"Yellow"},systemPrompt:"System Prompt (Markdown) *",systemPromptPlaceholder:"Enter Agent's system prompt...",readonly:"Read-only",readonlyDescription:"Read-only agents only use read tools and can run in parallel with other tasks.",enabled:"Enabled"},actions:{cancel:"Cancel",save:"Save",create:"Create"}},IP={loading:"Loading...",loadingBuiltin:"Loading built-in Sub Agents...",errorPrefix:"Failed to load: ",empty:{noMatch:"No matching Agents found",noMatchBuiltin:"No matching built-in Sub Agents found"},item:{builtin:"Built-in",subAgent:"Sub-Agent",mode:"Mode",toolsCount:"{{count}} tools",editTooltip:"Edit",deleteTooltip:"Delete",toolsLabel:"Available tools:",modelLabel:"Model Config",systemPromptLabel:"System prompt:",updateTimePrefix:"Updated: "}},MP={noWorkspaceForProject:"Please open a workspace first to create project-level Agent",nameRequired:"Please enter Agent name",nameFormatError:"Name must start with a letter and contain only letters, numbers, - and _",descriptionRequired:"Please enter Agent description",toolsRequired:"Please add at least one tool",contentRequired:"Please enter system prompt",updateSuccess:'Agent "{{name}}" updated successfully',createSuccess:'Agent "{{name}}" created successfully',operationFailed:"Failed to {{operation}} Agent: {{error}}",deleteSuccess:'Agent "{{name}}" deleted',deleteFailed:"Failed to delete: {{error}}",confirmDeleteSubagent:'Delete Agent "{{name}}"? The agent file will be removed and it will disappear from the list.',toggleSuccess:'Agent "{{name}}" {{status}}',toggleFailed:"Failed to toggle: {{error}}",subagentToggleSuccess:'Sub Agent "{{name}}" {{status}}',subagentToggleFailed:"Failed to toggle: {{error}}",enabled:"enabled",disabled:"disabled",update:"update",create:"create",modelUpdated:'"{{name}}" will use {{model}}',modelUpdateFailed:"Failed to set model",saveFailed:"Save failed"},jP={primary:"Primary Model",fast:"Fast Model"},EP={tools:{label:"Available tools",selectAll:"Select all",clear:"Clear",reset:"Reset to default",expand:"Expand",collapse:"Collapse",enabled:"Enabled"},messages:{confirmReset:"Reset this mode's tool configuration?",resetSuccess:"Tool configuration reset",resetFailed:"Reset failed",confirmSelectAll:"Enable all tools?",confirmClearAll:"Clear all tools?",allToolsEnabled:"All tools enabled",allToolsDisabled:"All tools disabled",toolEnabled:'"{{name}}" enabled tool: {{tool}}',toolDisabled:'"{{name}}" disabled tool: {{tool}}',toolToggleFailed:"Failed to toggle tool",modelUpdated:'"{{name}}" will use {{model}}',modelUpdateFailed:"Failed to set model"}},LP={title:TP,subtitle:PP,toolbar:FP,filters:RP,section:NP,form:DP,list:IP,messages:MP,model:jP,mode:EP},$P="AI Features",OP={all:"All",switches:"Feature Switches",models:"Model Config"},BP={interaction:"Interaction",development:"Development",analysis:"Analysis"},WP={sessionTitle:{title:"Auto Session Title",warning:"Session title will use first 20 characters of user message"},compression:{title:"Context Compression"}},zP={label:"Model",primary:"Primary Model",fast:"Fast Model",notConfigured:"Not configured",fastUsesPrimary:"Uses flagship"},UP={enable:"Enable",reset:"Reset",save:"Save",saving:"Saving..."},HP={empty:'No available models. Please add models in "Models" first.',placeholder:"Use main Agent model",updateSuccess:"{{agentName}} will use {{modelName}}"},qP={"git-func-agent":{displayName:"Git Functions",description:"Commit messages, code review"},"session-title-func-agent":{displayName:"Session titles",description:"Auto-generated conversation titles"}},VP={text:"Loading configuration..."},GP={saveSuccess:"Settings saved",saveFailed:"Save failed",confirmReset:"Are you sure you want to reset feature switches to defaults?",hasChanges:"You have unsaved changes",updateFailed:"Update failed"},KP={title:$P,tabs:OP,sections:BP,features:WP,model:zP,common:UP,models:HP,builtinAgents:qP,loading:VP,messages:GP},QP="Settings mode",JP="Manual",YP="AI",ZP={title:"AI Settings",loading:"Preparing the settings assistant…",loadError:"The AI settings conversation could not be opened.",retry:"Retry",newConversation:"New conversation",resetting:"Starting…",resetBusy:"Stop the current task before starting a new conversation",resetError:"A new conversation could not be started. The current conversation is unchanged.",resetAttachError:"The new conversation started, but its history could not be loaded. Reopen Settings to try again.",sendErrors:{title:"Settings request could not be completed",secureInputRequired:"This change needs a sensitive value. Enter it directly in Manual settings.",requestInvalid:"This request could not be validated. Rephrase it and try again.",revisionConflict:"These settings changed elsewhere. Review the latest values and try again.",manualDraftConflict:"Manual settings contain unsaved changes. Save or discard them before trying again.",recoveryReadOnly:"Settings are currently in read-only recovery mode. Rebuild the default configuration first.",fallback:"This settings request could not be processed. Please try again."},resetDialog:{title:"Start a new conversation?",message:"This clears this AI settings conversation and unconfirmed plans, but does not undo settings already applied.",confirm:"Start new conversation",cancel:"Keep current conversation"}},XP={title:"Confirm this settings change",description:"This change affects protected settings. Review the authoritative plan before continuing.",confirm:"Confirm and apply",reject:"Keep current settings"},eF={configured:"Configured",unconfigured:"Not configured",placeholder:"Enter a replacement value",update:"Update"},tF={notSet:"Not set"},nF={catalog:"Settings could not be loaded.",submit:"The request could not be started.",conflict:"These settings changed elsewhere. The latest values have been reloaded.",manualConflict:"This setting changed elsewhere. Keep your draft or press Escape to use the latest value.",invalidJson:"Enter valid JSON before saving this setting."},oF={modeLabel:QP,manualMode:JP,aiMode:YP,session:ZP,confirmation:XP,secret:eF,values:tF,errors:nF},sF="Model Configuration",iF="Edit Provider Configuration",aF="New Provider Configuration",rF="Edit Model Configuration",lF="New Model Configuration",cF="Basic Provider Parameters",dF="Basic Model Parameters",uF="Are you sure you want to delete this configuration?",pF={sectionTitle:"Local CLI accounts",rescan:"Re-scan",empty:"No signed-in Codex / Gemini CLI accounts detected. Sign in from the terminal first, then re-scan.",import:"Use this account",refresh:"Refresh token",refreshSuccess:"Token refreshed",refreshFailed:"Refresh failed: {{error}}",expiresAt:"Token valid until {{time}}",tokenValid:"Token ready",accountLine:"Account: {{account}}",label:"Authentication",options:{apiKey:"API Key",codexCli:"Codex CLI account",geminiCli:"Gemini CLI account"},detected:"Will use the local {{label}} ({{account}})",notDetected:"No signed-in {{kind}} account detected; sign in from the terminal first.",unknownAccount:"current login"},mF={title:"Select Model Provider",or:"or",orSelectProvider:"or select a preset provider",customTitle:"Custom Configuration",customDescription:"Manually configure all parameters, suitable for private deployments or other unlisted providers",getApiKey:"Get API Key",fetchModels:"Fetch Models",fetchHint:"Fetch the model list from the current provider; if it fails, fall back to common preset models",fetchingModels:"Fetching model list...",fetchSuccessCount:"Fetched {{count}} models from the provider",fetchFailedFallback:"Failed to fetch model list, fell back to common preset models",fetchEmptyFallback:"Provider returned no models, fell back to common preset models",fillApiKeyBeforeFetch:"Enter the API key before fetching models",usingPresetModels:"Currently showing common preset models",noPresetModels:"No models available. Fetch the model list or enter a model name manually",backToSelection:"Back to provider selection",selectModel:"Select model",multiSelectHint:"Supports multi-select. After selection, configure context window, max output tokens, and reasoning per model.",searchOrInputModel:"Search or enter model name...",inputModelName:"Enter model name...",useCustomModel:"Press Enter to use",addCustomModel:"Add Custom Model",modelAlreadyInList:"This model is already in the list",reusedExistingModel:"Using the existing model entry for this provider (no duplicate was added)",noModelsSelected:"Select a model first",removeModel:"Remove model",expandModelSettings:"Expand settings for {{name}}",collapseModelSettings:"Collapse settings for {{name}}",urlHint:"Official API URL pre-filled, modify if using proxy or private deployment",formatHint:"Automatically selected based on provider, usually no need to change"},gF={opensparo:{name:"Sparo Model Platform",description:"Sparo OS model platform"},gemini:{name:"Google Gemini",description:"Google Gemini series models"},anthropic:{name:"Anthropic Claude",description:"Anthropic Claude series models"},minimax:{name:"MiniMax",description:"MiniMax series models"},moonshot:{name:"Moonshot AI",description:"Moonshot Kimi series models"},deepseek:{name:"DeepSeek",description:"DeepSeek series models"},zhipu:{name:"Zhipu AI",description:"Zhipu AI GLM series models",urlOptions:{default:"OpenAI Format - Default",anthropic:"Anthropic Format",codingPlan:"OpenAI Format - CodingPlan"}},qwen:{name:"Qwen",description:"Alibaba Cloud Bailian Model Platform"},volcengine:{name:"Volcano Engine",description:"ByteDance Volcano Engine Model Platform"},siliconflow:{name:"SiliconFlow",description:"SiliconFlow Model Platform",urlOptions:{default:"OpenAI Format - Default",anthropic:"Anthropic Format"}},nvidia:{name:"NVIDIA",description:"NVIDIA NIM Model Platform"},openrouter:{name:"OpenRouter",description:"OpenRouter Model Platform"}},hF={api:"API Configuration",proxy:"Proxy Configuration"},fF={all:"All",text:"Text",multimodal:"Image",other:"Utility"},yF={label:"Model Category",placeholder:"Select model category",general_chat:"Text Generation",multimodal:"Image Understanding",image_generation:"Image Generation",embedding:"Embedding",search_enhanced:"Search",code_specialized:"Code",speech_recognition:"Speech Recognition"},wF={general_chat:"Text",multimodal:"Vision",image_generation:"Image",embedding:"Embed",search_enhanced:"Search",code_specialized:"Code",speech_recognition:"Speech"},vF={general_chat:"Text Generation: Generate text responses, code, etc. for most conversation scenarios",multimodal:"Image Understanding: Understand image content and have mixed text-image conversations",image_generation:"Image Generation: Generate images from text descriptions",embedding:"Embedding: Convert text into vectors for retrieval and similarity search",search_enhanced:"Search: Provide search-enhanced answers or retrieval support",code_specialized:"Code: Optimized for code generation, edits, and review",speech_recognition:"Speech Recognition: Convert speech to text (e.g., GLM-ASR)"},bF={configName:"Provider Name",configNamePlaceholder:"Enter provider name",modelName:"Model Name",modelSelection:"Select Models",modelNameHint:"GLM-ASR uses glm-asr, other speech models use their corresponding model names",baseUrl:"API URL",resolvedUrlLabel:"Request URL: ",forceUrlHint:"Append # to force use the exact URL you entered",apiKey:"API Key",apiKeyPlaceholder:"Enter your API Key",provider:"Request Format",providerPlaceholder:"Select request format",contextWindow:"Context Window Size",contextWindowHint:"Maximum context window size supported by the model (for calculating token usage percentage)",maxTokens:"Max Output Tokens",maxTokensHint:"Maximum tokens for model output per request (affects response length)",description:"Description",descriptionPlaceholder:"Configuration description (optional)"},kF={enable:"Enable Thinking",mode:"Reasoning Mode",enableHint:"Requires model to support thinking mode",summaryOn:"thinking on",summaryOff:"thinking off",summaryDefault:"API default",summaryEnabled:"explicit enable",summaryDisabled:"explicit disable",summaryAdaptive:"adaptive",budgetTokens:"Claude Thinking Budget",optionDefault:"API Default",optionEnabled:"Enabled",optionDisabled:"Disabled",optionAdaptive:"Adaptive"},SF={label:"Reasoning Effort",hint:"Controls provider-specific reasoning depth for Responses API and supported Claude adaptive reasoning models",placeholder:"Use API default",options:{none:"None",minimal:"Minimal",low:"Low",medium:"Medium",high:"High",xhigh:"Extra high",max:"Maximum"}},xF={basicInfo:"Basic Information",modelName:"Model Name",provider:"Request Format",apiUrl:"API URL",contextWindow:"Context Window",maxOutput:"Max Output",description:"Description",capabilities:"Capabilities",tokens:"tokens"},CF={enable:"Enable Proxy",url:"Proxy URL",urlPlaceholder:"http://127.0.0.1:7890 or socks5://127.0.0.1:1080",urlHint:"Supports HTTP/HTTPS/SOCKS5 proxy, format: protocol://address:port",username:"Username (optional)",usernamePlaceholder:"Proxy authentication username",password:"Password (optional)",passwordPlaceholder:"Proxy authentication password",save:"Save Proxy Configuration",saveSuccess:"Proxy configuration saved, restart IDE to take effect"},AF={title:"Streaming Timeout",label:"Idle Timeout (seconds)",placeholder:"Leave empty for no timeout",invalid:"Enter a positive integer in seconds, or leave this field empty.",save:"Save Streaming Timeout",saveSuccess:"Streaming timeout saved"},_F={text_chat:"Chat",image_understanding:"Vision",image_generation:"Image",embedding:"Embedding",search:"Search",code_specialized:"Code",function_calling:"Tools",speech_recognition:"Speech"},TF={openaiCompatible:"OpenAI Compatible",responsesApi:"OpenAI Responses API",claudeApi:"Claude API",geminiApi:"Gemini GenerateContent API",geminiCodeAssist:"Gemini Code Assist"},PF={expandModels:"Expand model list for {{name}}",collapseModels:"Collapse model list for {{name}}",modelUnit:"model",deleteProvider:"Delete provider",deleteTitle:"Delete this provider?",deleteMessage:'Remove "{{name}}" and all {{count}} model configuration(s) saved under it.',deleteWarning:"This action cannot be undone.",deleteConfirm:"Delete provider"},FF={save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",test:"Test Connection",newConfig:"New Configuration",addModel:"Add Model",addProvider:"Add Provider",createFirst:"Create First Configuration"},RF={noModels:"No model configurations",noMatchingModels:"No matching models found"},NF={placeholder:"Search model name, provider..."},DF={fillRequired:"Please fill in required fields",fillModelName:"Please fill in model name",duplicateModelNameUnderProvider:"This provider already has a model with this name. Use a different name or edit the existing entry.",changedExternally:"This model configuration changed elsewhere. Reopen it before saving.",saveFailed:"Save failed",deleteFailed:"Failed to delete configuration",loadFailed:"Failed to load AI configuration",testSuccess:"Test successful",testFailed:"Test failed",errorDetails:"Error details",connectionTestMessages:{toolCallsNotDetected:"This test did not detect any tool calls, so tool calling could not be verified this time.",imageInputCheckFailed:"The connection succeeded, but the image input check failed."},autoSetPrimary:"Automatically set as primary model",defaultDescription:"{{name}} model configuration",cloneName:"{{name}} - Copy",templateName:"{{provider}} - {{modelName}}",templateDescription:"{{description}} - {{modelName}}"},IF={title:"Advanced Settings",inlineThinkInText:{label:"Parse Tags In Text",hint:"Split text streams containing ... into live reasoning content."},skipSslVerify:{label:"Skip SSL Certificate Verification",warning:"Skipping SSL verification is a security risk, use only in test or internal network environments!"},customHeaders:{label:"Custom Headers",hint:"Add or modify HTTP request headers",modeLabel:"Apply Mode",modeReplace:"Replace",modeMerge:"Merge",modeReplaceHint:"Custom headers will completely replace default headers (you need to add Content-Type, Authorization, etc.)",modeMergeHint:"Apply default headers first, then apply custom headers (can override existing values, add new values)",addHeader:"Add Field",keyPlaceholder:"key",valuePlaceholder:"value"},customRequestBody:{label:"Custom Request Body",hint:"Enter request body fields in JSON format to override default request parameters",modeMerge:"Merge",modeTrim:"Trim",modeMergeHint:"Merge custom fields into the default request body and allow overriding existing fields.",trimHintOpenAI:"Keep only model, messages, max_tokens, and runtime-critical stream / tool fields before applying the custom request body.",trimHintResponses:"Keep only model, input, instructions, max_output_tokens, and runtime-critical stream / tool fields before applying the custom request body.",trimHintAnthropic:"Keep only model, messages, system, max_tokens, and runtime-critical stream / tool fields before applying the custom request body.",trimHintGemini:"Keep only contents, systemInstruction, generationConfig.maxOutputTokens, and tools / toolConfig before applying the custom request body. Gemini model selection comes from the request URL.",placeholder:`Example: +{ + "temperature": 0.8, + "top_p": 0.9 +}`,invalidJson:"Invalid JSON format, please check syntax",validJson:"JSON format is valid",mergeHint:"Custom fields will override corresponding fields in the default request body"}},MF={title:sF,editProvider:iF,newProvider:aF,editModel:rF,newModel:lF,editProviderSubtitle:cF,editSubtitle:dF,confirmDelete:uF,cliAuth:pF,providerSelection:mF,providers:gF,tabs:hF,categories:fF,category:yF,categoryIcons:wF,categoryHints:vF,form:bF,thinking:kF,reasoningEffort:SF,details:xF,proxy:CF,streamIdleTimeout:AF,capabilities:_F,formats:TF,providerGroup:PF,actions:FF,empty:RF,search:NF,messages:DF,advancedSettings:IF},jF="AI Usage",EF={refresh:"Refresh",reset:"Reset"},LF="Loading usage history...",$F={loadFailed:"Failed to load AI usage history.",resetFailed:"Failed to reset AI usage history."},OF={title:"Reset AI usage history?",message:"This resets all saved AI usage records on this device. This cannot be undone.",confirm:"Reset records",cancel:"Cancel"},BF={filters:"View",overview:"Overview",trend:"Usage Trend",recent:"Recent Requests",by:{agent:"Usage By Agent",model:"Usage By Model",time:"Usage By Time"}},WF={timeRange:{label:"Time range",today:"Today",thisWeek:"This week",thisMonth:"This month",all:"All time"},groupBy:{label:"Group by",agent:"Agent",model:"Model",time:"Time"},includeSubagent:{label:"Include subagents",description:"Count delegated agent calls in the same usage view."}},zF={total:"Total tokens",input:"Input",output:"Output",requests:"Requests"},UF={unknown:"Unknown",requests:"{{count}} requests",inOut:"In {{input}} / Out {{output}}"},HF={time:"Time",agent:"Agent",model:"Model",tokens:"Tokens"},qF="No AI usage records in this view yet.",VF={title:jF,actions:EF,loading:LF,messages:$F,resetDialog:OF,sections:BF,filters:WF,metrics:zF,labels:UF,table:HF,empty:qF},GF="Appearance",KF="Choose language, theme, and fonts without changing workspace behavior.",QF={title:"Appearance",language:"Language",themes:"Themes",builtIn:"Built-in",custom:"Custom",export:"Export",delete:"Delete",confirmDelete:'Are you sure you want to delete theme "{{name}}"?',languageRowHint:"Choose one language pack as the active UI language.",themeRowHint:"Choose the interface color theme.",themeLoading:"Loading theme settings...",themeLoadFailed:"Failed to load theme settings.",systemTheme:"Match system",systemThemeDescription:"Use light or dark theme based on your OS appearance. Updates when the system switches.",presets:{dark:{name:"Dark",description:"Default Sparo OS dark theme with ink-red accent"},light:{name:"Light",description:"Light theme - calm surfaces, ink text, restrained accent"}},fontSize:{title:"Font Size",loading:"Loading font settings...",loadFailed:"Failed to load font settings.",uiSizeLabel:"UI Font",uiSizeHint:"Controls font size across navigation, panels, settings, and all other UI elements.",levels:{compact:"Compact",small:"Small",default:"Default",medium:"Medium",large:"Large",custom:"Custom"},customPxLabel:"Custom size (12-20 px)",resetButton:"Reset to Default",previewText:"Sparo OS is an AI-driven programming environment. The quick brown fox jumps over the lazy dog.",flowChatLabel:"Chat area",flowChatHint:"When off, chat follows the UI font size. When on, pick an independent size (12-20 px).",flowChatCustomToggle:"Custom chat font size",markdownEditorLabel:"Markdown editor",markdownEditorHint:"When off, Markdown editing and preview follow the UI font size. When on, pick a reading and editing size (12-20 px).",markdownEditorCustomToggle:"Custom Markdown editor font size"}},JF={title:GF,subtitle:KF,appearance:QF},YF="General",ZF="Set startup behavior, logging, terminal defaults, tray behavior, and notifications.",XF={sections:{title:"Login"},toggleLabel:"Launch at login",toggleDescription:"Automatically start Sparo OS after you log in. Exact behavior depends on your operating system.",messages:{loading:"Loading...",loadFailed:"Failed to read launch-at-login setting",saveFailed:"Failed to update launch-at-login setting"}},eR={sections:{logging:"Logging",loggingHint:"Log level and directory for this session",level:"Log Level",path:"Startup Log Path"},level:{description:"Controls log verbosity in real time. Changes apply immediately."},path:{description:"Directory where log files for this run are written."},levels:{trace:"Trace",debug:"Debug",info:"Info",warn:"Warn",error:"Error",off:"Off"},actions:{openFolder:"Open Folder",openFolderTooltip:"Open log folder in file explorer"},messages:{loading:"Loading...",loadFailed:"Failed to load logging configuration",saveFailed:"Failed to save logging level",levelUpdated:"Logging level updated",openedFolder:"Log folder opened",openFailed:"Failed to open log folder",pathUnavailable:"Log folder path is unavailable"}},tR={sections:{terminal:"Terminal",defaultTerminal:"Default Terminal"},controls:{autoDetect:"Auto Detect (Recommended)",description:"Default shell type for new terminals",placeholder:"Select default terminal",noShells:"No available terminals detected"},warnings:{cmd:"CMD does not support shell integration. AI commands will execute via PowerShell.",gitBash:"Git Bash with oh-my-zsh may cause shell integration to fail. If issues occur, switch to PowerShell."},messages:{loading:"Loading...",loadFailed:"Failed to load configuration",updated:"Default terminal updated",saveFailed:"Failed to save configuration"}},nR={sections:{title:"System Tray"},closeAction:{label:"Close button behavior",description:"Choose what happens when you click the window's close button.",options:{tray:"Minimize to tray",quit:"Quit application"}},messages:{saveSuccess:"Tray settings saved",saveFailed:"Failed to save tray settings"}},oR={title:"Notifications",dialogCompletion:{label:"Task completion notification",description:"Show a toast notification when an AI task completes while the window is not in focus"},startupTips:{label:"Show tips on startup",description:"Display a usage tip card each time the app starts to help you discover features"},messages:{saveSuccess:"Notification settings saved",saveFailed:"Failed to save notification settings"}},sR={title:YF,subtitle:ZF,launchAtLogin:XF,logging:eR,terminal:tR,tray:nR,notifications:oR},iR="Settings",aR="Select Configuration",rR="Search settings…",lR="No matching settings",cR="Clear search",dR="Beta",uR={title:"Settings are temporarily read-only",message:"Sparo OS continued startup with safe defaults because the saved configuration could not be loaded safely.",description:"Rebuild the current defaults when you are ready. This deletes the unusable configuration and its saved secrets, but keeps sessions, workspaces, apps, and other data.",promptTitle:"Saved configuration is unusable",promptMessage:"Sparo OS is running with safe defaults. Rebuild the current default configuration now? The unusable configuration and its saved secrets will be deleted; all other application data stays intact.",action:"Rebuild defaults",rebuilding:"Rebuilding…",later:"Later",failed:"The default configuration could not be rebuilt. Sparo OS is still running safely in read-only mode; try again from Settings."},pR={appearance:"Language, theme, and interface font size.",basics:"Logging, terminal shell, launch at login, and notifications.",models:"AI models, API keys, providers, and proxy.",personalization:"Title generation, Agent companion, and thinking process.",voiceInput:"Local speech input, model downloads, and microphone defaults.",bitfunCoder:"BitFun Coder debug logging, ingest port, and language templates.",permissions:"Tool confirmation, timeouts, and desktop automation access.",memory:"Automatic memory extraction cadence and enablement.",editor:"Code editor font, display, and formatting.",lsp:"Language servers and code intelligence.",keyboard:"Shortcuts and key bindings.",aiUsage:"Historical AI usage by agent, model, and time.",dataStorage:"Application data, storage usage, and reset controls."},mR={general:"Basics",data:"Data",smartCapabilities:"Smart Configuration",productApps:"Product Apps",advanced:"Advanced"},gR={ai:"AI",appearance:"Appearance",basics:"General",models:"Models",personalization:"Personalization",voiceInput:"Voice Input",bitfunCoder:"BitFun Coder","bitfun-coder":"BitFun Coder",permissions:"Permissions",memory:"Memory",skills:"Skills",agents:"Agents",editor:"Code Editor",lsp:"LSP",keyboard:"Keyboard",aiUsage:"AI Usage",dataStorage:"Data & Storage",terminal:"Terminal","product-apps":"Product Apps",themes:"Themes",font:"Fonts",version:"Version","last-modified":"Last modified"},hR={advanced:"Advanced","agent-companion":"Agent companion",appearance:"Appearance",behavior:"Behavior",composer:"Message composer","computer-use":"Desktop automation","daily-letter":"Daily Letter",debug:"Debugging","default-model":"Default models",display:"Display","font-size":"Font size","global-auto-memory":"Global automatic memory","goal-mode":"Goal mode","host-scan":"Host scan",language:"Language",logging:"Logging",models:"Models",notifications:"Notifications",providers:"Model providers",proxy:"Proxy",runtime:"Runtime","session-title":"Session titles",shell:"Shell",shortcuts:"Shortcuts",theme:"Theme","thinking-process":"Thinking process","tool-execution":"Tool execution",tray:"System tray","workspace-auto-memory":"Workspace automatic memory"},fR={"enable-visual-mode":"Visual mode",version:"Version","last-modified":"Last modified"},yR={title:iR,selectConfig:aR,searchPlaceholder:rR,searchNoResults:lR,searchClear:cR,beta:dR,recovery:uR,tabDescriptions:pR,categories:mR,tabs:gR,sections:hR,fields:fR},wR="Data & Storage",vR="Review local storage usage and run scoped cleanup or reset actions.",bR="Loading storage usage...",kR={reset:"Run reset",resetting:"Resetting...",openFolderTooltip:"Open in file explorer"},SR={usage:"Local storage usage",reset:"Reset & cleanup"},xR={total:"Managed total"},CR={config:"Settings and preferences",data:"General app data",state:"Interface and task state",sessions:"Sessions",works:"Works",runs:"Runs",app_data:"Intelligent App data",services:"System services",workspaces:"Workspace runtime",agentic_os:"Global Agentic OS runtime",apps:"Installed and generated apps",components:"Components",agents:"Agents",skills:"Skills",skill_suites:"Skill suites",runtimes:"Managed runtimes",browser_profiles:"Managed browser profiles",secrets:"Credentials and authorization",cache:"Cache",logs:"Logs",temp:"Temporary files",backups:"Backups"},AR={mode:{soft:"Clear caches",appData:"Reset local data",factory:"Factory reset"},summary:{soft:"Clear caches, temporary files, and UI layout state while keeping settings and data.",appData:"Remove local settings, state, sessions, apps, cache, and runtime data.",factory:"Erase all Sparo OS-managed local data, including credentials and browser profiles."},details:{soft:"Frees space by clearing caches, temporary files, and UI layout state. Settings, credentials, and workspace data stay intact.",appData:"Returns the app to a clean local state. Settings, sessions, Works, Runs, Intelligent App data, system-service state, Agentic OS runtime, installed apps, cache, and temporary files are deleted.",factory:"Wipes everything Sparo OS manages, including credentials, browser profiles, custom agents, skills, and managed runtimes."},dialog:{confirm:"Continue",cancel:"Cancel"},confirm:{included:"Included",excluded:"Skipped",soft:{title:"Clear caches?",message:"This clears caches, temporary files, and UI layout state. Settings, credentials, and workspace data are kept."},appData:{title:"Reset local data?",message:"This permanently deletes the selected Sparo OS local data and cannot be undone. Your project source files are never touched, and the app will restart once the reset completes."},factory:{title:"Factory reset?",message:"This permanently deletes all Sparo OS-managed data on this device and cannot be undone. The app will restart once the reset completes."}},options:{forced:"Always removed in this mode",backup:{label:"Create a reset backup",description:"Copy configuration and state into a backup folder before deleting."},logs:{label:"Include logs",description:"Also delete runtime logs."},secrets:{label:"Include secrets",description:"Also delete stored credentials and authorization vaults."},browser:{label:"Include browser profiles",description:"Also delete Sparo-managed browser login state and profiles."}}},_R={confirm:"Reset & restart",cancel:"Cancel"},TR={loadFailed:"Failed to load storage usage.",resetFailed:"Failed to reset local data.",resetComplete:"Reset {{resetId}} completed and freed {{size}}. Restart Sparo OS before continuing.",openFolderFailed:"Could not open this folder in the file explorer."},PR="No tracked storage usage yet.",FR={title:wR,subtitle:vR,loading:bR,actions:kR,sections:SR,metrics:xR,categoryLabels:CR,reset:AR,resetDialog:_R,messages:TR,empty:PR},RR="Debug Config",NR="Log and language debug template configuration",DR={combined:"Debug Mode Settings",settings:"Debug Settings",templates:"Language Debug Templates"},IR={javascript:"JavaScript / TypeScript",python:"Python",rust:"Rust",go:"Go",java:"Java"},MR={logPath:{label:"Log File Path",description:"Debug log save path (relative to workspace root), defaults to .sparo_os/debug.log",placeholder:".sparo_os/debug.log",browse:"Browse"},ingestPort:{label:"Ingest Server Port",description:"HTTP server port for receiving web application logs"}},jR={description:"When enabled, custom templates will override built-in logic. When disabled, system default templates are used.",enableTooltip:"Click to enable custom template",disableTooltip:"Click to disable custom template",instrumentation:{label:"Instrumentation Code Template",placeholder:"Enter instrumentation code template...",placeholders:"Available placeholders"},region:{label:"Region Markers",startPlaceholder:"Start marker",endPlaceholder:"End marker"},notes:"Notes",configure:"Configure",reset:"Reset to Default Templates",noteItems:{javascript:{postToIngest:"Send logs to the ingest server via HTTP POST.",replaceData:"Replace {DATA} with a JavaScript object expression."},python:{appendNdjson:"Append NDJSON logs directly to LOG_PATH in the workspace.",ensureAscii:"Use ensure_ascii=False to preserve non-ASCII characters.",replaceData:'Replace {DATA} with a Python expression (e.g., {"var": var} or locals()).',importOnce:"Add the import statement once at the top of the file."},rust:{appendNdjson:"Append NDJSON logs directly to LOG_PATH.",requireSerdeJson:"Requires serde_json: cargo add serde_json.",replaceData:'Replace {DATA} with a Rust expression (e.g., {"var": var}).',syncOnly:"Use in synchronous code; for async code use tokio::fs."},go:{iife:"Use an immediately-invoked function so it can be inserted anywhere.",appendNdjson:"Append NDJSON logs directly to LOG_PATH.",imports:'Requires imports: "os", "encoding/json", "time".',replaceData:'Replace {DATA} with a Go expression (e.g., map[string]interface{}{"var": var}).'},java:{appendNdjson:"Append NDJSON logs directly to LOG_PATH.",requireGson:"Requires Gson (or Jackson as an alternative).",replaceData:'Replace {DATA} with a Java object (e.g., Map.of("var", var)).',writeString:"Java 11+ can use Files.writeString; older versions use Files.write + getBytes()."}}},ER={save:"Save Config",saving:"Saving...",cancel:"Cancel"},LR={logFile:"Log File"},$R={loading:"Loading...",loadFailed:"Failed to load configuration",saveSuccess:"Configuration saved",saveFailed:"Failed to save configuration",resetSuccess:"Restored to default configuration",resetFailed:"Failed to reset configuration",logPathUpdated:"Log file path updated",selectFileFailed:"Failed to select file",templateEnabled:"Enabled {{name}} template",templateDisabled:"Disabled {{name}} template"},OR={title:RR,subtitle:NR,sections:DR,languageLabels:IR,settings:MR,templates:jR,actions:ER,fileDialog:LR,messages:$R},BR="Default Model Configuration",WR="Loading...",zR={default:"Default Config",models:"Model List",proxy:"Proxy"},UR={title:"Core Configuration",required:"Required",optional:"Optional",primary:{label:"Primary Model",description:"For complex reasoning, code generation, multi-step tasks",placeholder:"Select primary model"},fast:{label:"Fast Model",description:"For simple Q&A, quick responses, cost-saving scenarios",hint:"When not configured, all tasks use the primary model",placeholder:"Select fast model",notSet:"Not set (use primary model)"}},HR={title:"Multimodal Model Configuration",capabilities:{image_understanding:{label:"Image Understanding",description:"Analyze images and screenshots, support mixed image-text conversations"},image_generation:{label:"Image Generation",description:"Generate images from text descriptions"},speech_recognition:{label:"Speech Recognition",description:"Convert speech to text, support voice input"}},notConfigured:"Not configured",notSet:"Not set",selectModel:"Select model",autoSelect:"Auto select"},qR={title:"Advanced Configuration",modeOverrides:{title:"Mode Model Overrides",description:"Specify different models for specific modes (default: primary model)"},subAgentOverrides:{title:"SubAgent Model Overrides",description:"Specify different models for specific assistants (default: primary model)"},subAgents:{"git-func-agent":{displayName:"Git Functions",description:"Commit messages, code review"},"session-title-func-agent":{displayName:"Session titles",description:"Auto-generated conversation titles"},"arc-func-agent":{displayName:"Architecture Analysis",description:"Dependency graph, Mermaid diagrams"},compression:{displayName:"Context Compression",description:"Intelligently compress long conversation context"}}},VR={primary:"Primary",primaryShort:"Flagship",fast:"Fast",fastShort:"Fast",custom:"Custom",customShort:"Other",modelChoice:"Model choice",selectModel:"Select model",notConfigured:"Not configured, will use primary model"},GR={noModels:'No models available. Please add models in the "Model List" tab first.'},KR={loadFailed:"Failed to load configuration",updateFailed:"Update failed",modelUpdated:"{{slot}} set to {{name}}",capabilityUpdated:"Capability model updated"},QR={title:BR,loading:WR,tabs:zR,core:UR,optional:HR,advanced:qR,selection:VR,empty:GR,messages:KR},JR="Code Editor",YR="Code editor changes save automatically and update open editors.",ZR={appearance:{title:"Appearance"},behavior:{title:"Editing Behavior"},display:{title:"Display Settings"},advanced:{title:"Advanced Features"},reset:{title:"Reset"}},XR={font:"Font",fontSize:"Font Size",lineHeight:"Line Height"},e2={tabSize:"Tab Size",insertSpaces:"Insert Spaces",insertSpacesDesc:"Insert spaces instead of tabs",wordWrap:"Word Wrap",wordWrapOptions:{off:"Off",on:"On",wordWrapColumn:"At Column",bounded:"At Viewport and Column"},lineNumbers:"Line Numbers",lineNumberOptions:{on:"On",off:"Off",relative:"Relative",interval:"Interval"}},t2={minimap:"Show Minimap",minimapDesc:"Display code minimap on editor side",minimapPosition:"Minimap Position",minimapPositionLeft:"Left",minimapPositionRight:"Right",minimapSize:"Minimap Size",minimapSizeAuto:"Auto",minimapSizeFill:"Fill",minimapSizeFit:"Fit"},n2={formatOnSave:"Format on Save",formatOnSaveDesc:"Auto format code when saving",formatOnPaste:"Format on Paste",formatOnPasteDesc:"Auto format when pasting code",trimAutoWhitespace:"Trim Trailing Whitespace",trimAutoWhitespaceDesc:"Remove trailing whitespace on save"},o2={reset:"Reset to Default",save:"Save Settings"},s2={loading:"Loading...",loadFailed:"Failed to load configuration",saving:"Saving...",saveSuccess:"Config saved, open editors will update",saveFailed:"Failed to save configuration",resetFailed:"Failed to reset configuration",confirmReset:"Are you sure you want to reset editor config to defaults?",resetDone:"Reset to defaults"},i2={title:"Reset code editor settings?",message:"Code editor font, behavior, display, and advanced options will return to their defaults.",confirm:"Reset code editor",cancel:"Cancel"},a2={title:JR,subtitle:YR,sections:ZR,appearance:XR,behavior:e2,display:t2,advanced:n2,actions:o2,messages:s2,resetDialog:i2},r2="Keyboard Shortcuts",l2="Review shortcuts, record changes, then apply them together.",c2="Search shortcuts or key bindings…",d2="Apply",u2="Saving…",p2="Reset to Defaults",m2="Click to record a new key binding",g2="Press new key combination…",h2="Revert this change",f2="This shortcut is fixed and cannot be changed",y2="No matching shortcuts found",w2="Conflict",v2="Failed to save, please try again",b2="Failed to reset, please try again",k2="Mixed bindings — record to reset as a set",S2={title:"Reset keyboard shortcuts?",message:"All custom shortcut changes will be removed and the default bindings will be restored.",confirm:"Reset shortcuts",cancel:"Cancel"},x2={space:"Space"},C2={app:"Global",canvas:"Editor Canvas",chat:"Agent Session",filetree:"File Tree"},A2={nav:{toggleSearch:"Open navigation search"},scene:{openSettings:"Open Settings",openTerminal:"Open Terminal",escapeToAgenticBase:"Return to Agentic OS desktop"},canvas:{splitHorizontal:"Horizontal Split",splitVertical:"Vertical Split",anchorZone:"Toggle Anchor Zone",maximize:"Maximize Editor",closePreview:"Close Preview"},tab:{close:"Close Current Tab",reopenClosed:"Reopen Closed Tab",switchMerged:"Switch editor tab",switchMergedHint:"Record modifier + any digit 1–9 once; the same modifiers apply to all tab slots."},chat:{btwFill:"Start side-thread session",stopGeneration:"Stop Generation",activateInput:"Activate Input",newSession:"New Session"},filetree:{rename:"Rename",delete:"Delete",refresh:"Refresh",newFile:"New File",newFolder:"New Folder",collapseAll:"Collapse All"}},_2={title:r2,subtitle:l2,search:c2,apply:d2,saving:u2,reset:p2,clickToRecord:m2,recording:g2,revertChange:h2,fixedBinding:f2,noResults:y2,conflict:w2,saveError:v2,resetError:b2,mergedNonUniform:k2,resetDialog:S2,keyLabels:x2,scopes:C2,shortcuts:A2},T2="MCP",P2="Manage MCP server connections",F2={serverList:{title:"MCP Server List",description:"Manage MCP server status and JSON configuration."}},R2={servers:"Servers",add:"Add Server"},N2={id:"Server ID",idPlaceholder:"github-mcp",idHint:"Server ID is a unique identifier and cannot be duplicated",name:"Server Name",namePlaceholder:"GitHub MCP Server",type:"Server Type",typeLocal:"Local Process",typeRemote:"Remote Service",typeContainer:"Container Service",command:"Start Command",commandPlaceholder:"node",commandHint:"e.g.: node, python, npx",args:"Command Arguments (one per line)",argsPlaceholder:`server.js +--port +3000`,argsHint:"One argument per line",env:"Environment Variables",envPlaceholder:'JSON format, e.g.: {"KEY": "value"}',url:"Server URL",urlPlaceholder:"http://localhost:3000",enabled:"Enable this server",autoStart:"Auto start on application launch",transport:"Transport",statusDetail:"Status Detail",remoteUrl:"Remote URL",remoteAuth:"Authentication",remoteAuthConfigured:"configured",remoteAuthConfiguredWithSource:"configured via {{source}}",remoteAuthMissing:"not configured",remoteOAuthReady:"OAuth configured, authorization required",remoteAuthMethod:"Auth Method",remoteAuthMethodOAuthXaa:"OAuth configured, XAA reserved",remoteAuthMethodOAuth:"OAuth",remoteAuthMethodXaa:"XAA",remoteOAuthIdle:"Not started yet",remoteOAuthAwaitingBrowser:"Waiting to open browser",remoteOAuthAwaitingCallback:"Waiting for provider callback",remoteOAuthExchangingToken:"Exchanging authorization code",remoteOAuthAuthorized:"Authorized",remoteOAuthFailed:"Failed",remoteOAuthCancelled:"Cancelled",runtime:{source:"Source",path:"Resolved Path",available:"command available",unavailable:"command unavailable",managed:"managed",system:"system",unknown:"unknown",unsupportedReason:"Unavailable Reason",unsupportedRemoteSse:"Remote MCP SSE transport is not yet supported"},authSource:{headers:"headers",env:"env",oauth:"OAuth"}},D2={uninitialized:"Uninitialized",starting:"Starting",connected:"Connected",healthy:"Healthy",needsAuth:"Needs Auth",reconnecting:"Reconnecting",failed:"Failed",stopping:"Stopping",stopped:"Stopped",disconnected:"Disconnected",connecting:"Connecting",error:"Error"},I2={add:"Add Server",addFirst:"Add First Server",edit:"Edit",editServer:"Edit Server",addServer:"Add Server",delete:"Delete",start:"Start",stop:"Stop",restart:"Restart",refresh:"Refresh",save:"Save",saveConfig:"Save Config",cancel:"Cancel",cancelAdd:"Cancel Add",close:"Close",backToList:"Back to List",jsonConfig:"JSON Config",remoteAuth:"Remote Auth",startRemoteOAuth:"Connect with OAuth",restartRemoteOAuth:"Restart OAuth",reconnectRemoteOAuth:"Reconnect with OAuth",cancelRemoteOAuth:"Cancel OAuth",saveRemoteAuth:"Save and Reconnect"},M2={placeholder:"Search servers..."},j2={noServers:"No MCP servers configured",noServersHint:"Add MCP servers to extend functionality",noMatchingServers:"No matching servers found"},E2="Loading...",L2={type:"Type",enabled:"Enabled",autoStart:"Auto Start",status:"Status",yes:"Yes",no:"No"},$2={remoteAuthTitle:"Remote auth: {{serverName}}",remoteOAuthHint:"Use OAuth to connect this remote MCP server. Sparo OS will listen on a local callback URL and reconnect the server after authorization.",remoteOAuthCurrentStatus:"OAuth state: {{status}}",remoteOAuthRedirectUri:"Callback URL: {{redirectUri}}",remoteOAuthStatus:"OAuth status: {{status}} - {{message}}",remoteAuthHint:"Paste a Bearer token or a full Authorization header value. Saving will restart the remote MCP server.",remoteAuthServerUrl:"Server URL: {{url}}",remoteAuthPlaceholder:"Bearer eyJ... or eyJ..."},O2={title:"MCP JSON Config",hint1:"Use standard Cursor format for MCP configuration. Config will be saved to app.json in user directory.",hint2:'Format: the "type" field is optional. If you provide "command" it will be parsed as stdio (local process); if you provide "url" it will be parsed as sse (remote service). You can also set type="stdio"/"sse" explicitly for compatibility.',lintLocation:" (line {{line}}, col {{column}})",lintError:"JSON syntax error{{location}}: {{message}}",exampleTitle:"Configuration Examples:",localProcess:"Local Process (stdio):",remoteService:"Remote Service (sse):"},B2={title:"MCP Resources",actions:{refresh:"Refresh",close:"Close"},search:{placeholder:"Search resources..."},loading:{resources:"Loading resources...",content:"Loading content..."},empty:{noMatch:"No resources found",noResources:"No resources available",selectToView:"Select a resource to view its content"},errors:{loadContentFailed:"Failed to load resource content",binaryContent:"Binary resource content cannot be previewed here"},mockContent:`# {{name}} + +This is the content of {{uri}} + +Lorem ipsum dolor sit amet...`},W2={addSuccess:"Server added successfully",addFailed:"Failed to add server",deleteSuccess:"Server deleted",deleteFailed:"Failed to delete server",deleteConfirm:`Are you sure you want to delete this MCP server? + +Note: This action cannot be undone.`,startSuccess:'Server "{{serverId}}" started',startFailed:'Failed to start server "{{serverId}}"',stopSuccess:'Server "{{serverId}}" stopped',stopFailed:'Failed to stop server "{{serverId}}"',restartSuccess:'Server "{{serverId}}" restarted',restartFailed:'Failed to restart server "{{serverId}}"',saveSuccess:"MCP config saved and applied",saveFailed:"Failed to save config",partialStartFailed:"Config saved, but some servers failed to start. Please check server configuration.",serverSaved:'Server "{{name}}" saved',jsonError:"JSON format error",nameRequired:"Please enter server name",idRequired:"Please enter server ID",commandRequired:"Local process type requires a start command",urlRequired:"Remote service type requires a server URL",validationFailed:"Validation Failed",commandUnavailable:'Server "{{serverId}}" command is unavailable. Check runtime installation or command configuration.',remoteOAuthAuthorized:'OAuth connected for "{{serverId}}".',remoteOAuthFailed:'OAuth failed for "{{serverId}}".',remoteAuthRequired:"Please provide a Bearer token or full Authorization header value.",remoteAuthUpdated:'Updated remote auth for "{{serverId}}".',remoteOAuthStarted:'Opened OAuth sign-in for "{{serverId}}".'},z2={unknownError:"Unknown error",jsonFormatError:"JSON Format Error",configStructureError:"Config Structure Error",serverConfigError:"Server Config Error",permissionError:"File Permission Error",fileOperationError:"File Operation Failed",resourceNotFound:"Resource Not Found",serverStartError:"Server Start Failed",operationFailed:"{{context}} Failed",suggestions:{jsonFormat:["Use online JSON validator to check format","Ensure all strings use double quotes","Check for extra commas","Verify all brackets are properly closed"],configStructure:['Check if config contains "mcpServers" field','Ensure "mcpServers" is an object type',"Refer to the configuration examples"],serverConfig:["Provide either command (stdio) or url (sse)","args must be an array format","env must be an object format"],permission:["Run application as administrator","Check config file access permissions","Verify antivirus is not blocking file writes"],fileOperation:["Check if disk space is sufficient","Verify config directory exists and is accessible","Try restarting the application"],serverStart:["Check if command path is correct","Verify required runtime is installed (e.g., Node.js)","Check environment variable configuration","Verify port is not in use"],default:["Check network connection","Try the operation again","Check logs for more information","Contact technical support if issue persists"]},jsonParseError:`JSON format error: {{message}} + +Please check: +• All key names and string values use double quotes +• No extra commas +• All brackets are properly closed`,mcpServersRequired:`Config must contain "mcpServers" field + +Correct format: +{ + "mcpServers": { + "server-name": { ... } + } +}`,mcpServersMustBeObject:`"mcpServers" must be an object (not an array or other type) + +Correct format: +"mcpServers": { + "server-id": {...} +}`,deleteServerFailed:'Failed to delete server "{{serverId}}": {{message}}'},U2={startSuccess:"Start Success",startFailed:"Start Failed",stopSuccess:"Stop Success",stopFailed:"Stop Failed",restartSuccess:"Restart Success",restartFailed:"Restart Failed",saveSuccess:"Save Success",saveFailed:"Save Failed",deleteSuccess:"Delete Success",deleteFailed:"Delete Failed",operationFailed:"Operation Failed",partialStartFailed:"Partial Server Start Failed",suggestionPrefix:"Suggestions:"},H2={title:T2,subtitle:P2,section:F2,tabs:R2,server:N2,status:D2,actions:I2,search:M2,empty:j2,loading:E2,labels:L2,modal:$2,jsonEditor:O2,resourceBrowser:B2,messages:W2,errors:z2,notifications:U2},q2="Memory",V2="Control background memory extraction and host scanning cadence.",G2={global:{sectionTitle:"Global memory",enabled:"Enable global auto memory",enabledDesc:"Automatically extract durable knowledge into global agentic_os memory.",extractEveryEligibleTurns:"How often to update global memory",extractEveryEligibleTurnsDesc:"Update agentic_os memory once every N eligible conversations.",minExtractIntervalMinutes:"Minimum time between updates",minExtractIntervalMinutesDesc:"Set to 0 to disable the cooldown.",forceExtractAfterPendingEligibleTurns:"Force update during cooldown",forceExtractAfterPendingEligibleTurnsDesc:"Set to 0 to disable this override. Otherwise, auto memory runs immediately once pending eligible turns reach this threshold, even if the cooldown has not expired."},workspace:{sectionTitle:"Workspace memory",enabled:"Enable workspace auto memory",enabledDesc:"Automatically extract durable knowledge into this workspace's memory.",extractEveryEligibleTurns:"How often to update workspace memory",extractEveryEligibleTurnsDesc:"Update workspace memory once every N eligible conversations.",minExtractIntervalMinutes:"Minimum time between updates",minExtractIntervalMinutesDesc:"Set to 0 to disable the cooldown.",forceExtractAfterPendingEligibleTurns:"Force update during cooldown",forceExtractAfterPendingEligibleTurnsDesc:"Set to 0 to disable this override. Otherwise, auto memory runs immediately once pending eligible turns reach this threshold, even if the cooldown has not expired."},units:{minutes:"min",turns:"turns"}},K2={text:"Loading configuration..."},Q2={disableAll:"Disable",enableAll:"Enable",resetAll:"Reset",retry:"Retry"},J2={title:"Reset memory settings?",message:"Global memory, workspace memory, and host scan settings will return to their defaults.",confirm:"Reset settings",cancel:"Cancel"},Y2={title:"Host Scan",enable:{label:"Enable background auto scan",description:"Periodically refresh the host overview in a background Agentic OS session. If the file is missing or empty, the first attempt waits 10 minutes."},interval:{label:"Regular scan interval",description:"When the host overview already exists and is non-empty, refresh it on this cadence"},intervals:{daily:"Daily",every3Days:"Every 3 days",weekly:"Every 7 days",every2Weeks:"Every 14 days",monthly:"Every 30 days"},messages:{loadFailed:"Failed to load host scan settings",saveFailed:"Failed to save host scan settings",enabledUpdated:"Host scan setting updated",intervalUpdated:"Host scan interval updated"}},Z2={loadFailed:"Failed to load configuration",saveSuccess:"Settings saved",saveFailed:"Save failed",disableAllSuccess:"Auto memory and host scan disabled",disableAllFailed:"Failed to disable settings",enableAllSuccess:"Auto memory and host scan enabled",enableAllFailed:"Failed to enable settings",resetAllSuccess:"Memory settings reset to defaults",resetAllFailed:"Failed to reset settings"},X2={title:q2,subtitle:V2,autoMemory:G2,loading:K2,actions:Q2,resetDialog:J2,hostScan:Y2,messages:Z2},eN="Permissions",tN="Control tool approval, execution limits, and desktop automation access.",nN={sectionTitle:"Tool execution behavior"},oN={maxContinuationTurns:"Goal auto-run budget",maxContinuationTurnsDesc:"Maximum number of automatic continuation turns Goal mode can queue for each new goal.",turns:"turns"},sN={sectionTitle:"Computer use (desktop)",enable:"Enable Computer use",enableDesc:"When off, the ComputerUse tool stays disabled in every session mode.",accessibility:"Accessibility",accessibilityDesc:"",screenCapture:"Screen recording",screenCaptureDesc:"",granted:"Granted",notGranted:"Not granted",openSettings:"Setting",platformNote:"Note"},iN={sectionTitle:"Browser control (CDP)",status:"Browser status",statusDesc:"Sparo OS uses port 9222 to control browser tabs directly through CDP.",connected:"Connected",notConnected:"Not connected",tabs:"tabs",connect:"Connect",connectSuccess:"Connected to {{browser}}",connectFailed:"Failed to connect browser",restartSuccess:"Restarted {{browser}} with debugging enabled",restartFailed:"Failed to restart browser with debugging enabled",createLauncher:"Create launcher",createLauncherDesc:"Create a macOS launcher that starts the browser with the CDP debugging port enabled.",createLauncherSuccess:"Launcher created at {{path}}",createLauncherFailed:"Failed to create launcher",restartModal:{title:"Restart browser?",description:"{{browser}} is already running without the debugging port. Sparo OS needs to restart it with debugging enabled before it can control tabs.",warning:"This will close current browser windows and reopen the browser.",cancel:"Cancel",confirm:"Restart and enable debugging",restarting:"Restarting..."}},aN={text:"Loading configuration..."},rN={saveSuccess:"Settings saved",saveFailed:"Save failed"},lN={title:eN,subtitle:tN,toolExecution:nN,goalMode:oN,computerUse:sN,browserControl:iN,loading:aN,messages:rN},cN="Personalization",dN="Tune assistant presentation, companion appearance, and session-facing behavior.",uN={sessionTitle:{title:"Auto Session Title",warning:"Session title will use first 20 characters of user message"},dailyLetter:{title:"Daily Letter",enable:"Enable Daily Letter",subtitle:"Choose the model used to write Daily Letters. When unset, it uses the primary model."},agentCompanion:{title:"Agent companion",enable:"Show Agent companion",petLabel:"Appearance",petDescription:"Choose a built-in appearance or import a Petdex zip package.",petPlaceholder:"Choose appearance",defaultPet:"Default Sparky",defaultPetDescription:"Use the built-in Sparky companion.",groups:{presets:"Built-in",imported:"Imported"},import:"Import",importing:"Importing...",delete:"Delete",deleteDialog:{title:"Delete imported appearance?",message:'"{{name}}" will be removed from this device. The default companion will be selected instead.',confirm:"Delete appearance",cancel:"Cancel"}},thinkingProcess:{title:"Thinking process",showProcess:"Show thinking process",showProcessDescription:"When off, FlowChat no longer shows model thinking output.",keepCompletedItem:"Keep expandable item after completion",keepCompletedItemDescription:"After a thinking output finishes and auto-collapses, keep an expandable thinking item in FlowChat."}},pN={label:"Model",primary:"Primary Model",fast:"Fast Model",notConfigured:"Not configured",fastUsesPrimary:"Uses flagship"},mN={enable:"Enable"},gN={empty:'No available models. Please add models in "Models" first.',updateSuccess:"{{agentName}} will use {{modelName}}"},hN={text:"Loading configuration..."},fN={saveSuccess:"Settings saved",saveFailed:"Save failed",updateFailed:"Update failed"},yN={title:cN,subtitle:dN,features:uN,model:pN,common:mN,models:gN,loading:hN,messages:fN},wN="Voice Input",vN="Manage local speech input and the SenseVoice Small INT8 model.",bN="Loading voice input settings...",kN={composer:"Message composer",model:"Local model"},SN={auto:"Auto detect",zh:"Mandarin Chinese",yue:"Cantonese",en:"English",ja:"Japanese",ko:"Korean"},xN={enabled:{label:"Show voice input",description:"Display the microphone action in the composer."},language:{label:"Recognition language",description:"Default language used for local transcription."},maxRecording:{label:"Recording limit",description:"Maximum seconds per voice input."}},CN={not_installed:"Not installed",downloading:"Downloading",installed:"Installed",verifying:"Verifying",corrupt:"Needs repair",deleting:"Deleting",error:"Error"},AN={refresh:"Refresh",version:"Version {{version}}",size:"{{size}}",progress:"{{percent}}% · {{downloaded}} / {{total}}",download:"Download",downloading:"Downloading",downloaded:"Downloaded",cancel:"Cancel",cancelling:"Cancelling",openFolder:"Open location",verify:"Verify",verifying:"Verifying",delete:"Delete",deleting:"Deleting",keep:"Keep",deleteConfirmTitle:"Delete local speech model?",deleteConfirmMessage:"{{name}} will be removed from local storage.",empty:"No speech model is available."},_N={loadFailed:"Failed to load voice input settings",saveSuccess:"Voice input settings saved",saveFailed:"Failed to save voice input settings",downloadSuccess:"Speech model downloaded",downloadFailed:"Failed to download speech model",downloadCancelled:"Speech model download cancelled",cancelFailed:"Failed to cancel download",openFolderFailed:"Failed to open speech model location",verifySuccess:"Speech model verified",verifyFailed:"Failed to verify speech model",deleteSuccess:"Speech model deleted",deleteFailed:"Failed to delete speech model"},TN={title:wN,subtitle:vN,loading:bN,sections:kN,languages:SN,composer:xN,states:CN,model:AN,messages:_N},PN="Open Project",FN="New Project",RN="Go Home",NN="Return to main desktop",DN="Back to previous scene",IN="Recent scenes",MN="Scene navigation",jN="Global",EN="About",LN="Open Menu",$N="Open task list",ON="Task Management",BN="Close Menu",WN="Select a project directory to open",zN="Settings",UN="Expand Left Panel",HN="Collapse Left Panel",qN="Expand Right Panel",VN="Collapse Right Panel",GN="Chat",KN="Show Chat Panel",QN="Hide Chat Panel",JN="Appearance",YN="Language",ZN="Language",XN="Theme",eD="Follow system",tD="Multi-Device Collaboration",nD="Open a workspace before using Device Network.",oD="Multi-Device Collaboration · Connected",sD="Multi-Device Collaboration · Waiting for connection",iD="Set up connection",aD="View details",rD="Disconnect bot",lD="Disconnecting...",cD="Via",dD="View mode switch",uD="Cowork Assistant",pD="BitFun Coder",mD="Switch to Cowork Assistant",gD="Switch to Coder mode",hD="Hide Agentic",fD="Activate Agentic",yD="Switch Workspace",wD="Recent Workspaces",vD="No Recent Workspaces",bD="Select Workspace",kD={openProject:PN,newProject:FN,goHome:RN,returnToMainDesktop:NN,backToPreviousScene:DN,recentScenes:IN,sceneNavigation:MN,globalScope:jN,about:EN,openMenu:LN,openSessionsList:$N,openTaskManagement:ON,closeMenu:BN,selectProjectDirectory:WN,configCenter:zN,expandLeftPanel:UN,collapseLeftPanel:HN,expandRightPanel:qN,collapseRightPanel:VN,chatPanel:GN,showChatPanel:KN,hideChatPanel:QN,appearance:JN,language:YN,languageList:ZN,appearanceThemeList:XN,followSystemTheme:eD,remoteConnect:tD,remoteConnectRequiresWorkspace:nD,remoteControlConnected:oD,remoteControlWaiting:sD,remoteControlSetup:iD,remoteControlViewDetails:aD,remoteControlDisconnectBot:rD,remoteControlDisconnecting:lD,remoteControlVia:cD,modeSwitchAriaLabel:dD,modeCowork:uD,modeCoder:pD,switchToCowork:mD,switchToCoder:gD,hideAgentic:hD,activateAgentic:fD,switchWorkspace:yD,recentWorkspaces:wD,noRecentWorkspaces:vD,noWorkspaceOpen:bD},SD={navControl:"Navigation controls",mainNav:"Main navigation",sceneHeader:"Scene header"},xD="Back",CD="Forward",AD="Back (Alt+←)",_D="Forward (Alt+→)",TD={sessions:"Tasks",project:"Directory",memory:"Memory",agents:"AI Apps",skills:"Skills",tools:"Tools",capabilities:"Capabilities",terminal:"Shell",git:"Git",subAgent:"Subagents"},PD={agents:"Which agents it can call",skills:"What it knows — specialized knowledge files",tools:"What it can use — built-in tools & MCP services",addWorkspace:"Add workspace",newAgenticOsSession:"Restart Agentic OS"},FD={workspace:"Workspace",sessions:"Tasks",apps:"Apps",devKit:"Dev Kit",shell:"Shell"},RD="Collapse task list",ND={entry:{title:"App Builder",description:"Build a Product App with a clear goal, work object, surface, and component graph."},panel:{title:"App Builder",reload:"Reload preview",openInApps:"Open Product App",emptyTitle:"Builder is drafting for you",emptyDescription:"The first runnable version will appear here automatically.",loading:"Loading preview",loadFailed:"Failed to load preview",retry:"Retry"},diagnostics:{title:"Diagnostics",ok:"Runtime OK",empty:"No runtime errors yet",fatalCount:"{{count}} errors",warningCount:"{{count}} warnings"}},DD={comingSoon:"Soon"},ID={triggerPlaceholder:"Search",headerSearchHint:"Alt + F Search",headerShortcut:"Alt F",triggerTooltip:"Search (Alt+F)",inputPlaceholder:"Search work, workspaces, Product Apps, and Components...",groupWorks:"Work",groupRecentWork:"Recent work",groupWorkspaces:"Open Workspaces",groupApps:"Product Apps",groupWorkObjects:"Work Objects",groupComponents:"Components",groupArtifacts:"Artifacts",groupSessions:"Task chats",groupRecentTasks:"Recent task chats",empty:"No results found",noRecentTasks:"No recent work. Type to search workspaces, Product Apps, Components, and more.",workHint:"{{status}}",workWorkspaceHint:"{{status}} in {{workspace}}",workObjectHint:"{{app}} / {{scope}}",artifactHint:"from {{work}}",sessionWorkspaceHint:"chat in {{workspace}}"},MD={title:"Extensions",categories:{agents:"Agents",extensions:"Extensions",analytics:"Analytics"}},jD={title:"Shell",filters:{label:"Show"},views:{all:"All",manual:"Mine",agent:"Agent"},actions:{newTerminal:"New Terminal",refresh:"Refresh"},context:{start:"Start",stop:"Stop",editConfig:"Edit Config",saveConfig:"Save Config",deleteSavedTerminal:"Delete Saved Terminal",delete:"Delete",close:"Close"},badges:{startupCommand:"cmd",saved:"saved",default:"Default"},empty:{all:"No terminals yet",manual:"No user terminals yet",agent:"No agent terminals yet",quickNew:"Quick new terminal"}},ED={newSession:"New task",newBitfunCoderSession:"BitFun Coder",newCoworkSession:"Write, organize, or plan",newDesignSession:"Design or prototype",newBitfunCoderSessionShort:"BitFun Coder",newBitfunCoderSessionDomain:"Coding Product App",newCoworkSessionShort:"Cowork Assistant",newCoworkSessionDomain:"Writing and planning",newDesignSessionShort:"Designer",newDesignSessionDomain:"Design and prototypes",newDeepResearchSession:"Research a topic",newDeepResearchSessionShort:"Research task",newDeepResearchSessionDomain:"Research and synthesis",newAppBuilderSession:"Create a Product App",newAppBuilderSessionShort:"App Builder",newAppBuilderSessionDomain:"Product App design",systemBadge:"System",systemGroup:"System",extensionGroup:"Extensions",modeAppBuilder:"App Builder",agenticOs:"Open Agentic OS",agenticOsShort:"Agentic OS",modeBitfunCoder:"BitFun Coder",modeCowork:"Cowork Assistant",modeDesign:"Designer",bitfunCoderSessionMode:"BitFun Coder task",coworkSessionMode:"Cowork Assistant task",designSessionMode:"Designer task",noSessions:"No tasks yet",rename:"Rename",delete:"Delete",confirmEdit:"Confirm",cancelEdit:"Cancel",showMore:"{{count}} more tasks",showAll:"{{count}} more (show all)",showLess:"Show less",workspaceOwner:"Workspace: {{name}}",sessionContext:"In: {{name}}"},LD={title:"Scheduled Jobs",open:"Open scheduled jobs",shortLabel:"Schedule",listTitle:"Jobs",loading:"Loading scheduled jobs...",never:"Not scheduled",nextRunLabel:"Next run",fields:{workspacePath:"Workspace path",session:"Session",name:"Job name",enabled:"Enabled",enabledHint:"Enable this job",scheduleKind:"Schedule type",at:"Run at",everyMs:"Interval (minutes)",anchorMs:"Anchor time (optional)",cronExpr:"Cron expression",timezone:"Timezone (optional)",prompt:"Prompt"},placeholders:{workspacePath:"Enter workspace path",session:"Select or enter a session ID",name:"For example: Daily global news briefing",anchorMs:"Leave blank to use creation time",timezone:"For example: Asia/Shanghai",prompt:"Enter the message that should be sent when the schedule fires"},scheduleKinds:{at:"One-time",every:"Interval",cron:"Cron"},scheduleSummary:{every:"Every {{everyMinutes}} minutes",cron:"Cron: {{expr}}",cronWithTz:"Cron: {{expr}} · {{tz}}"},status:{idle:"Idle",disabled:"Disabled",queued:"Queued",running:"Focus",ok:"OK",error:"Error",cancelled:"Cancelled"},actions:{refresh:"Refresh jobs",newJob:"New job",toggleEnabled:"Toggle enabled state",edit:"Edit job",delete:"Delete job",save:"Save changes",create:"Create job",cancel:"Cancel"},editor:{editTitle:"Edit job",createTitle:"Create job"},empty:{title:"No scheduled jobs yet",description:"Click the plus button to create your first scheduled job."},deleteDialog:{title:'Delete job "{{name}}"?'},messages:{loadFailed:"Failed to load scheduled jobs: {{error}}",saveFailed:"Failed to save scheduled job: {{error}}",updateFailed:"Failed to update scheduled job: {{error}}",deleteFailed:"Failed to delete scheduled job: {{error}}",deleteSuccess:"Scheduled job deleted",createSuccess:"Scheduled job created",updateSuccess:"Scheduled job updated"},validation:{nameRequired:"Please enter a job name",promptRequired:"Please enter the job prompt",workspaceRequired:"Please enter a workspace path",sessionRequired:"Please select a session"}},$D={empty:"No opened workspaces yet",emptyProjects:"No project workspaces",closeFailed:"Failed to close workspace",resetWorkspaceFailed:"Failed to reset workspace",workspaceReset:"Workspace reset",reorderFailed:"Failed to reorder workspaces",dropBefore:"Release to insert before",dropAfter:"Release to insert after",revealFailed:"Failed to reveal workspace folder",copyPathFailed:"Failed to copy path",createSessionFailed:"Failed to create task",initSessionFailed:"Failed to start AGENTS.md initialization task",worktreeCreated:"Worktree created",worktreeCreatedAndOpened:"Worktree created and opened",worktreeCreateFailed:"Failed to create worktree: {{error}}",worktreeCreateOrOpenFailed:"Worktree was created, but opening it as a workspace failed: {{error}}",worktreeDeleted:"Worktree deleted",deleteWorktreeFailed:"Failed to delete worktree",expandSessions:"Expand task list",collapseSessions:"Collapse task list",groups:{projects:"Projects"},actions:{more:"More actions",newSession:"New task",resetWorkspace:"Reset workspace",initAgents:"Initialize AGENTS.md",newWorktree:"New worktree",deleteWorktree:"Delete worktree",copyPath:"Copy path",reveal:"Reveal in explorer",close:"Close workspace"},resetWorkspaceDialog:{title:"Reset {{name}}?",message:"This will clear everything inside the workspace directory without deleting the workspace directory itself.",pathLabel:"Workspace path"},deleteWorktreeDialog:{title:"Delete {{name}}?",message:"This will close the workspace and remove the worktree directory.",pathLabel:"Worktree path"}},OD={allAgents:"All Agents",newAgent:"New Agent",agentsOverview:"Agents"},BD={allSkills:"All Skills",addSkill:"Add Skill"},WD={builtinTools:"Built-in Tools",mcpServices:"MCP Services"},zD={openMyAgent:"My Agent",customize:"Customize"},UD="More options",HD="Multimodal Tools",qD="Notifications",VD=JSON.parse(`{"subtitle":"What do you want to work on?","agenticOSDesc":"Coordinate and carry AI work","sectionExtensions":"Extensions","sectionSystem":"System","welcomeHint":"Open Agentic OS on the left, or browse extensions and system tools","hub":{"ariaLabel":"Sparo Hub","sections":{"frequent":"Main","more":"More","preview":"Browse previews","direct":"Go directly"},"aria":{"frequent":"Main destinations","more":"More destinations","preview":"Destinations that switch the preview","direct":"Destinations that open scenes directly"},"controls":{"group":"Environment and preferences","settings":"Open Settings","about":"About","settingsShort":"Settings","theme":"Theme","language":"Language","systemTheme":"Follow system","systemThemeShort":"System","lightTheme":"Light","darkTheme":"Dark","currentTheme":"Theme: {{value}}","currentLanguage":"Language: {{value}}","exitTheme":"Exit theme selection","exitLanguage":"Exit language selection"},"trigger":{"open":"Open Sparo Hub","close":"Close Sparo Hub"},"capsule":{"default":"Sparo Hub","running":"Work · {{count}} running","attention":"Work · {{count}} need you","dailyLetter":"Daily Letter · Unread"},"states":{"current":"Current","ready":"Ready","unread":"Unread","running":"{{count}} running"},"actions":{"openItem":"Open {{item}}","newAgenticOsSession":"New session"},"work":{"summary":"{{running}} running · {{attention}} need you","empty":"No work needs attention right now","open":"Open Work Center","new":"New work"},"stage":{"agentic-os":{"status":"Ready","lede":"Start with an outcome. Sparo connects the right capabilities and keeps the work continuous.","points":{"first":{"title":"Start a conversation","meta":"Name the next outcome"},"second":{"title":"Continue together","meta":"Return to recent context"},"third":{"title":"Run history","meta":"See the execution thread"}}},"apps":{"status":"Action surface","lede":"Apps work independently or become the dedicated execution surface for a work item.","points":{"first":{"title":"Discover","meta":"Find the right capability"},"second":{"title":"Open","meta":"Enter the app space"},"third":{"title":"Carry work","meta":"Connect the current task"}}},"files":{"status":"Global scope","lede":"Move naturally between the local file system, global locations, and project workspaces.","points":{"first":{"title":"Computer","meta":"Drives and pinned folders"},"second":{"title":"Workspace","meta":"Project-scoped browsing"},"third":{"title":"Open location","meta":"Continue with a file"}}},"shell":{"status":"Environment ready","lede":"Choose the right system or project execution scope while keeping context intact.","points":{"first":{"title":"System scope","meta":"Global command environment"},"second":{"title":"Project scope","meta":"Follow the workspace"},"third":{"title":"Permission edge","meta":"Keep execution explicit"}}},"daily-letter":{"status":"Working in background","lede":"The system gathers progress, distills what matters, and delivers it at the right moment.","points":{"first":{"title":"Gather","meta":"Collect today's activity"},"second":{"title":"Distill","meta":"Find signals and follow-ups"},"third":{"title":"Deliver","meta":"Shape the Daily Letter"}}},"memory":{"status":"Only visible to you","lede":"Memory is not a filing cabinet. It is a personal trajectory formed through long-term collaboration.","points":{"first":{"title":"Preferences","meta":"Understand your choices"},"second":{"title":"Collaboration","meta":"Adapt how Sparo works"},"third":{"title":"Project context","meta":"Carry context forward"}}},"skills":{"status":"Matched automatically","lede":"Connect specialist knowledge and working methods so they appear in the right tasks.","points":{"first":{"title":"Knowledge","meta":"Capture expertise"},"second":{"title":"Method","meta":"Organize reliable flows"},"third":{"title":"Invocation","meta":"Match the task"}}},"tools":{"status":"Called on demand","lede":"Built-in tools and connected services extend what agents can execute safely.","points":{"first":{"title":"Built-in tools","meta":"System execution"},"second":{"title":"MCP services","meta":"Connected systems"},"third":{"title":"Permission edge","meta":"Keep calls controlled"}}},"subagents":{"status":"Ready to coordinate","lede":"The lead agent holds direction while specialists take on clearly bounded work in parallel.","points":{"first":{"title":"Lead agent","meta":"Hold the overall direction"},"second":{"title":"Specialists","meta":"Match focused capability"},"third":{"title":"Parallel work","meta":"Return one result"}}},"settings":{"status":"Applies globally","lede":"A small set of controls shapes Sparo OS capabilities, boundaries, and expression.","points":{"first":{"title":"Models","meta":"Default intelligence"},"second":{"title":"Permissions","meta":"Execution boundaries"},"third":{"title":"Appearance & behavior","meta":"Personalize the experience"}}}},"preview":{"common":{"loading":"Loading","statusUnavailable":"Status unavailable","partialData":"Partial data","enabled":"On","disabled":"Off","count":"{{count}} items","retry":"Retry"},"agenticOs":{"category":"Coordination hub","status":{"processing":"Working now","current":"Current session","available":"Ready"},"summary":"{{sessions}} sessions · {{turns}} turns","sections":{"continue":"Continue together","recent":"Recent sessions","sessionCount":"{{count}} shown"},"session":{"turns":"{{count}} turns","loading":"Loading…"},"empty":{"title":"Start a new collaboration","description":"Tell Sparo what you want to make happen.","noRecent":"No other recent sessions"},"actions":{"newSession":"New session","openTimeline":"View timeline"},"aria":{"openSession":"Open session: {{title}}"}},"workCenter":{"category":"Work surface","status":{"loading":"Loading","unavailable":"Unavailable","attention":"{{count}} need you","running":"{{count}} running","idle":"Up to date"},"metrics":{"running":"Running","attention":"Need you","recent":"Recent"},"sections":{"running":"Running now","recent":"Recent work","workCount":"{{count}} total"},"empty":{"noWork":"No work yet","noRunning":"Nothing is running","noRecent":"No recent work"},"error":{"loadFailed":"Couldn't load work"},"actions":{"newWork":"New work","openAll":"View all work","retry":"Retry","handle":"Handle","viewProgress":"View progress","resume":"Resume","continue":"Continue","viewResult":"View result","open":"Open"},"aria":{"openWork":"Open work: {{title}}"},"workStatus":{"draft":"Draft","active":"Ready","running":"Running","waiting_user":"Waiting for you","blocked":"Blocked","paused":"Paused","completed":"Completed","failed":"Failed","cancelled":"Cancelled","interrupted":"Interrupted","archived":"Archived"}},"apps":{"category":"Intelligent apps","status":"{{count}} ready to continue","metrics":{"active":"Continue","installed":"Installed","discover":"Discover"},"sections":{"apps":"Apps","continue":"Continue running","running":"Running","pinned":"Pinned","recommended":"Recommended apps","recent":"Recently opened","installed":"My apps","discover":"Discover apps"},"workStatus":{"running":"Running","attention":"Needs attention","active":"Ready to continue"},"appState":{"running":"Running","installed":"Installed","discover":"View"},"actions":{"open":"Open App Center","create":"Create app","manage":"Manage"},"empty":{"appsTitle":"No apps available","continueTitle":"Nothing to continue","runningTitle":"No running apps","catalogTitle":"No recommendations"},"aria":{"apps":"Apps","runningApps":"Running apps","recommendedApps":"Recommended apps","continueApp":"Continue {{name}}","openRunningApp":"Open running app {{name}}","openApp":"Open app {{name}}"},"errors":{"works":"App work is temporarily unavailable","catalog":"The app catalog is temporarily unavailable"}},"files":{"category":"Global file system","search":{"placeholder":"Search locations or enter a path","ariaLabel":"Search known locations or enter a full path","clear":"Clear location search"},"sections":{"continue":"Continue browsing","common":"Common locations","results":"Location results"},"actions":{"open":"Open file manager","search":"Search locations"},"types":{"folder":"Folder","file":"File"},"empty":{"continueTitle":"Nothing to continue","commonTitle":"No common locations","searchTitle":"No matching locations","contentsTitle":"This location is empty"},"aria":{"openLocation":"Open location {{name}}","openEntry":"Open {{name}}"},"errors":{"contents":"This location is temporarily unavailable"}},"shell":{"category":"Execution environments","status":"{{count}} running","metrics":{"running":"Running","manual":"Manual","agent":"Agent"},"sections":{"running":"Running","saved":"Saved terminals"},"actions":{"open":"Open Shell","new":"New terminal"},"newSessionName":"Terminal {{count}}","empty":{"runningTitle":"No terminals","savedTitle":"No saved terminals","savedDescription":"Save a name, directory, and startup command in Shell.","workspaceDescription":"Open a workspace to use saved terminals."},"errors":{"sessions":"Terminal status is temporarily unavailable"}},"dailyLetter":{"category":"System briefing","status":{"notGenerated":"Not written today","writing":"Writing today's letter","unread":"Unread","ready":"Read"},"actions":{"generate":"Generate today's letter","generating":"Generating…","open":"Open Daily Letter","openUnread":"Open the letter","continue":"Continue reading","expandReading":"Expand to read","reviewReceipts":"Review {{count}} receipts"},"receiptPrompt":"{{count}} thing to confirm","metrics":{"pendingReceipts":"Receipts","appIdeas":"App ideas","history":"Letters"},"sections":{"today":"Today","recent":"Recent letters"},"scope":{"agentic_os":"Global","workspace":"Workspace"},"empty":{"todayTitle":"No letter today","writingTitle":"Generating letter","history":"No previous letters"},"errors":{"load":"Daily Letter is temporarily unavailable","history":"Recent letters could not be loaded","generate":"The letter could not be generated"}},"memory":{"category":"User trajectory","status":{"ready":"Auto memory on","partial":"Partially active","paused":"Automatic memory is paused"},"actions":{"open":"Open Memory"},"growth":{"title":"Today's growth","unit":"points","caption":"Memories saved today","recent":"Recent memories","empty":"No new memories yet today","persistence":"{{count}} sources consolidated","persistencePending":"Ready to consolidate"},"sections":{"current":"Current memory"},"items":{"user":{"title":"About you","meta":"Preferences and collaboration style"},"longTerm":{"title":"Long-term memory","meta":"Formed through continued collaboration"},"workspace":{"title":"Current workspace","meta":"Project context"}},"updated":{"today":"Today","hoursAgo":"{{count}}h ago","unavailable":"Not formed yet","noWorkspace":"No workspace"},"consolidation":{"ariaLabel":"Memory consolidation status","state":{"ready":"Organized","running":"Organizing","failed":"Needs attention","disabled":"Unavailable","notRun":"Not organized yet"},"summary":"{{count}} sources · {{time}}","lastRun":"Last organized {{time}}","runningMeta":"Consolidating recent memory records","notRunMeta":"Ready when memory records appear","statusUnavailable":"Status unavailable","actions":{"run":"Organize now","running":"Organizing"},"messages":{"started":"Memory organization started","notNeeded":"Memory is already up to date","failed":"Memory organization failed"}},"errors":{"load":"Memory is temporarily unavailable","records":"Memory records could not be loaded"}},"skills":{"category":"Capability extensions","status":{"available":"Capabilities available","empty":"No skills installed"},"metrics":{"installed":"Installed","project":"Project","suites":"Suites"},"sections":{"available":"Available now","popular":"Popular to discover"},"scope":{"builtin":"Built in","user":"User","project":"Project"},"meta":{"installed":"{{count}} installed","installs":"{{count}} installs"},"actions":{"open":"Open Skills"},"empty":{"installedTitle":"No installed skills","marketTitle":"No new skills"},"errors":{"load":"Skills are temporarily unavailable","installed":"Installed skills could not be loaded","market":"Discoverable skills could not be loaded"}},"capabilities":{"category":"Execution and delegation","status":{"ready":"Capabilities ready","attention":"Connections need attention","partial":"Some status is unavailable","idle":"Ready when needed"},"metrics":{"builtin":"Built-in","connected":"Connected","specialists":"Experts"},"sections":{"execution":"Execution","specialists":"Specialists"},"meta":{"servers":"{{count}} servers","specialists":"{{count}} ready","connectedOf":"{{connected}} / {{count}} connected","tools":"{{count}} tools"},"execution":{"builtin":"Built-in tools","builtinDescription":"Files, Shell, Web, and workflow capabilities","mcpServices":"MCP services","mcpServicesDescription":"Connections to external systems and data","mcpTools":"MCP tools","mcpToolsDescription":"Extensions provided by connected services"},"actions":{"tools":"Open Tool Center","subagents":"Manage Subagents"},"empty":{"noneTitle":"No subagents yet","noneDescription":"Create a specialist for clearly bounded delegated work.","noneEnabledTitle":"No specialists are enabled","noneEnabledDescription":"Open Subagents to choose who can be called."},"errors":{"execution":"Execution status is temporarily unavailable","servers":"MCP status is unavailable","tools":"The tool catalog is unavailable","subagents":"Subagents are temporarily unavailable"}},"tools":{"category":"Connected capabilities","status":{"ready":"Connections healthy","attention":"Needs attention","noServers":"No MCP servers","idle":"Servers are idle"},"metrics":{"builtin":"Built-in tools","mcpTools":"MCP tools","connected":"Connected"},"sections":{"servers":"MCP connections","capabilities":"Capability map"},"meta":{"servers":"{{count}} servers"},"serverStatus":{"connected":"Connected","needsAuth":"Authorization needed","failed":"Failed","starting":"Starting","reconnecting":"Reconnecting","stopping":"Stopping","stopped":"Stopped","idle":"Idle"},"capabilities":{"files":"Files & navigation","filesDescription":"Read, edit, search, and move through files","workflow":"Planning & sessions","workflowDescription":"Plan work, interact, and manage sessions","extensions":"Extensions","extensionsDescription":"Delegated and MCP-provided capabilities"},"actions":{"open":"Open Tools"},"empty":{"serversTitle":"No MCP servers configured","serversDescription":"Open Tools to add a connected capability."},"errors":{"load":"Tools are temporarily unavailable","servers":"MCP status could not be loaded"}},"subagents":{"category":"Delegated specialists","status":{"ready":"Ready to call","empty":"No subagents","noneEnabled":"None enabled"},"metrics":{"ready":"Ready","all":"All","project":"Project"},"sections":{"ready":"Ready specialists","sources":"Sources"},"meta":{"ready":"{{count}} ready","tools":"{{count}} tools"},"sources":{"project":"Project","projectDescription":"Available in the current workspace","user":"User","userDescription":"Available across workspaces","builtin":"Built in","builtinDescription":"Maintained by Sparo"},"actions":{"open":"Open Subagents"},"empty":{"noneTitle":"No subagents yet","noneDescription":"Create a specialist for focused delegated work.","noneEnabledTitle":"No specialists are enabled","noneEnabledDescription":"Open Subagents to choose who can be called."},"errors":{"load":"Subagents are temporarily unavailable"}}},"items":{"agentic-os":{"category":"Coordination hub","description":"Coordinate tasks, call capabilities, and move work across apps and projects.","hint":"Continue global collaboration here, or start a separate session."},"workCenter":{"category":"Action surface","description":"Review running, waiting, and scheduled work.","hint":"Work state feeds directly back into the bottom-left entry."},"apps":{"category":"Action surface","description":"Open intelligent apps for the work at hand.","hint":"Apps can open independently or become the execution surface for a work item."},"files":{"category":"Global environment","description":"Browse local files, drives, and pinned folders, or open a folder as a workspace.","hint":"This is the global file-system entry, not just the current project."},"shell":{"category":"Global environment","description":"Open a shell in system or project scope.","hint":"Switch between system and project sessions after entering."},"daily-letter":{"category":"System background","description":"Review today's progress and follow-ups gathered for you in the background.","hint":"New letters appear on both the icon and the bottom-left entry."},"memory":{"category":"User trajectory","description":"Review preferences, collaboration feedback, and workspace context remembered by Agentic OS.","hint":"Memory reflects long-term collaboration, not a one-off action."},"skills":{"category":"Extended capability","description":"Manage reusable specialist knowledge and working methods.","hint":"Agents call skills automatically when they fit the task."},"capabilities":{"category":"Execution and delegation","description":"Review executable tools, connected services, and delegatable specialists together.","hint":"Tools execute; subagents take on clearly bounded work in parallel."},"tools":{"category":"Extended capability","description":"Review built-in tools and connected MCP services.","hint":"Tools extend execution boundaries and rarely need daily management."},"subagents":{"category":"Extended capability","description":"Manage specialist collaborators that top-level agents can call.","hint":"Subagents take on bounded tasks in parallel during complex work."},"settings":{"category":"System settings","description":"Manage models, permissions, appearance, and system behavior.","hint":"Changes here affect how Sparo OS operates globally."}}}}`),GD={label:"Work Dock",title:"Work",subtitle:"{{count}} in focus",searchPlaceholder:"Search work...",filterNoMatch:"No matching work",empty:"No work yet",loadFailed:"Failed to load work",retry:"Retry",pinKeepOpen:"Keep open",unpinKeepOpen:"Unpin keep-open",openWorkList:"Open work quick view",openWorkCenter:"Open work center",openWorkCenterShort:"Center",openWork:"Open work",openWorkDetails:"Work details",rowActions:"Work actions",workShort:"Work",activeWorksGroupLabel:"Focus work",runningWorksGroupLabel:"Focus work",recentWorksGroupLabel:"Recent",newWorkButton:"Start new work",createTitle:"Create Work",modeAriaLabel:"Work start mode",modeManual:"I choose",modeAgenticOs:"Delegate to OS",sentencePrefix:"Let",sentenceInfix:"work in",sentenceSuffix:".",delegatePrefix:"Let Sparo",delegateSuffix:".",objectivePlaceholder:"describe the work",objectiveRequired:"Describe the work first",agentSearchPlaceholder:"Search Product Apps",workspacePlaceholder:"Choose where this work belongs",globalScopeLabel:"Global Work",globalScopeDescription:"Not tied to a project folder",workspaceRequired:"Choose a project folder first",workspaceRequiredHint:"This Product App needs a project folder before it can start.",noOpenWorkspace:"No matching folders",browseWorkspace:"Choose folder",confirmCreate:"Start",confirmDispatch:"Delegate",createFailed:"Failed to create work",dispatchFailed:"Failed to send to Agentic OS",browseWorkspaceFailed:"Failed to choose folder",workspaceMissing:"Pick a workspace first",openFailed:"Failed to open work",cancelFailed:"Failed to cancel run",cancelRunningWork:"Cancel run",removeFailed:"Failed to remove work",removeWork:"Archive work",resultCount:"{{count}} results",executor:{systemGroup:"Built-in executors",intelligentAppGroup:"Intelligent Apps",releaseUnavailable:"This app has no active compatible Release in the selected scope.",systemBadge:"Built-in",bitfunCoder:"BitFun Coder",bitfunCoderDescription:"Coding, debugging, verification, and handoff",cowork:"Cowork Assistant",coworkDescription:"Writing, planning, and coordination",design:"Designer",designDescription:"Design and prototypes",research:"Deep Research",researchDescription:"Research and synthesis"},group:{all:"All",running:"Running",active:"Open",done:"Done"},status:{draft:"Draft",active:"Open",running:"Running",waiting_user:"Needs you",blocked:"Blocked",paused:"Paused",completed:"Completed",failed:"Failed",archived:"Archived"},kind:{"one-shot":"One shot","multi-step":"Multi-step","long-running-session":"Long-running",recurring:"Recurring",tracking:"Tracking",topic:"Topic","app-workflow":"App workflow","delegated-work":"Delegated"}},KD={aria:SD,back:xD,forward:CD,backShortcut:AD,forwardShortcut:_D,items:TD,tooltips:PD,sections:FD,collapseSessions:RD,appBuilder:ND,badges:DD,search:ID,myAgent:MD,shell:jD,sessions:ED,scheduledJobs:LD,workspaces:$D,agents:OD,skills:BD,tools:WD,actions:zD,moreOptions:UD,multimodalTools:HD,notifications:qD,menuPanel:VD,workDock:GD},QD="Remote Control",JD="Device Network",YD="Connection Setup",ZD="Connection Settings",XD="Back to Device Network",eI="Control",tI="Mobile",nI="Desktop",oI="Desktop Control",sI="Mobile Control",iI="IM Control",aI="This Computer",rI="Current Device",lI="My Phone",cI="View · Control",dI="Online · Control",uI="Waiting for phone",pI="Auxiliary Interaction",mI="Connected through phone",gI="Watch",hI="Headphones",fI="Glasses",yI="WeChat, Feishu, and other IM channels are message and command inputs",wI="Secure Connection",vI="End-to-end encrypted",bI="Connection Carrier",kI="Choose connection infrastructure to establish a secure channel",SI="Keep your phone and this computer on the same network, then scan the QR code to connect.",xI="Connect this device through an authorized ngrok tunnel.",CI="Create an end-to-end encrypted connection through the Sparo relay.",AI="Connect through a relay service that you deploy and maintain.",_I="Receive messages and commands through a Telegram Bot.",TI="Receive messages and commands through a Feishu bot.",PI="Sign in with a WeChat QR code and connect the messaging channel.",FI="Execution",RI="Data Center",NI="Execution Node",DI="One device can also control",II="Local node online · Data and execution enabled",MI="Add Windows node",jI="Add Linux node",EI="Windows Node",LI="Linux Node",$I="Ready to add",OI="Add",BI="Multiple Windows, macOS, and Linux nodes can execute concurrently",WI="1 primary node online · End-to-end encrypted",zI="2 primary nodes online · End-to-end encrypted",UI="Scan QR Code",HI="Connect New Device",qI="Distributed Execution",VI="Distributed execution is not available yet.",GI="Auxiliary Devices",KI="Auxiliary device support is not available yet.",QI="Got it",JI="LAN",YI="Sparo Relay",ZI="NAT Traversal",XI="Self-Hosted",eM="IM Control",tM="Connection Carrier",nM="IM Control",oM="Connect",sM="Connecting...",iM="Disconnect",aM="Cancel",rM="Scan the QR code with your phone to connect",lM="Send the pairing code to the bot to complete pairing",cM="Mobile device connected. You can close this dialog.",dM="User ID",uM="View ngrok tunnel usage & status.",pM="Server URL",mM="Current IP",gM="Gateway IP",hM="Feishu",fM="Open Bot",yM="Ready",wM="Waiting for connection...",vM="URL Copied",bM="Waiting for bot confirmation...",kM="Handshaking...",SM="Verifying...",xM="Connected",CM="Disconnected",AM="Connect via local network. Both devices must be on the same LAN/WiFi. If connection fails, check router security settings (such as AP/client isolation) and make sure proxy/tunneling settings do not route or block LAN traffic (allow direct LAN access) on both devices.",_M="Connect via Sparo OS relay server. The server is currently self-hosted by the Sparo OS team and is mainly provided for convenient trials and feature evaluation. Although message payloads are protected with end-to-end encryption, the relay service and related infrastructure may still observe necessary metadata, and any public-facing service can introduce information security or data leakage risks due to misconfiguration, log exposure, operational mistakes, or attacks. For long-term use, production environments, or higher-security scenarios, we strongly recommend using a self-hosted server under your own deployment and operational control.",TM="Connect via ngrok tunnel. For first-time use, just install ngrok and configure auth token. No need to start ngrok manually.",PM="Connect via ngrok tunnel. First-time use need to ",FM="install ngrok",RM=" and configure auth token. No need to start ngrok manually.",NM="Connect via your own self-hosted relay server.",DM="Connect via your own ",IM="self-hosted relay server",MM=".",jM="Connect via Feishu, Telegram, or WeChat (iLink) bot. Complete the setup for your chosen channel below.",EM="Open Telegram and search for @BotFather",LM="Send /newbot and follow the prompts to create a bot",$M="Copy the Bot Token and paste it below",OM="View the ",BM="full Feishu bot setup guide",WM="",zM="Go to ",UM="Feishu Open Platform",HM=" and create a Custom App",qM="Enable Bot capability and configure Permissions & Scopes and Events & Callbacks",VM="Copy App ID and App Secret below",GM="WeChat",KM="Uses Tencent WeChat iLink. Sign in with WeChat QR first, then send the 6-digit pairing code like other IM bots.",QM="Tap the button below to show a QR code, scan it with WeChat, and confirm on your phone.",JM="After you confirm login in WeChat, Sparo OS will show the 6-digit pairing code automatically; open the bot chat in WeChat and send that code.",YM="Show WeChat login QR",ZM="Cancel QR login",XM="Scanned. Please confirm login in WeChat; the pairing code will appear here automatically.",ej="WeChat is linked. If pairing does not start automatically, tap Connect to retry.",tj="Waiting for scan…",nj="Verbose Mode",oj="Concise Mode",sj="Open ngrok setup page",ij="Remote Connect Disclaimer",aj="Before enabling Remote Connect, please read and accept the following:",rj="Remote Connect may contain undiscovered security vulnerabilities, functional defects, or incompatible changes. Please use it with full awareness of the risks.",lj="Remote Connect enables network communication paths (including but not limited to LAN, third-party relay, self-hosted relay, bot channels, and other pathways). Use it only on trusted devices and networks.",cj="Remote message payloads are protected with end-to-end encryption (X25519 ECDH + AES-256-GCM with ephemeral key pairs per session); relay servers cannot decrypt message content. However, required metadata (such as device name, connection state, service endpoint, and other connection-context details) is not covered by business-message encryption and may still be visible to network paths, service nodes, or other infrastructure.",dj="Sparo OS's Remote Connect encryption implementation is fully open-source. You are free to audit the source code to verify its security.",uj="Do not transmit sensitive content in untrusted environments. Bot platforms, third-party networks, host logging policies, and other external service practices may affect your exposure surface.",pj="Sparo OS does not use your Remote Connect message content for model training or commercial data exploitation. Third-party services you choose to use (such as ngrok, Telegram, Feishu, self-hosted infrastructure tooling, and other integrations) may process data under their own terms.",mj="For ngrok, self-hosted relay, Telegram/Feishu bot modes, and other integration pathways, you are responsible for protecting URLs, tokens, app IDs, app secrets, keys, and other credentials. Credential leakage can cause unauthorized access or other security incidents.",gj="QR codes contain connection details including relay address, room ID, public key, and other session identifiers. Do not share screenshots, recordings, or displays of these codes with unrelated parties.",hj="When using ngrok or other third-party tunneling providers, traffic passes through external service links. You should evaluate account security, jurisdiction/compliance constraints, quota limits, service availability, and potential intermediary-link risks.",fj="When using a self-hosted relay, you are responsible for host/container security (including but not limited to patching, access control, TLS certificates, port exposure, firewall rules, DDoS/brute-force protection, audit logging, backup/recovery, and other operational safeguards). A compromised or misconfigured server, leaked keys, or other operational failures may lead to service disruption, data leakage, or tampering risks.",yj="Connectivity and stability may be affected by firewall rules, router isolation policies (e.g., AP/client isolation), proxy/tunneling settings, and other network-control policies.",wj="In bot mode, pairing codes are for current-session binding only. Do not share them with unrelated parties. Other bot-platform behaviors or policy changes may also affect security and availability.",vj="Bot pairing details are persisted on the local disk to enable automatic reconnection after restart. If your machine is accessed by unauthorized individuals, compromised by malware, or affected by other system-security incidents, this information could be exploited.",bj="The mobile client loads as a web application in a browser. Browser cache, local storage, page screenshots, system clipboard, and other browser/system features may introduce additional information exposure risks.",kj="Some countries or regions have legal restrictions on encrypted communication, tunneling services, cross-border data transfer, and related activities. Please evaluate compliance with your local laws and regulations, including potential policy changes.",Sj="Any risks, losses, disputes, or other adverse consequences arising during your use of Remote Connect (including but not limited to data leakage, service interruption, account anomalies, or service unavailability) are your responsibility; Sparo OS is not liable for resulting issues.",xj="View disclaimer",Cj="Agreed",Aj="Not agreed",_j="Decline",Tj="Agree and Continue",Pj={title:QD,networkTitle:JD,setupTitle:YD,connectionSettings:ZD,backToNetwork:XD,controlLayer:eI,mobileEndpoint:tI,desktopEndpoint:nI,desktopControl:oI,mobileControl:sI,imControl:iI,thisComputer:aI,currentDevice:rI,myPhone:lI,canViewControl:cI,onlineControl:dI,waitingForPhone:uI,auxiliaryInteraction:pI,throughPhone:mI,watch:gI,headphones:hI,glasses:fI,messageCommandEntry:yI,secureConnection:wI,endToEndEncrypted:vI,transportMethod:bI,transportHint:kI,setupSummaryLan:SI,setupSummaryNgrok:xI,setupSummarySparoServer:CI,setupSummaryCustomServer:AI,setupSummaryTelegram:_I,setupSummaryFeishu:TI,setupSummaryWeixin:PI,executionDataNodes:FI,dataCenter:RI,executionNode:NI,sameDeviceCanControl:DI,localNodeRunning:II,windowsNodePlaceholder:MI,linuxNodePlaceholder:jI,windowsNode:EI,linuxNode:LI,readyToAdd:$I,add:OI,concurrentExecutionHint:BI,nodeSummary:WI,nodeSummaryConnected:zI,scanQr:UI,connectNewDevice:HI,distributedExecutionTitle:qI,distributedExecutionUnavailable:VI,auxiliaryDevicesTitle:GI,auxiliaryDevicesUnavailable:KI,gotIt:QI,tabLan:JI,tabSparoServer:YI,tabNgrok:ZI,tabCustomServer:XI,tabBot:eM,groupNetwork:tM,groupBot:nM,connect:oM,connecting:sM,disconnect:iM,cancel:aM,scanHint:rM,botHint:lM,connectedHint:cM,connectedUserId:dM,ngrokUsageLink:uM,serverUrl:pM,currentIp:mM,gatewayIp:gM,feishu:hM,openBot:fM,stateIdle:yM,stateWaiting:wM,urlCopied:vM,stateWaitingBot:bM,stateHandshaking:kM,stateVerifying:SM,stateConnected:xM,stateDisconnected:CM,desc_lan:AM,desc_sparo_server:_M,desc_ngrok:TM,desc_ngrok_prefix:PM,desc_ngrok_link:FM,desc_ngrok_suffix:RM,desc_custom_server:NM,desc_custom_server_prefix:DM,desc_custom_server_link:IM,desc_custom_server_suffix:MM,desc_bot:jM,botTgStep1:EM,botTgStep2:LM,botTgStep3:$M,botFeishuDocPrefix:OM,botFeishuDocLink:BM,botFeishuDocSuffix:WM,botFeishuStep1Prefix:zM,botFeishuOpenPlatform:UM,botFeishuStep1Suffix:HM,botFeishuStep2:qM,botFeishuStep3:VM,weixin:GM,botWeixinIntro:KM,botWeixinStep1:QM,botWeixinStep2:JM,botWeixinQrButton:YM,botWeixinQrCancel:ZM,botWeixinAwaitingPhoneConfirm:XM,botWeixinLinked:ej,botWeixinPolling:tj,botVerboseMode:nj,botConciseMode:oj,openNgrokSetup:sj,disclaimerTitle:ij,disclaimerIntro:aj,disclaimerItemGeneralRisk:rj,disclaimerItemSecurity:lj,disclaimerItemEncryption:cj,disclaimerItemOpenSource:dj,disclaimerItemPrivacy:uj,disclaimerItemDataUsage:pj,disclaimerItemCredentials:mj,disclaimerItemQrCode:gj,disclaimerItemNgrok:hj,disclaimerItemSelfHosted:fj,disclaimerItemNetwork:yj,disclaimerItemBot:wj,disclaimerItemBotPersistence:vj,disclaimerItemMobileBrowser:bj,disclaimerItemCompliance:kj,disclaimerItemLiability:Sj,disclaimerReview:xj,disclaimerStatusAgreed:Cj,disclaimerStatusPending:Aj,disclaimerDecline:_j,disclaimerAgree:Tj},Fj={title:"Editor",openFile:"Open File",saveFile:"Save File",saveAs:"Save As",closeFile:"Close File",closeAll:"Close All",undo:"Undo",redo:"Redo",find:"Find",replace:"Replace",findInFiles:"Find in Files",goToLine:"Go to Line",goToSymbol:"Go to Symbol",format:"Format",formatSelection:"Format Selection",comment:"Toggle Comment",fold:"Fold",unfold:"Unfold",foldAll:"Fold All",unfoldAll:"Unfold All",wordWrap:"Word Wrap",minimap:"Minimap",breadcrumbs:"Breadcrumbs",lineNumbers:"Line Numbers",whitespace:"Whitespace",encoding:"Encoding",lineEnding:"Line Ending",language:"Language Mode",common:{retry:"Retry",loading:"Loading...",loadFailed:"Load failed",fileNotFound:"File not found",permissionDenied:"Permission denied",networkError:"Network error",saveFailedWithMessage:"Failed to save file: {{message}}",save:"Save",cancel:"Cancel",edit:"Edit",add:"Add",delete:"Delete"},codeEditor:{loadingFile:"Loading file...",saving:"Saving...",initFailedWithMessage:"Failed to initialize editor: {{message}}",externalModifiedConfirm:`This file was modified by another program. + +You have unsaved changes. Discard them and reload the file?`,externalModifiedTitle:"File changed on disk",externalModifiedDetail:"The file's metadata on disk (modified time / size) no longer matches the version this editor is based on. You have unsaved local changes. Reloading will discard them.",discardAndReload:"Discard and reload",keepLocalEdits:"Keep my edits",saveConflictTitle:"Save conflict",saveConflictDetail:"The file on disk was modified by another program before save. Overwrite the file with your editor content, or discard local changes and reload from disk.",overwriteSave:"Overwrite",reloadFromDisk:"Reload from disk",unsupportedBinaryTitle:"Unsupported file type",unsupportedBinaryMessage:"This file type cannot be opened in the editor, so Sparo OS did not load it. Use an external app to inspect it.",unsupportedBinaryMessageWithSize:"This {{size}} file type cannot be opened in the editor, so Sparo OS did not load it. Use an external app to inspect it."},diffEditor:{loading:"Loading diff editor...",openFailed:"Failed to open",initFailedWithMessage:"Failed to initialize diff editor: {{message}}",changesCount:"({{count}} changes)",prevChange:"Previous change (Alt+↑ / Shift+F7)",nextChange:"Next change (Alt+↓ / F7)",switchToInline:"Switch to inline view",switchToSideBySide:"Switch to side-by-side view"},imageViewer:{filePathEmpty:"File path is empty",loadImageFailedWithMessage:"Failed to load image: {{message}}",decodeFailed:"Failed to load image: the browser couldn't decode the image data",zoomOut:"Zoom out (Ctrl + -)",zoomReset:"Reset zoom (Ctrl + 0)",zoomIn:"Zoom in (Ctrl + +)",rotate90:"Rotate 90°",download:"Download image",enterFullscreen:"Enter fullscreen",exitFullscreen:"Exit fullscreen",imageUrlEmpty:"Image URL is empty"},statusBar:{readOnly:"Read Only",goToLine:"Go to Line",indentSettings:"Indent Settings",fileEncoding:"File Encoding",selectLanguageMode:"Select Language Mode",lspConnected:"LSP Connected",lspConnecting:"LSP Connecting...",lspDisconnected:"LSP Disconnected",selectionLinesChars:"{{lines}} lines, {{chars}} chars",selectionChars:"{{count}} selected",ln:"Ln",col:"Col",indentSpaces:"Spaces: {{n}}",indentTab:"Tab: {{n}}",goToLineHint:"Line or Line:Col (Enter to go, Esc to close)",goToLinePlaceholder:"e.g. 10 or 10:5",selectIndent:"Select Indent",selectEncoding:"Select Encoding",selectLanguageModeHint:"Select Language Mode (click to switch)",indentOptionSpaces:"Spaces: {{n}}",indentOptionTab:"Tab: {{n}}"}},Rj={title:"Terminal",new:"New Terminal",split:"Split Terminal",kill:"Kill",clear:"Clear",scrollToBottom:"Scroll to Bottom",copySelection:"Copy Selection",paste:"Paste",selectAll:"Select All",find:"Find",shell:"Shell",workingDirectory:"Working Directory",runCommand:"Run Command",commandHistory:"Command History"},Nj={title:"Git",repository:"Repository",branch:"Branch",branches:"Branches",checkout:"Checkout",newBranch:"New Branch",deleteBranch:"Delete Branch",merge:"Merge",rebase:"Rebase",commit:"Commit",commitMessage:"Commit Message",stage:"Stage",unstage:"Unstage",stageAll:"Stage All",unstageAll:"Unstage All",discard:"Discard Changes",discardAll:"Discard All Changes",push:"Push",pull:"Pull",fetch:"Fetch",remote:"Remote",remotes:"Remotes",stash:"Stash",stashList:"Stash List",stashApply:"Apply Stash",stashPop:"Pop Stash",stashDrop:"Drop Stash",log:"Commit History",diff:"Diff",blame:"Blame",tags:"Tags",status:{modified:"Modified",added:"Added",deleted:"Deleted",renamed:"Renamed",untracked:"Untracked",staged:"Staged",conflict:"Conflict",unknown:"Unknown"},statusDescription:{untracked:"New file, not yet added to Git",modified:"Modified but not staged",added:"New file staged",deleted:"File deleted",renamed:"File renamed",conflicted:"File has merge conflicts",staged:"Changes staged, ready to commit",unknown:"Unknown status"},actions:{sync:"Sync",refresh:"Refresh",viewHistory:"View History",viewChanges:"View Changes",resolveConflict:"Resolve Conflict"}},Dj={referencesPanel:{previewFallback:"(no preview)",emptyTitle:"No references found",emptyWithSymbol:'No references found for symbol "{{symbol}}"',emptyDescription:"No references found",titleWithSymbol:'References for "{{symbol}}"',title:"References",emptyLine:"(empty line)"},errors:{loadPluginsFailed:"Failed to load plugins",installPluginFailed:"Failed to install plugin",uninstallPluginFailed:"Failed to uninstall plugin",initializeFailed:"Failed to initialize LSP"}},Ij={title:"File Explorer",empty:"No files",emptyFiltered:"No matching files found",draggingFile:"File: {{name}}",newFile:"New File",newFolder:"New Folder",rename:"Rename",delete:"Delete",refresh:"Refresh",collapse:"Collapse All",expand:"Expand All",filter:"Filter Files",showHidden:"Show Hidden Files",sortBy:"Sort By",sortByName:"By Name",sortByModified:"By Modified",sortBySize:"By Size",sortByType:"By Type",compressionTooltip:`Compressed path: {{compressed}} +Full path: {{full}}`,errors:{loadTreeFailed:"Failed to load file tree",loadTreeFailedWithMessage:"Failed to load file tree: {{message}}"}},Mj={title:"Search",placeholder:"Search...",searchFiles:"Search Files",searchContent:"Search Content",searchSymbols:"Search Symbols",matchCase:"Match Case",matchWholeWord:"Match Whole Word",useRegex:"Use Regular Expression",includeFiles:"Include Files",excludeFiles:"Exclude Files",results:"Search Results",noResults:"No Results",noResultsHint:"Try refining your query or check spelling",expand:"Expand",collapse:"Collapse",resultsSummary:"Found {{files}} files with {{matches}} matches",resultsShowing:" (showing first {{count}})",loadMore:"Load more ({{count}})",replace:"Replace",replaceAll:"Replace All",global:{placeholder:"Search files and content...",placeholderDisabled:"Open a workspace first",phaseFilename:"Searching filenames...",phaseContent:"Searching content...",resultsFound:"Found {{count}} results",resultsShowing:" (showing {{count}})",loadMore:"Load more ({{count}} results)",resultsTruncatedFiles:"Showing the first {{count}} file matches.",resultsTruncatedContent:"Showing the first {{count}} content matches.",lineNumberPrefix:"Line {{line}}: "}},jj={title:"Snapshot",create:"Create Snapshot",restore:"Restore Snapshot",delete:"Delete Snapshot",compare:"Compare Snapshots",list:"Snapshot List",name:"Snapshot Name",description:"Snapshot Description",createdAt:"Created At",auto:"Auto Snapshot",manual:"Manual Snapshot"},Ej={title:"Visualization",mermaid:"Mermaid Diagram",zoom:"Zoom",zoomIn:"Zoom In",zoomOut:"Zoom Out",fitView:"Fit View",center:"Center",export:"Export Image",layout:"Layout"},Lj={editor:{loadingFile:"Loading file...",placeholder:"Start writing Markdown...",emptyPreview:"This file is empty for now. Press Space to start AI collaboration.",source:"Source",markdown:"Markdown",livePreview:"Live preview",preview:"Preview",moreMenu:"More",centeredLayout:"Centered layout",documentSections:"Document sections",viewModeLabel:"Markdown editor mode",exportHtml:"Export HTML",exportPdf:"Export PDF",exportSaveTitleHtml:"Export Markdown as HTML",exportSaveTitlePdf:"Export Markdown as PDF",exportedHtml:"HTML exported to {{path}}",exportedPdf:"PDF exported to {{path}}",exportFailed:"Export failed: {{message}}",revealExport:"Show in folder",exportNeedsDesktop:"Markdown export is available in the desktop app.",notice:{sourcePreviewFallback:"This document contains content that cannot be safely represented in visual mode. Edit in source mode or switch to preview."}},planViewer:{loadingPlan:"Loading plan...",unsaved:"Unsaved",build:"Build",built:"Built",building:"Building...",remainingTodos:"{{count}} Remaining To-dos",toggleYamlEditOn:"Edit YAML",toggleYamlEditOff:"Close editor",yamlPlaceholder:"YAML frontmatter...",contentPlaceholder:"Plan content...",buildPlanTitle:"Build Plan: {{name}}"},tiptap:{placeholder:"Enter Markdown...",toolbarPlaceholder:"Toolbar",mermaidRendering:"Rendering Mermaid diagram...",mermaidRenderFailed:"Mermaid Render Failed",mermaidRenderFailedWithMessage:"Render failed: {{message}}",unknownError:"Unknown error",localImageAltLoadFailedWithSrc:"Failed to load image: {{src}}",localImageTitleUnableToLoadWithPath:"Unable to load: {{path}}",localImageLoading:"Loading image...",localImageFailed:"Image failed to load",outline:{label:"Document sections",title:"Sections"},rawHtml:{inlineLabel:"HTML",preview:"Preview",sandbox:"Sandbox",source:"Source",editSource:"Edit source",html:"HTML",details:"Details",frontmatter:"Frontmatter",footnote:"Footnote",markdown:"Markdown"},details:{summaryPlaceholder:"Summary"},tableQuickInsert:{insertColumn:"Insert column",insertRow:"Insert row"},insertLinkTextPlaceholder:"Link text",inlineAi:{triggerHint:"Press Space to use AI",askMode:"Ask AI",continueMode:"Continue Writing",askPlaceholder:"Ask AI anything...",continuePlaceholder:"Add a direction for the continuation...",currentPage:"Current Page",suggestionSection:"Suggestions",summaryAction:"Add Summary",todoAction:"Add Todo List",summaryDirection:"Insert a short summary at the current position that captures the key points above while keeping the current document language and style.",todoDirection:"Insert a concise Markdown todo list at the current position that extracts the next action items while keeping the current document language and style.",thinkSection:"Think, Ask, Discuss",cancel:"Cancel",working:"Working...",askSubmit:"Send to AI",continueSubmit:"Continue",accept:"Accept",reject:"Discard",previewTitle:"AI Preview",previewStreaming:"Streaming",previewReady:"Ready to insert",workspaceRequired:"Please open a workspace before using AI assist.",askEmpty:"Please enter a question for AI.",askSent:"Question sent to the AI workspace session.",askFailed:"Failed to send question.",continueInserted:"AI continuation inserted.",continueEmptyResult:"AI returned empty content or the insertion point is no longer available.",continueFailed:"AI continuation failed.",continueStartFailed:"Failed to start AI continuation.",tempSessionName:"Markdown Inline Continue"},coauthor:{barLabel:"Co-author",actionPlaceholder:"Choose action",promptPlaceholder:"Optional direction",apply:"Apply",review:"Review",run:"Propose edits",acceptAll:"Accept all",rejectAll:"Reject all",retry:"Retry",stale:"Source changed",selectionUnresolved:"Could not safely locate the selected Markdown.",comments:"Comments",profileOn:"Profile enabled",profileOff:"Profile disabled",failed:"Co-author request failed.",applied:"Co-author proposal applied.",polishSelection:"Polish",reviewSelection:"Review",selectionAnchor:"Ask Sparo to rewrite this selection",selectionPromptPlaceholder:"Tell Sparo how to rewrite this selection",selectionSubmit:"Rewrite selection",selectionClose:"Close selection rewrite",acceptOp:"Accept change",rejectOp:"Reject change",acceptShort:"Accept",rejectShort:"Cancel",acceptHunk:"Accept hunk",rejectHunk:"Reject hunk",proposed:"Proposed change",streamingRewrite:"Writing in place...",commentPin:"Co-author comment"},shortcuts:{undo:"Undo",redo:"Redo",save:"Save",escape:"Exit editing",indent:"Indent",outdent:"Outdent",bold:"Bold",italic:"Italic",link:"Insert link",newBlock:"New block"}}},$j={editor:Fj,terminal:Rj,git:Nj,lsp:Dj,fileTree:Ij,search:Mj,snapshot:jj,visualization:Ej,markdown:Lj},Oj="Show Window",Bj="Hide Window",Wj="New Session",zj="Recent Sessions",Uj="No sessions",Hj="Quit",qj="Sparo OS v{{version}}",Vj="Sparo OS is running in the system tray. Right-click the tray icon to open the menu.",Gj="Confirm Quit",Kj="{{count}} Agent task(s) are running. Are you sure you want to quit?",Qj={showWindow:Oj,hideWindow:Bj,newSession:Wj,recentSessions:zj,noSessions:Uj,quit:Hj,version:qj,trayHint:Vj,quitConfirmTitle:Gj,quitConfirmMessage:Kj},Jj={name:"Sparo OS",version:"版本",loading:"加载中...",welcome:"欢迎使用 Sparo OS"},Yj={general:{name:"通用助手",description:"通用 AI 助手,可以回答各种问题"},runno:{name:"Runno",description:"系统原生通用执行 Agent,覆盖规划、自动化、实现与验证"},coder:{name:"BitFun Coder",description:"面向实现、调试、自动化、验证和交付的软件工程 Product App"},bitfunCoder:{name:"BitFun Coder",description:"面向实现、调试、自动化、验证和交付的软件工程 Product App"},projectQa:{name:"项目问答助手",description:"专注于项目问答与代码库探索的助手"},requirementClarification:{name:"需求澄清助手",description:"专注于澄清需求并收集细节的助手"},core:{name:"核心助手",description:"用于通用任务与协调的核心助手"}},Zj={initializing:"正在初始化核心系统..."},Xj={clarificationItemTitle:"澄清项 {{index}}",clarificationItemProcessed:"已处理",clarificationBatchCompleted:"批量澄清处理完成"},eE={minimize:"最小化",maximize:"最大化",restore:"还原",close:"关闭"},tE={title:"新建工作区",subtitle:"创建一个新的工作区目录",parentDirectory:"父目录",parentDirectoryPlaceholder:"点击右侧按钮选择父目录",selectParentDirectory:"选择新工作区的父目录位置",select:"选择",projectName:"工作区名称",projectNamePlaceholder:"请输入工作区名称,例如:my-project",fullPath:"完整路径",cancel:"取消",create:"创建",creating:"创建中...",errorSelectParent:"请选择父目录",errorEnterName:"请输入工作区名称",errorCreateFailed:"创建工作区失败"},nE={productTitle:"Sparo OS",tagline:"面向智能应用的 Agentic OS",close:"关闭",copy:"复制",copyDiagnostics:"复制构建信息",copied:"已复制",version:"v{{version}}",specSheetTitle:"构建信息",buildDate:"构建",commit:"提交",branch:"分支",links:{repository:"查看源码",documentation:"文档",issues:"反馈问题"},licenseLabel:"{{type}} 许可证",copyright:"© 2026 Sparo OS 开发团队。保留所有权利。"},oE={confirm:"确认",cancel:"取消",save:"保存",delete:"删除",edit:"编辑",create:"创建",new:"新建",add:"添加",remove:"移除",close:"关闭",open:"打开",copy:"复制",paste:"粘贴",cut:"剪切",undo:"撤销",redo:"重做",refresh:"刷新",reload:"重新加载",search:"搜索",filter:"筛选",sort:"排序",export:"导出",import:"导入",download:"下载",upload:"上传",submit:"提交",reset:"重置",clear:"清空",select:"选择",selectAll:"全选",deselectAll:"取消全选",expand:"展开",collapse:"收起",more:"更多",less:"收起",yes:"是",no:"否",ok:"确定",apply:"应用",back:"返回",next:"下一步",previous:"上一步",finish:"完成",skip:"跳过",retry:"重试",continue:"继续",stop:"停止",pause:"暂停",resume:"恢复",start:"开始",end:"结束"},sE={descriptions:{copy:"将选中的内容复制到剪贴板",cut:"将选中的内容剪切到剪贴板",paste:"从剪贴板粘贴内容",selectAll:"选择所有内容",refresh:"刷新当前内容",delete:"删除文件或文件夹",copyPath:"复制文件或文件夹的完整路径",copyRelativePath:"复制相对于工作区的路径"},status:{copySuccess:"已复制到剪贴板",cutSuccess:"已剪切到剪贴板",pasteSuccess:"已粘贴",selectAllSuccess:"已全选",refreshTriggered:"已触发刷新",deleteSuccess:"已删除",copyPathSuccess:"已复制路径到剪贴板",copyRelativePathSuccess:"已复制相对路径到剪贴板"},confirmDeleteFile:'确定要删除文件 "{{name}}" 吗?',confirmDeleteFolder:'确定要删除文件夹 "{{name}}" 及其所有内容吗?',selectionMenu:{name:"文本选择菜单",description:"提供文本选择相关的操作"},terminalMenu:{name:"终端菜单",description:"提供终端相关的操作",clearTerminal:"清空终端"},editorMenu:{name:"编辑器菜单",description:"提供编辑器相关的操作"},fileExplorerMenu:{name:"文件浏览器菜单",description:"提供文件和文件夹操作"},flowChatMenu:{name:"FlowChat菜单",description:"提供FlowChat对话相关的操作"},notificationMenu:{name:"通知菜单",description:"通知中心的右键菜单",items:{copyTitle:"复制标题",copyMessage:"复制内容",copyAll:"复制全部"}},globalMenu:{name:"全局菜单",description:"提供全局通用的菜单项"},projectContextDocumentMenu:{name:"工程上下文文档菜单",description:"提供工程上下文文档的删除操作"}},iE={loading:"加载中",saving:"保存中",saved:"已保存",unsaved:"未保存",success:"成功",error:"错误",warning:"警告",info:"信息",pending:"等待中",processing:"处理中",completed:"已完成",failed:"失败",cancelled:"已取消",interrupted:"已中断",active:"活动",inactive:"非活动",enabled:"已启用",disabled:"已禁用",online:"在线",offline:"离线",connected:"已连接",disconnected:"已断开",ready:"就绪",notReady:"未就绪"},aE={validationSuccess:{checkbox:"设置正确",input:"输入正确",select:"选择正确"}},rE={now:"现在",today:"今天",yesterday:"昨天",tomorrow:"明天",thisWeek:"本周",lastWeek:"上周",nextWeek:"下周",thisMonth:"本月",lastMonth:"上月",nextMonth:"下月",thisYear:"今年",lastYear:"去年",nextYear:"明年",second:"秒",seconds:"秒",minute:"分钟",minutes:"分钟",hour:"小时",hours:"小时",day:"天",days:"天",week:"周",weeks:"周",month:"月",months:"月",year:"年",years:"年",ago:"前",later:"后",just_now:"刚刚",minutesAgo:"{{count}} 分钟前",hoursAgo:"{{count}} 小时前",daysAgo:"{{count}} 天前",monthsAgo:"{{count}} 个月前",yearsAgo:"{{count}} 年前"},lE={file:"文件",files:"文件",folder:"文件夹",folders:"文件夹",newFile:"新建文件",newFolder:"新建文件夹",rename:"重命名",delete:"删除",copy:"复制",cut:"剪切",paste:"粘贴",duplicate:"复制副本",move:"移动",openWith:"打开方式",reveal:"在资源管理器中显示",copyPath:"复制路径",copyRelativePath:"复制相对路径",download:"下载",downloadSaveTitle:"保存文件",transferNeedsDesktop:"上传与下载仅适用于桌面版应用。",newFileDescription:"在当前文件夹中创建新文件",newFolderDescription:"在当前文件夹中创建新文件夹",renameDescription:"重命名文件或文件夹",revealDescription:"在系统文件管理器中打开此位置",createFileSuccess:"创建新文件",createFolderSuccess:"创建新文件夹",renameStarted:"开始重命名",revealOpening:"正在打开文件管理器",compressedPathTooltip:`压缩路径: {{compressed}} +完整路径: {{full}}`},cE={formatDocument:"格式化文档",goToDefinition:"转到定义",goToTypeDefinition:"查看类型定义",findAllReferences:"查找所有引用",renameSymbol:"重命名符号",quickFix:"快速修复...",goToSymbol:"转到符号...",highlightAllOccurrences:"高亮所有出现位置",addToChat:"添加到聊天"},dE={delete:"删除文档"},uE={noData:"暂无数据",noResults:"无结果",noFiles:"暂无文件",noContent:"暂无内容"},pE={required:"此字段为必填项",invalid:"输入无效",tooShort:"输入过短",tooLong:"输入过长",invalidEmail:"邮箱格式无效",invalidUrl:"URL 格式无效",invalidNumber:"数字格式无效",minLength:"最少 {{min}} 个字符",maxLength:"最多 {{max}} 个字符",minValue:"最小值为 {{min}}",maxValue:"最大值为 {{max}}",password:{minLength:"密码长度至少 {{min}} 位",lowercase:"至少包含一个小写字母",uppercase:"至少包含一个大写字母",number:"至少包含一个数字",specialCharSuggested:"建议包含特殊字符"}},mE={subtitle:"Hi,今天我能帮你做什么?",greetingMorning:"早上好,准备好开始今天的工作了吗?",greetingAfternoon:"下午好,让我们继续推进吧",greetingEvening:"晚上好,有什么我能帮到你的?",continueLastWork:"继续我们的工作",openFolder:"开始新任务",selecting:"正在选择...",recentlyOpened:"最近的项目",projects:"个项目",collapse:"收起",showMore:"查看更多 ({{count}} 个)",noProjectsYet:"还没有打开过项目",startYourJourney:"选择一个项目目录,我来帮你",selectWorkspaceDirectory:"选择项目目录",pathNotExist:"路径不存在",invalidWorkspacePath:"工作区路径无效或为空",daysAgo:"{{count}} 天前",weeksAgo:"{{count}} 周前",unknownTime:"未知时间"},gE={configCenter:"配置中心",diff:"Diff",fixPreview:"修复预览",gitDiff:"Git Diff",gitSettings:"Git 设置",taskPlanner:"任务规划器",fileBrowser:"文件浏览器",editor:"编辑器",markdown:"Markdown",mermaidChart:"Mermaid 图表",settings:"设置",settingsWithSection:"设置 - {{section}}"},hE={greetingMorning:"早安,创造者",greetingAfternoon:"欢迎回来,一起开工",greetingEvening:"傍晚好,创造者",greetingNight:"深夜问好,代码诗人",subtitleMorning:"「新的一天,新的可能,让我们一起创造些什么」",subtitleAfternoon:"「在这里,AI 不是工具,而是你的智能伙伴,思维如水般流动,创意瞬间成为现实」",subtitleEvening:"「黄金编码时间,让灵感在夜幕中绽放」",subtitleNight:"「夜深人静,正是创造的时刻,Where AI meets IDE, Magic happens」",featureIntro:"我可以帮你读懂复杂代码,快速实现新功能,重构老旧项目,或是解决那些让人头疼的 Bug...",featureIntroCowork:"我可以帮你整理桌面,搜集资料和制作PPT、PDF文档等等...",lastTimeYouWere:"我记得你上次离开时在...",branch:"分支:",aheadCommits:"领先 {{count}} 个提交",behindCommits:"落后 {{count}} 个提交",unstagedFiles:"未暂存 {{count}} 个文件",stagedFiles:"已暂存 {{count}} 个文件",unpushedCommits:"未推送 {{count}} 个提交",timeSinceLastCommit:"距离上次提交:",youMightWant:"接下来你可能想...",defaultAction1:"查看当前的代码修改",defaultAction1Command:"查看我当前修改了哪些文件",defaultAction2:"继续上次的开发工作",defaultAction2Command:"帮我继续写代码",defaultAction3:"提交当前的更改",defaultAction3Command:"帮我提交代码"},fE={aiAgent:"会话",terminal:"终端",git:"Git",settings:"设置",fileViewer:"文件",fileViewerCollapseNav:"收起文件导航",fileViewerExpandNav:"展开文件导航",memory:"记忆",projectContext:"项目概况",apps:"应用",subagents:"子代理",skills:"技能",tools:"工具箱",mermaidEditor:"Mermaid 图表",shell:"终端",panelView:"面板视图",workCenter:"工作中心",dailyLetter:"今日来信"},yE={returnToAgenticOS:"返回 Agentic OS"},wE={scenes:"正在加载场景"},vE={remote:{title:"远程 SSH",connect:"连接远程工作区",connecting:"连接中...",connected:"已连接",disconnect:"断开连接",savedConnections:"已保存的连接",sshConfigHosts:"SSH 配置",fillForm:"使用",newConnection:"新建连接",host:"主机地址",port:"端口",username:"用户名",connectionName:"连接名称",connectionNamePlaceholder:"留空自动生成",authMethod:"认证方式",password:"密码",privateKey:"私钥",privateKeyPath:"私钥路径",browsePrivateKey:"选择私钥文件",pickPrivateKeyDialogTitle:"选择 SSH 私钥",passphrase:"密码短语",passphraseOptional:"留空表示无密码短语",homeFolder:"主目录",clickToEditPath:"点击编辑路径",selectWorkspace:"选择工作区目录",openWorkspace:"打开为工作区",selected:"已选择",clickToSelect:"点击选择一个目录",name:"名称",size:"大小",modified:"修改时间",emptyDirectory:"目录为空",hostRequired:"主机地址不能为空",usernameRequired:"用户名不能为空",portInvalid:"端口必须是 1-65535 之间的数字",passwordRequired:"密码不能为空",keyPathRequired:"私钥路径不能为空",enterPassword:"请输入密码",enterKeyPath:"请输入私钥路径",keyPathDescription:"输入私钥文件路径",authPromptTitle:"SSH 认证",disconnectConfirm:"确定要断开连接吗?",disconnectWorkspaceConfirm:"确定要关闭远程工作区吗?这将断开与远程服务器的连接。",newFile:"新建文件",newFolder:"新建文件夹",delete:"删除",deleteTitle:"确认删除",deleteConfirm:"确定要删除此文件/文件夹吗?此操作无法撤销。",rename:"重命名",upload:"上传到远程",download:"下载到本地",uploadDialogTitle:"选择要上传的文件",downloadDialogTitle:"保存文件",transferFailed:"传输失败",transferNeedsDesktop:"上传与下载仅适用于桌面版应用。",transferring:"正在传输…"}},bE={dialogCompleted:"AI 助手已完成任务。"},kE={classify:{label:"分类",immediate:"即时事项",topic:"Topic",tracking:"长期跟踪",recurring:"周期事项"}},SE={app:Jj,agents:Yj,core:Zj,agentService:Xj,window:eE,newProject:tE,about:nE,actions:oE,contextMenu:sE,status:iE,form:aE,time:rE,file:lE,editor:cE,document:dE,empty:uE,validation:pE,startup:mE,tabs:gE,welcome:hE,scenes:fE,overlay:yE,loading:wE,ssh:vE,notify:bE,newWork:kE},xE={primary:"主按钮",secondary:"次按钮",danger:"危险按钮",ghost:"幽灵按钮"},CE={placeholder:"请输入...",clear:"清空",show:"显示",hide:"隐藏"},AE={placeholder:"请选择",noOptions:"无选项",loading:"加载中...",search:"搜索...",emptyText:"暂无数据",selectAll:"全选",customValueHint:"按 Enter 使用自定义值",useCustomValue:'使用 "{{value}}"'},_E={decrease:"减少",increase:"增加"},TE={exitFullscreen:"退出全屏",exitFullscreenHint:"退出全屏 (ESC)",enterFullscreen:"全屏预览"},PE={emptyError:"此字段不能为空"},FE={copySuccess:"复制成功",copyCode:"复制代码",resizeColumn:"调整第 {{index}} 列宽度",resetColumnWidths:"双击或按 Enter 重置列宽"},RE={renderFailed:"图表渲染失败",codeIncomplete:"代码不完整,等待更多内容...",rendering:"正在渲染图表...",openInEditor:"在编辑器中打开",showCode:"查看源码",hideCode:"隐藏源码",copyCode:"复制代码"},NE={completedTitle:"复现步骤已完成",instructionTitle:"请按以下步骤复现问题",continueButton:"继续",processing:"处理中...",notified:"已通知 AI 分析日志,请等待结果...",instruction:"完成上述步骤后,点击下方按钮让 AI 继续分析日志",userCompleted:"[用户已完成复现] 请立即收集并分析日志。",userCompletedShort:"用户已完成复现",operationFailed:"操作失败,请重试"},DE={todoCard:{title:"任务管理",description:"管理任务列表",total:"总计",inProgress:"进行中",completed:"已完成",noTasks:"暂无任务",taskCount:"{{total}} 项任务 / {{completed}} 已完成"},webSearchCard:{searchTitle:"网页搜索",fetchTitle:"获取链接",searchQuery:"搜索查询",url:"URL",results:"搜索结果",resultsCount:"{{count}} 个结果",resultCount:"结果数",noResults:"未找到相关结果",searching:"正在搜索...",searchDesc:"搜索网页内容",fetchDesc:"获取网页链接内容",unspecifiedQuery:"未指定查询"},snapshotCard:{writeFile:"写入文件",editFile:"编辑文件",deleteFile:"删除文件",multiEdit:"批量编辑",accept:"接受修改",reject:"拒绝修改",viewDetails:"查看详情",viewFullDiff:"查看完整差异",processing:"正在处理文件...",linesAdded:"行新增",linesDeleted:"行删除",filesCount:"{{count}} 文件",filePath:"文件路径",unspecifiedFile:"未指定文件",file:"文件"},taskCard:{title:"执行任务",description:"执行专门的AI任务",taskType:"任务类型",taskDesc:"任务描述",result:"任务结果",processing:"AI正在处理任务...",defaultType:"AI任务",unspecifiedTask:"未指定任务"},searchCard:{grepTitle:"文本搜索",globTitle:"文件搜索",grepDesc:"在文件中搜索文本",globDesc:"按模式搜索文件",pattern:"搜索模式",path:"搜索路径",matches:"个匹配",files:"个文件",matchingFiles:"匹配文件",noTextMatch:"未找到匹配的文本",noFileMatch:"未找到匹配的文件",unspecifiedPattern:"未指定模式",currentDir:"当前目录",matchCount:"{{count}} 处"},contextCompressionCard:{title:"上下文压缩",description:"优化对话上下文,节省tokens",compressing:"智能压缩上下文中...",analyzing:"正在分析并压缩上下文...",triggerBeforeUserMessage:"用户消息前",triggerAfterToolBatch:"工具批次完成",triggerAfterAiResponse:"AI响应后",triggerManual:"手动触发",triggerAuto:"自动触发",triggerTime:"触发时机:{{trigger}} · 第{{count}}次",duration:"耗时",savedTokens:"压缩 {{count}} tokens · 当前比例 {{ratio}}%"},toolConfig:{read:{displayName:"读取文件",description:"读取指定文件的内容"},write:{displayName:"写入文件",description:"写入或创建文件"},edit:{displayName:"编辑文件",description:"编辑文件内容"},delete:{displayName:"删除文件",description:"删除指定文件"},grep:{displayName:"文本搜索",description:"在文件中搜索文本"},glob:{displayName:"文件搜索",description:"按模式搜索文件"},webSearch:{displayName:"网页搜索",description:"搜索网页内容"},webFetch:{displayName:"获取链接",description:"获取链接内容"},task:{displayName:"执行任务",description:"执行专门的 AI 任务"},todoWrite:{displayName:"任务管理",description:"管理任务列表"},contextCompression:{displayName:"上下文压缩",description:"智能压缩对话上下文"},default:{description:"执行 {{toolName}} 工具"}},baseToolCard:{awaitingConfirmation:"等待确认",analyzing:"分析参数中...",running:"执行中...",completed:"已完成",cancelled:"已取消",failed:"执行失败",preparing:"准备中",inputParams:"输入参数:",confirm:"确认",cancel:"取消",result:"结果:",viewDetails:"查看详情"}},IE={alertDemo:{title:"Alert 警告提示",subtitle:"简约的警告提示组件",sections:{basic:"基础类型",withTitle:"带标题",withDescription:"带描述文本",closable:"可关闭",noIcon:"无图标"},messages:{operationSuccess:"操作成功完成",operationFailed:"操作失败,请重试",operationRisk:"此操作存在风险",infoMessage:"这是一条信息提示",deploySuccessTitle:"部署成功",deploySuccessMessage:"应用已成功部署到生产环境",deployFailedTitle:"部署失败",deployFailedMessage:"应用部署过程中遇到错误",expiringTitle:"即将过期",expiringMessage:"您的订阅将在 7 天后到期",expiringDescription:"为了避免服务中断,请及时续费",updateTitle:"版本更新",updateMessage:"发现新版本 v3.0.0",updateDescription:"包含性能优化和新功能",closableMessage:"点击右侧按钮关闭此提示",closableInfoTitle:"提示信息",closableInfoMessage:"这个提示也可以关闭",noIconMessage:"这是一个没有图标的提示"}},iconButtonExample:{title:"IconButton 组件示例",sections:{basic:"基础样式(Default)- 透明背景,悬停时显示底色",ghost:"Ghost 样式 - 与 Default 一致",primary:"Primary 强调按钮 - 使用 CSS 变量",shape:"形状变体 - 圆形",other:"其他变体",usage:"使用说明"},usage:{defaultGhost:{label:"default/ghost: ",text:"透明背景,悬停时显示底色,适合低优先级操作"},primary:{label:"primary: ",text:"强调按钮,使用与文本按钮一致的 CSS 变量系统,适合高优先级操作"},disabled:{label:"禁用状态: ",text:"使用 disabled 属性,opacity 降低为 0.5"},theme:{label:"主题支持: ",text:"primary 变体通过 CSS 变量支持主题定制"}}},previewApp:{title:"Sparo OS 设计系统",emptyState:"请从左侧选择入口查看设计系统指引",navigationTitle:"设计系统",collapseNavigation:"收起导航",expandNavigation:"展开导航",theme:{label:"主题",light:"浅色",dark:"深色",lightDescription:"浅色主题",darkDescription:"深色主题"},tiers:{primitive:"原子",pattern:"模式",recipe:"配方"}},layouts:{quickJump:"快速跳转",previewLabel:"预览",idLabel:"ID:"},markdownPreview:{title:"Markdown 组件预览",badge:"内容组件",backToLibrary:"← 返回组件库",controls:{variantLabel:"样式变体:",modeLabel:"模式:",preview:"预览",edit:"编辑",reset:"重置内容"},variants:{default:"默认",bordered:"带边框",minimal:"简洁"},editorPlaceholder:"在这里输入 Markdown 内容...",sample:`# Markdown 组件完整预览 + +欢迎来到 Sparo OS 的 Markdown 组件预览页面! + +## 基础语法 + +### 文本样式 + +这是**粗体文本**,这是*斜体文本*,这是~~删除线~~。 + +你还可以组合使用,比如 ***粗斜体***。 + +### 列表 + +#### 无序列表 + +- 项目 1 +- 项目 2 + - 子项目 2.1 + - 子项目 2.2 +- 项目 3 + +#### 有序列表 + +1. 第一步 +2. 第二步 +3. 第三步 + +#### 任务列表 + +- [x] 已完成的任务 +- [ ] 待完成的任务 +- [ ] 另一个任务 + +## 代码展示 + +### 内联代码 + +使用 \`npm install\` 安装依赖,然后运行 \`npm run dev\` 启动开发服务器。 + +### 代码块 + +\`\`\`typescript +interface User { + id: string; + name: string; + email: string; +} + +function greetUser(user: User): string { + return \`Hello, \${user.name}!\`; +} + +const user: User = { + id: '1', + name: 'Alice', + email: 'alice@example.com' +}; + +console.log(greetUser(user)); +\`\`\` + +\`\`\`javascript +// JavaScript example +const fetchData = async () => { + try { + const response = await fetch('https://api.example.com/data'); + const data = await response.json(); + return data; + } catch (error) { + console.error('Error:', error); + } +}; +\`\`\` + +\`\`\`python +# Python example +def fibonacci(n): + if n <= 1: + return n + return fibonacci(n-1) + fibonacci(n-2) + +for i in range(10): + print(f"F({i}) = {fibonacci(i)}") +\`\`\` + +## 表格 + +| 特性 | 描述 | 支持状态 | +|------|------|---------| +| 标题 | H1-H6 标题 | 是 | +| 列表 | 有序/无序列表 | 是 | +| 代码块 | 语法高亮 | 是 | +| 表格 | Markdown 表格 | 是 | +| 链接 | 超链接 | 是 | +| 图片 | 图片展示 | 是 | +| 引用 | 引用块 | 是 | + +## 引用块 + +> 这是一个引用块。 +> +> 可以用来强调重要信息或引用他人的话。 +> +> — Sparo OS Team + +> **提示:** 引用块可以包含其他 Markdown 元素,包括**粗体**、*斜体*和\`代码\`。 + +## 链接 + +访问 [Sparo OS 官网](https://sparo.dev) 了解更多信息。 + +查看 [GitHub 仓库](https://github.com/sparo-os) 获取源代码。 + +自动链接:https://example.com + +## 图片 + +![示例图片](https://via.placeholder.com/600x300/667eea/ffffff?text=Sparo OS+Markdown) + +## 分割线 + +--- + +## 嵌套内容 + +### 列表中的代码 + +1. 首先安装依赖: + \`\`\`bash + npm install react-markdown + \`\`\` + +2. 然后在代码中使用: + \`\`\`jsx + import ReactMarkdown from 'react-markdown'; + + {content} + \`\`\` + +### 引用中的列表 + +> #### 注意事项 +> +> - 确保正确转义特殊字符 +> - 使用合适的语法高亮 +> - 保持文档结构清晰 + +## 特殊格式 + +
+点击展开详细内容 + +这是折叠的内容,点击标题可以展开。 + +- 支持 HTML 标签 +- 可以包含 Markdown 内容 + +
+ +## 总结 + +Sparo OS 的 Markdown 组件支持: + +1. 支持完整的 Markdown 语法 +2. 支持 GitHub Flavored Markdown (GFM) +3. 支持漂亮的暗色主题 +4. 支持代码语法高亮 +5. 支持响应式表格 +6. 支持自定义样式变体 + +**开始使用吧!**`},usageGuide:{label:"AI 使用指引",recipeLabel:"配方",useWhen:"使用场景",composeWith:"组合使用",avoid:"避免",states:"预览状态"}},ME={close:"关闭",confirm:"确认",cancel:"取消"},jE={alert:{title:"提示",ok:"确定"},confirm:{title:"确认",ok:"确定",cancel:"取消"},prompt:{title:"输入",placeholder:"请输入...",ok:"确定",cancel:"取消"}},EE={copy:"复制",copied:"已复制",close:"关闭",expand:"展开",collapse:"收起"},LE={close:"关闭标签",popOut:"弹出为独立场景",closeOthers:"关闭其他标签",closeAll:"关闭所有标签",closeRight:"关闭右侧标签",pin:"固定标签",unpin:"取消固定",unsaved:"未保存",fileDeleted:"已删除",hiddenTabsCount:"{{count}} 个隐藏标签",confirmCloseWithDirty:`文件 "{{title}}" 有未保存的更改。 + +是否放弃更改并关闭?`,confirmCloseAllWithDirty:`以下 {{count}} 个文件有未保存的更改: + +{{fileList}} + +是否放弃所有更改并关闭?`},$E={expand:"展开",collapse:"收起",loading:"加载中..."},OE={empty:"暂无数据",loading:"加载中...",rowsPerPage:"每页行数",totalRows:"共 {{total}} 行",page:"第 {{page}} 页",of:"共 {{total}} 页"},BE={first:"第一页",last:"最后一页",previous:"上一页",next:"下一页",page:"第 {{page}} 页",of:"共 {{total}} 页"},WE={noItems:"无项目"},zE={cut:"剪切",copy:"复制",paste:"粘贴",delete:"删除",selectAll:"全选"},UE={contextList:{emptyTitle:"暂无上下文",emptyHint:"从文件树、代码编辑器或 Mermaid 图表拖拽内容到这里",title:"上下文",clearAll:"清空",clearAllTitle:"清空所有上下文",clearAllConfirm:"确定要清空所有 {{count}} 个上下文吗?"},contextCard:{unknownType:"未知类型: {{type}}",removeContext:"移除此上下文",viewFullCode:"查看完整代码",viewLargeImage:"查看大图"},contextTypes:{selection:"文本选择",file:"文件",folder:"文件夹",editor:"编辑器",flowChat:"FlowChat",flowChatToolCard:"FlowChat 工具卡片",flowChatTextBlock:"FlowChat 文本块",tab:"标签页",panelHeader:"面板标题",emptySpace:"空白区域",custom:"自定义",unknown:"未知"},webElement:{from:"来自"},diagram:{defaultTitle:"Mermaid 图表",types:{flowchart:"流程图",sequence:"时序图",class:"类图",state:"状态图",er:"ER图",gantt:"甘特图",other:"图表"},codeSize:{chars:"{{count}} 字符",kChars:"{{count}}K 字符"}},validation:{warnings:{codeLinesLarge:"选择的代码行数较多(>{{max}} 行),建议精简",codeContentLarge:"选择的代码内容较大(>{{maxChars}} 字符),可能影响处理速度",fileLarge:"文件较大(>{{size}}MB),可能影响处理速度",mermaidCodeLong:"Mermaid 代码较长(>{{maxChars}} 字符),可能影响处理速度",mermaidCodeInvalid:"可能不是有效的 Mermaid 语法"}}},HE={close:"关闭",closeAll:"关闭所有"},qE={title:"通知中心",actions:{markAllRead:"全部已读",clearAll:"清除所有"},searchPlaceholder:"搜索通知...",filters:{all:"全部 ({{count}})",placeholder:"分类"},activeTasks:{title:"正在进行的任务 ({{count}})"},empty:{noMatches:"没有匹配的通知",noNotifications:"暂无通知"},groups:{earlier:"更早"}},VE={text:"加载中...",retry:"重试"},GE={title:"暂无数据",description:"没有找到相关内容"},KE={title:"出错了",description:"发生了意外错误",retry:"重试"},QE={placeholder:"搜索...",noResults:"无搜索结果",clear:"清空搜索"},JE={required:"必填",optional:"选填",submit:"提交",reset:"重置",cancel:"取消"},YE={minimize:"最小化",maximize:"最大化",restore:"还原",close:"关闭"},ZE={workspaceOpenFailed:"打开工作区失败",projectRequestMessage:`我想创建一个新项目: + +{{description}} + +请帮我设计项目结构并开始实现。`,projectRequestSent:"已将项目需求发送给小方,开始协作创建!",projectRequestSendFailed:"发送项目描述失败,请手动输入",flowChatInitFailed:"初始化失败,请刷新页面重试"},XE={sessions:"Agent 工作台",files:"文件树",terminal:"终端",projectContext:"工程上下文",git:"Git",capabilities:"能力配置",clickToSelectBranch:"点击选择分支",aiWingExpand:"展开 AI 工具",devWingExpand:"展开开发工具"},eL={noContentOpen:"暂未打开任何内容",filesCount:"{{count}} 个文件",searchPlaceholder:"搜索文件名或路径...",noPreview:"暂无预览内容",groupPrimary:"主",groupSecondary:"次",groupTertiary:"三",groupPrimaryFull:"主分栏",groupSecondaryFull:"次分栏",groupTertiaryFull:"第三分栏",mergeAllGroups:"合并所有分栏",mergeAll:"一键合一",noMatchingFiles:"没有匹配的文件",noOpenFiles:"没有打开的文件",clickToSwitch:"点击卡片切换文件",exit:"退出",openFileLocation:"打开文件位置",pinAsTab:"固定为标签 (Enter)",closeEsc:"关闭 (Esc)",enterToPin:"Enter 固定为标签",escToClose:"Esc 关闭",dragTabHere:"拖拽标签到此处",dragToResize:"拖拽调整大小 | 双击重置",terminal:"终端",dropLeft:"左",dropRight:"右",dropTop:"上",dropBottom:"下",dropCenter:"放置"},tL={empty:{title:"暂无内容",description:"选择一个文件或节点来预览内容"},unknownContent:{title:"不支持的内容类型",description:"无法预览此类型的内容",contentType:"内容类型:{{type}}"},visualizationDisabled:{title:"可视化功能已禁用",description:"工程阅读模式专注于文件浏览和预览"},errors:{markdownEditorMissingPath:"无法加载Markdown编辑器:缺少文件路径或初始内容",planViewerMissingPath:"无法加载Plan查看器:缺少文件路径",terminalMissingSessionId:"无法加载终端:缺少会话ID",productAppRuntimeMissingHost:"无法加载 Product App 运行时:缺少承载界面",productAppRuntimeBootTimeout:"应用未能完成启动,请重试。",gitPanelRemoved:"此版本已移除 Git 集成。"},placeholder:{architectureLayerViewer:"架构层级查看器功能开发中...",noDiffResult:"没有Diff结果可显示",noModuleChanges:"没有模块变更"},actions:{copyContent:"复制内容",downloadContent:"下载内容",close:"关闭",retry:"重试"},loading:{gitDiff:"加载Git差异...",gitGraph:"加载Git图表...",gitBranchHistory:"加载分支提交历史...",gitSettings:"加载Git设置...",diffView:"加载差异视图...",taskDetail:"加载任务详情...",dependencyGraph:"加载依赖关系图...",planViewer:"加载计划...",terminal:"加载终端...",productAppRuntime:"正在加载 Product App...",productAppRuntimeUpdating:"正在更新..."},aiSession:{title:"AI会话: {{sessionId}}",unknown:"未知",sessionStatus:"会话状态:",operationsCount:"操作数量:",operationsValue:"{{count}} 个操作",startTime:"开始时间:",unknownTime:"未知",fileOperations:"文件操作"},fallback:{noCodeContent:"无代码内容"}},nL={button:xE,input:CE,select:AE,numberInput:_E,codeEditor:TE,inputDialog:PE,markdown:FE,mermaidBlock:RE,reproductionSteps:NE,flowChatCards:DE,designSystem:IE,modal:ME,dialog:jE,tooltip:EE,tabs:LE,tree:$E,table:OE,pagination:BE,dropdown:WE,contextMenu:zE,contextSystem:UE,notification:HE,notificationCenter:qE,loading:VE,empty:GE,error:KE,search:QE,form:JE,windowControls:YE,appLayout:ZE,bottomBar:XE,canvas:eL,flexiblePanel:tL},oL="Sparo OS 设计系统预览",sL={designSystem:"设计系统",previewTheme:"预览主题",previewLanguage:"界面语言"},iL={lightDescription:"浅色预览主题",darkDescription:"深色预览主题",light:{name:"浅色",description:"干净明亮的预览主题"},slate:{name:"石板",description:"柔和克制的深色预览主题"},dark:{name:"深色",description:"高对比度深色预览主题"},"sparo-china-style":{name:"墨韵",description:"取意中国水墨的浅色主题"},"sparo-china-night":{name:"墨夜",description:"取意中国水墨的深色主题"},"sparo-cyber":{name:"赛博",description:"高能量赛博深色预览主题"}},aL={library:"组件库",expandNavigation:"展开导航",collapseNavigation:"收起导航",searchPlaceholder:"搜索组件",searchAriaLabel:"搜索设计系统组件",navigationAriaLabel:"设计系统组件库",categoryExamplesAriaLabel:"{{category}}组件",shown:"已显示 {{count}} 项",searchShortcut:"按 / 开始搜索"},rL={noMatches:"没有匹配结果",searchSuggestion:"请尝试输入组件名称或 ID。",noPreview:"未找到预览",previewSuggestion:"请尝试其他组件名称,或清空搜索条件。"},lL={tiers:{primitive:"原子层",pattern:"模式层",recipe:"配方层"},examplesAriaLabel:"预览示例",previous:"上一个:{{name}}",next:"下一个:{{name}}",usage:"用法",usageGuidance:"使用指南",closeUsage:"关闭使用指南"},cL={recipe:"配方",useWhen:"适用场景",composeWith:"组合使用",avoid:"避免",states:"覆盖状态",notes:"{{count}} 条说明"},dL={categories:{"ds-primitives":{name:"基础组件",description:"稳定的底层控件,应在组合模式中使用,不应演变为功能内部的独立 UI 框架。"},"ds-patterns":{name:"组合模式",description:"页面与工作流的结构模板,AI 应优先选择组合模式,再使用底层组件。"},"ds-ai-entry":{name:"AI 构建规则",description:"使用设计系统组合产品界面前,应从这里开始。"}},examples:{"ds-sparo-logo-mark":{name:"Sparo 标志",description:"支持尺寸、描边宽度和 currentColor 继承的矢量品牌标志。"},"ds-sparo-system-icons":{name:"Sparo 语义图标族",description:"覆盖系统、工作类型、导航、搜索筛选、文件传输及编辑管理的一方图标。"},"ds-button-semantics":{name:"按钮命令语义",description:"按钮类型、尺寸、加载、禁用与纯图标命令的使用规则。"},"ds-floating-card":{name:"浮动卡片",description:"具有大圆角、两级悬浮阴影和标准关闭命令的非模态界面。"},"ds-popup-menu":{name:"弹出菜单",description:"使用统一悬浮阴影与中等圆角的锚定菜单基线。"},"ds-form-controls":{name:"表单控件",description:"在真实设置文案中展示文本框、选择器、开关与复选框。"},"ds-feedback":{name:"反馈组件",description:"用于桌面工作流的状态徽标与空状态组件。"},"ds-search-and-filters":{name:"搜索与筛选",description:"适用于紧凑桌面界面的搜索图标与筛选命令。"},"ds-dialog-tabs-alerts":{name:"对话框、标签页与警告",description:"具有明确角色、标签和恢复状态的键盘友好组件。"},"ds-input-variants":{name:"输入框变体",description:"带标签与说明的文本域、搜索框和数字输入状态。"},"ds-segmented-pagination":{name:"分段控制与分页",description:"覆盖选中、禁用、聚焦、窄布局和长标签状态的导航控件。"},"ds-loading-status":{name:"加载与状态组件",description:"稳定的加载占位与带文字说明的状态指示。"},"ds-app-window":{name:"应用窗口",description:"无需遮罩、可承载复杂内容的应用内非模态弹出窗口。"},"ds-scene-panel":{name:"场景与面板",description:"包含命令分组与有界工作区的默认桌面场景结构。"},"ds-list-detail":{name:"列表详情工作流",description:"可选择的主列表,以及聚焦的详情或检查器界面。"},"ds-settings-page":{name:"设置页面",description:"适用于设置、偏好与服务商配置的标准布局。"},"ds-item-card":{name:"项目卡片",description:"适用于任务、应用和其他可操作目录项的可复用卡片结构。"},"ds-tool-card":{name:"真实工具卡片",description:"展示已注册 Read 与 Bash 工具实际使用的紧凑型和可展开对话流卡片。"},"ds-navigation-empty-status":{name:"导航、空状态与状态栏",description:"用于工作区导航与可靠空状态的辅助组合模式。"},"ds-action-list-row":{name:"操作列表行",description:"覆盖选择、元数据、状态、操作、加载与错误的可复用行结构。"},"recipe-agent-session-workbench":{name:"智能体会话工作台",description:"用于会话分流、任务续接与实时智能体活动的真实产品场景。"},"recipe-workspace-file-operations":{name:"工作区文件操作",description:"用于文件、差异和工作区浏览任务的紧凑导航与详情结构。"},"recipe-model-settings":{name:"模型与权限设置",description:"覆盖默认模型、工作区策略与校验状态的设置配方。"},"recipe-tool-execution":{name:"工具执行卡片",description:"用于运行中、已完成与失败工具输出的对话流执行结构。"}}},uL={documentTitle:oL,header:sL,themes:iL,sidebar:aL,empty:rL,focused:lL,guide:cL,catalog:dL},pL={unknown:"发生未知错误",network:"网络错误",timeout:"请求超时",serverError:"服务器错误",notFound:"未找到资源",unauthorized:"未授权",forbidden:"禁止访问",badRequest:"请求无效",conflict:"资源冲突",tooManyRequests:"请求过于频繁",copyFailed:"Copy failed. Please try again."},mL={notFound:"文件未找到:{{path}}",readError:"读取文件失败:{{path}}",writeError:"写入文件失败:{{path}}",deleteError:"删除文件失败:{{path}}",permissionDenied:"权限不足:{{path}}",alreadyExists:"文件已存在:{{path}}",invalidPath:"无效的文件路径:{{path}}",tooLarge:"文件过大:{{path}}",encodingError:"文件编码错误:{{path}}",createFileFailed:"Failed to create file",createFolderFailed:"Failed to create folder",renameFailed:"Rename failed",revealFailed:"Failed to open file manager"},gL={notFound:"工作区未找到",openError:"打开工作区失败",invalidPath:"无效的工作区路径",alreadyOpen:"工作区已打开"},hL={notRepository:"当前目录不是 Git 仓库",cloneError:"克隆仓库失败",commitError:"提交失败",pushError:"推送失败",pullError:"拉取失败",mergeConflict:"存在合并冲突",branchError:"分支操作失败",stashError:"贮藏操作失败",authError:"认证失败",remoteError:"远程仓库错误"},fL={connectionError:"连接 AI 服务失败",apiKeyInvalid:"API 密钥无效",modelNotFound:"模型未找到",contextTooLong:"上下文超出限制",rateLimited:"请求频率超出限制",generationError:"生成内容失败",streamError:"流式响应错误",timeout:"AI 响应超时",initializeFailedTitle:"AI client initialization failed",configRequired:"Model configuration is required"},yL={createError:"创建终端失败",executeError:"执行命令失败",killError:"终止进程失败",shellNotFound:"Shell 未找到"},wL={maximizeFailed:"最大化窗口失败:{{error}}",closeFailed:"关闭窗口失败:{{error}}"},vL={openError:"打开编辑器失败",saveError:"保存文件失败",formatError:"格式化失败",parseError:"解析文件失败",lspError:"语言服务器错误"},bL={loadError:"加载配置失败",saveError:"保存配置失败",invalidFormat:"配置格式无效",validationError:"Configuration validation failed"},kL={createError:"创建快照失败",restoreError:"恢复快照失败",notFound:"快照未找到",corrupted:"快照已损坏",loadStatsFailed:"加载快照统计失败",loadSessionsFailed:"加载快照会话失败",loadOperationsFailed:"加载会话操作失败",getDiffFailed:"获取文件差异失败",acceptOperationFailed:"接受操作失败",rejectOperationFailed:"拒绝操作失败",rollbackSessionFailed:"回滚会话失败",cleanupFailed:"清理过期数据失败"},SL={noSelection:"No text selected",notEditable:"Content is not editable",readOnlyEditor:"Editor is read-only",clipboardUnavailable:"Clipboard access is unavailable",clipboardEmpty:"Clipboard is empty",copyFailed:"Copy failed",cutFailed:"Cut failed",pasteFailed:"Paste failed",selectAllFailed:"Select all failed",refreshFailed:"Refresh failed",deleteFailed:"Delete failed",deleteCancelled:"Delete canceled",editorModelUnavailable:"Editor model is unavailable",copyPathFailed:"Copy path failed",copyRelativePathFailed:"Copy relative path failed"},xL={initializationFailed:"Core system initialization failed"},CL={title:"界面出了点问题",description:"当前界面已安全暂停。你的项目文件没有因此被修改。",reload:"重新加载",sections:{currentState:"当前状态",nextSteps:"建议操作",errorSummary:"错误摘要"},actionHint:"建议先重新加载。如果反复出现,再复制诊断信息或打开日志文件夹。",currentStateBody:"应用窗口仍在运行,但当前界面的一部分已经停止渲染。建议先重新加载;如果问题反复出现,请先复制诊断信息或打开日志文件夹,再反馈给开发者。",suggestions:{reload:"重新加载应用,通常可以恢复临时的界面渲染问题。",copyDiagnostics:"如果这个页面再次出现,复制诊断信息用于排查。",openLogs:"需要提供更完整的运行时信息时,打开日志文件夹并附上相关日志。"},actions:{copyDiagnostics:"复制诊断信息",openLogs:"打开日志文件夹",copied:"诊断信息已复制到剪贴板。",copyFailed:"无法复制诊断信息。你仍可以展开技术详情后手动复制。",logsOpened:"日志文件夹已打开。",openLogsFailed:"无法打开日志文件夹。你仍可以先复制诊断信息。"},technicalDetails:"技术详情",unknown:"未知错误"},AL={general:pL,file:mL,workspace:gL,git:hL,ai:fL,terminal:yL,window:wL,editor:vL,config:bL,snapshot:kL,contextMenu:SL,core:xL,boundary:CL},_L={welcomeBack:"欢迎回来!",workingIn:"您正在 {{workspace}} 中",workingInWithBranch:"您正在 {{workspace}} 中,工作分支是 {{branch}}",capabilities:"我可以帮你读懂复杂代码,快速实现新功能,",capabilities2:"重构老旧项目,或是解决那些让人头疼的 Bug。",readyToHelp:"说出你的想法,我随时待命",noWorkspace:"这里还空空如也",openProject:"打开一个项目,让我们一起开始编码之旅"},TL={noTabs:"暂无打开的标签",selectFromLeft:"从左侧选择文件或内容来创建新标签",dragTabHere:"拖拽标签到此处",releaseToAdd:"释放以添加到此栏"},PL={noPanels:"Sparo OS",noPanelsHint:"使用底部栏切换面板或按 Ctrl+\\ Ctrl+] 展开面板",chatHiddenTitle:"聊天已隐藏",chatHiddenDesc:"你可以在右上角点击“聊天”重新打开。",chatHiddenAction:"重新打开聊天",panelCollapseHintLeft:"<- 松开收起",panelCollapseHintRight:"松开收起 ->",panelMode:{collapsed:"收起",compact:"紧凑",comfortable:"舒适",expanded:"展开"},resizer:{leftAriaLabel:"调整左侧面板大小",centerAriaLabel:"调整面板大小",rightAriaLabel:"调整右侧面板大小",title:"拖拽调整面板大小 | 双击切换模式 | 当前: {{mode}}"}},FL={toBottom:"回到底部",toBottomWithCount:"回到底部 ({{count}} 条新消息)",toLatest:"跳转到最新消息",clickToLatest:"点击跳转到最新",anchorJumpToTurn:"跳转到{{turn}}:{{title}}"},RL={user:"用户",assistant:"助手",system:"系统",thinking:"思考中...",generating:"生成中...",copy:"复制消息",copied:"已复制",copyFailed:"已复制!",regenerate:"重新生成",edit:"编辑消息",editPlaceholder:"编辑你的消息...",editSubmit:"保存并重新运行",editCancel:"取消编辑",editSuccess:"消息已更新并重新运行",editHistoryDialogTitle:"编辑第 {{index}} 轮并从这里重新运行?",editHistoryDialogIntro:"这会从这条消息开始重写对话。",editBusyDialogTitle:"停止正在运行的轮次并编辑第 {{index}} 轮?",editBusyDialogIntro:"当前有轮次正在执行。编辑会先停止它,然后重写历史。",editDialogBulletStopRunning:"停止当前正在运行的任务",editDialogBulletFiles:"将文件恢复到这一轮开始前的状态",editDialogBulletHistory:"删除这一轮及之后的对话记录",editDialogBulletRerun:"使用编辑后的消息开启新的轮次",delete:"删除消息",retry:"重试",clickToExpand:"点击展开",clickToCollapse:"点击收起",fillToInput:"填充到输入框",cannotRollback:"无法回滚",rollbackTo:"回滚到第 {{index}} 轮之前(删除该轮及之后)",rollbackDialogTitle:"确定回滚到第 {{index}} 轮之前?",rollbackDialogIntro:"将执行:",rollbackDialogBulletFiles:"撤销从该轮开始的所有文件修改",rollbackDialogBulletHistory:"删除该轮及之后的对话记录(不可恢复)",rollbackPanelDialogTitle:"回滚到第 {{index}} 轮之前?",rollbackPanelDialogIntro:"将执行:",rollbackPanelBulletRestore:"将文件恢复到第 {{index}} 轮之前的状态",rollbackPanelBulletUndo:"撤销从该轮开始的所有文件变更",rollbackPanelBulletHistory:"保留会话历史(之后仍可继续对话)",rollbackSuccess:"已回滚并删除后续对话记录",rollbackFailed:"回滚失败",sessionStartMarker:"会话开始 {{time}}"},NL={copySelection:"复制选中内容",selectionCopied:"已复制",copySelectionFailed:"复制选中内容失败",addSelectionToChat:"添加到 Chat",createSideQuestionFromSelection:"新建侧问",selectionActions:"选中内容操作",copyFullContent:"复制完整内容",copyContent:"复制内容",copyDialog:"复制整个对话",copyToolInput:"复制工具输入",copyToolOutput:"复制工具输出"},DL={placeholder:"有什么可以帮您...",placeholderWithContext:"输入消息,或拖放文件添加上下文...",send:"发送",sendShortcut:"发送 (⏎)",queueShortcut:"加入队列 (⏎)",stop:"停止",stopGeneration:"停止生成 (Esc)",processingCapsule:"正在处理",cancelShortcut:"取消",clear:"清空",attach:"附加文件",collapseInput:"收起输入框",expandInput:"展开输入框",retry:"重试",addImage:"添加图片",maxImagesWarning:"最多只能选择{{count}}张图片",imagePasteFailed:"图片粘贴失败",removeImage:"移除图片",context:{textFragment:"长文本:{{preview}}",longTextTitle:"长文本",emptyPreview:"空白",characterCount:"{{count}} 字",skillSuiteDetail:"技能套装 · {{count}} 个 Skill",skillDetail:"Skill · {{suite}}",standaloneSkill:"独立 Skill",open:"打开{{label}}",remove:"移除{{label}}"},messageTooLarge:"消息超过最大长度 {{max}} 个字符(当前 {{count}} 个字符)。",openWorkspaceFolder:"打开工作区文件夹",openWorkspaceFolderFailed:"打开工作区文件夹失败:{{error}}",globalWorkspace:"全局",spaceToActivate:"有什么可以帮您?按空格快速键入",voiceInput:{transcribeOnly:"仅转写",transcribeAndSend:"转写并发送",start:"开始语音输入",stop:"停止并转写",preparing:"正在准备语音输入",recording:"录音中",transcribing:"转写中",disabled:"语音输入已关闭",modelMissing:"请先在设置中下载本地语音模型",unsupported:"当前环境不支持麦克风采集",permissionDenied:"麦克风权限被拒绝",failed:"语音输入失败",empty:"未识别到语音文本"}},IL={title:"{{count}} 条待发送",edit:"编辑待发送消息",delete:"删除待发送消息",saveEdit:"保存待发送消息",cancelEdit:"取消编辑",editAriaLabel:"待发送消息草稿",dispatching:"发送中",resume:"继续",imageCount:"{{count}} 张图片",updateFailed:"更新待发送消息失败",deleteFailed:"删除待发送消息失败",resumeFailed:"恢复队列失败",pauseReasons:{user_cancelled:"已因取消而暂停",run_failed:"已因执行失败而暂停",app_recovered:"已因恢复会话而暂停",default:"已暂停"},guide:"引导当前对话",guideFailed:"引导发送失败"},ML={title:"上下文",add:"添加上下文",remove:"移除上下文",clear:"清空上下文",file:"文件",folder:"文件夹",selection:"选中内容",codeBlock:"代码块",image:"图片",url:"URL",dragHint:"拖放文件到此处添加上下文"},jL={staticContext:"静态上下文",currentRequest:"当前请求",closeDetails:"关闭上下文详情",noSegmentData:"暂无分段数据",calculating:"正在计算上下文预算",segments:{systemPrompt:"系统 Prompt",environment:"环境",workspace:"工作区",memory:"记忆",files:"文件",toolDefinitions:"工具定义",skills:"技能",subagentDefinitions:"子代理定义",conversation:"对话历史",currentMessage:"当前消息",assistant:"助手回复",toolResults:"工具结果",images:"图片",summary:"摘要",overhead:"模型开销"}},EL={title:"智能体",select:"选择智能体",default:"默认助手",coding:"BitFun Coder",review:"代码审查",architect:"架构师",custom:"自定义智能体"},LL={title:"模型",select:"选择模型",temperature:"温度",maxTokens:"最大令牌数",topP:"Top P",streaming:"流式输出",autoMigrated:{title:"模型已自动切换",description:'会话原模型"{{previous}}"不可用,已切换为"{{next}}"。',reason:"原因:{{reason}}"}},$L={newSession:"新建会话",history:"历史记录",settings:"设置",export:"导出对话",clear:"清空对话",fullscreen:"全屏",exitFullscreen:"退出全屏"},OL={ready:"就绪",thinking:"思考中",generating:"生成中",error:"发生错误",offline:"离线",connecting:"连接中",connected:"已连接"},BL={sendFailed:"发送失败",connectionError:"连接错误",timeout:"请求超时",modelError:"模型错误",contextTooLong:"上下文过长",rateLimited:"请求过于频繁",unknown:"未知错误"},WL={title:"任务规划",completed:"完成",completedCount:"{{count}} 完成",inProgress:"进行中",inProgressCount:"{{count}} 进行中",pending:"待处理",pendingCount:"{{count}} 待处理",todoItems:"待办事项 ({{count}})",save:"保存",cancel:"取消",sendToModel:"将修改发送给模型",sending:"发送中...",doubleClickToEdit:"双击编辑",percentComplete:"{{percent}}% 完成",currentStatus:"当前状态: {{status}}"},zL={searchResults:"搜索结果",loading:"加载中...",noMatchingFiles:"没有找到匹配的文件",emptyDirectory:"空目录",rootDirectory:"根目录",goBack:"返回上级目录",navHint:"导航",enterHint:"进入",backHint:"返回",selectHint:"选择"},UL={copy:"复制",copied:"已复制",copyOutputContent:"复制输出内容",copiedOutputContent:"已复制输出内容",edit:"编辑",openInEditor:"在编辑器中打开",aiReply:"AI回复 {{timestamp}}",toolCall:"🔧 工具调用: {{name}}",unknownTool:"未知工具"},HL={title:"💡 智能推荐",close:"关闭"},qL={title:"侧问",shortLabel:"侧问",hint:"不保存 · 使用当前对话上下文 · 无工具",placeholder:"问个小问题…",ask:"提问",asking:"思考中…",cancel:"停止",openThread:"打开子会话",threadLabel:"子会话",emptyThreadLabel:"暂未打开{{label}}",origin:"来自",parent:"父会话",turnLabel:"第 {{index}} 轮",back:"返回",backToParent:"返回父会话",empty:"请在 /btw 后面写上问题",nestedDisabled:"侧问会话中不能继续新建侧问",error:"失败",close:"关闭",noSession:"当前没有可用于 /btw 的会话"},VL={title:"主机扫描",shortLabel:"主机扫描",threadLabel:"主机扫描",emptyThreadLabel:"暂未打开{{label}}",origin:"来自",parent:"来源会话"},GL={turnList:"轮次列表",timeline:"时间线",untitledTurn:"未命名轮次",previousTurn:"上一轮对话",nextTurn:"下一轮对话",turnBadge:"第 {{current}} 轮",btwBackTooltipWithTurn:"返回到来源会话:{{title}}(第 {{turn}} 轮)",btwBackTooltipWithoutTurn:"返回到来源会话:{{title}}",btwCreateTooltip:"快速发起一个侧问",agentTypeTooltip:"{{type}}:{{path}}",backToAgenticOs:"返回 Agentic OS 会话",searchPlaceholder:"搜索对话轮次",searchResult:"{{current}} / {{total}}",searchNoResults:"没有匹配的轮次",searchPrevious:"上一个匹配轮次",searchNext:"下一个匹配轮次",searchClose:"关闭搜索",searchOpen:"搜索对话轮次",hideCompletedThinkingItems:"隐藏已完成的思考条目",showCompletedThinkingItems:"显示已完成的思考条目",resetHistory:"重置历史",moreMenu:"更多",showCompletedThinkingInConversation:"显示/隐藏思考",resetSession:"重置会话",sidecar:{groupLabel:"会话面板",more:"更多面板",designs:"设计产物",designTokens:"设计令牌",appBuilder:"应用构建器"},goalPanel:{open:"目标详情",close:"关闭目标详情",title:"目标",edit:"编辑目标",objective:"目标",saveEdit:"保存",saving:"保存中",cancelEdit:"取消",emptyEditError:"目标不能为空。",updateFailed:"更新目标失败。",controlFailed:"目标操作失败。",fallbackMessage:"AI 提取失败,已使用你的输入作为目标。",needsInput:"需要输入",gaps:"剩余缺口",pause:"暂停目标",resume:"继续目标",review:"审核目标",clear:"清除目标",cancelExecution:"取消目标执行"}},KL={timeFilterTooltip:"按时间筛选",timeFilterAll:"全部时间",timeFilterToday:"今天",timeFilterLast7:"最近 7 天",timeFilterThisMonth:"本月",timeFilterCustomRange:"自定义时间段…",timeFilterCustomTitle:"自定义日期范围",timeFilterCustomHint:"先点选开始日期,再点选结束日期。",timeFilterCustomSummary:"{{start}} – {{end}}",timeFilterCustomPickEndHint:"请选择结束日期(已开始:{{start}})",timeFilterCustomPickEnd:"请点选结束日期以完成范围。",timeFilterCustomPrevMonth:"上一月",timeFilterCustomNextMonth:"下一月",timeFilterCustomApply:"应用",timeFilterCustomCancel:"取消",counterFiltered:"{{shown}} / {{total}}"},QL={title:"时间轴",toggleTooltip:"时间轴",counter:"{{sessions}} 段 · {{turns}} 轮",counterFiltered:"{{sessionsShown}} / {{sessionsTotal}} 段 · {{turnsShown}} / {{turnsTotal}} 轮",searchPlaceholder:"搜索全部历史",empty:"还没有任何对话。在下方发送消息开始第一段。",emptyTimeFilter:"该时间范围内没有会话。请调整筛选或选择「全部时间」。",sessionEmpty:"暂无轮次",turnCount_one:"{{count}} 轮",turnCount_other:"{{count}} 轮",newSession:"开始新的一段",newSessionLabel:"新一段",selectSessions:"选择会话",selectionModeActive:"正在选择会话",selectSession:"选择 {{title}}",deselectSession:"取消选择 {{title}}",bulkLabel:"会话选择操作",selectAllVisible:"选择当前可见会话",selectedCount:"已选择 {{count}} / {{total}}",deleteSelected:"删除所选会话",clearSelection:"清除选择",deleteDialogTitle:"删除所选会话?",deleteDialogMessage:"将永久删除 {{count}} 个所选会话。此操作无法撤销。",deleteConfirm:"删除会话",deletePreviewMore:"……以及另外 {{count}} 个",deleteSuccess:"已删除 {{count}} 个会话",deleteFailed:"{{count}} 个所选会话删除失败",bucket:{today:"今天",yesterday:"昨天",thisWeek:"本周早些时候",thisMonth:"本月早些时候"}},JL={files:"文件",reviewLabel:"审查",reviewAll:"全部审查",loadFailed:"加载失败",clickToViewDiff:"点击查看 Diff",review:{displayMessage:`审查修改的文件: +{{files}}`,displayMessageFiltered:`审查过滤后的文件: +{{files}} + +已跳过 {{skipped}} 个命中排除规则的文件。`,filteredNotice:"本次将分析 {{included}} 个文件,并跳过 {{skipped}} 个命中排除规则的文件,例如锁文件、生成物或二进制资源。",noEligibleFiles:"排除命中规则的文件后,本次会话里没有可审查文件。",prompt:`请审查本次会话中修改的以下文件: + +{{files}}`,promptFiltered:`请审查本次会话中修改的以下文件: + +{{files}} + +请不要审查另外 {{skipped}} 个已跳过的文件,因为它们命中了锁文件、生成物或二进制文件的排除规则。`,threadTitle:"代码审查"}},YL={filesCount:"{{count}} 个文件",expandList:"展开列表",collapseList:"收起列表"},ZL={errors:{refreshSessionFailed:"刷新会话状态失败",acceptFileFailed:"接受文件失败",rejectFileFailed:"拒绝文件失败",acceptSessionFailed:"接受会话失败",rejectSessionFailed:"拒绝会话失败",acceptBlockFailed:"接受块失败",rejectBlockFailed:"拒绝块失败"}},XL={subtitle:"BitFun Coder · 对话记录",poweredBy:"Powered by",aiAssistant:"BitFun Coder",dialogNotFound:"未找到对话数据",containerNotFound:"导出容器未找到",generateFailed:"生成图片失败",fileNamePrefix:"Sparo OS 对话",exportSuccess:"图片已导出:{{filePath}}",exportSuccessPrefix:"图片已导出:",exportFailed:"导出图片失败,请重试",exporting:"正在导出...",exportToImage:"导出为图片"},e$={copyDialog:"复制对话",copiedDialog:"已复制!",forkDialog:"从这里分叉会话",forkFailed:"创建分叉会话失败",like:"点赞",dislike:"点踩",report:"举报",feedbackThanks:"感谢您的反馈!",feedbackDevVersion:"开发版本暂不提供反馈功能",userLabel:"👤 用户:",toolCallLabel:"🔧 工具调用: {{name}}"},t$={readFiles_one:"读取了 {{count}} 个文件",readFiles_other:"读取了 {{count}} 个文件",readFiles:"读取了 {{count}} 个文件",searchCount_one:"进行了 {{count}} 次搜索",searchCount_other:"进行了 {{count}} 次搜索",searchCount:"进行了 {{count}} 次搜索",commandCount_one:"执行了 {{count}} 条命令",commandCount_other:"执行了 {{count}} 条命令",commandCount:"执行了 {{count}} 条命令",thinkingCount_one:"思考了 {{count}} 次",thinkingCount_other:"思考了 {{count}} 次",thinkingCount:"思考了 {{count}} 次",exploreCount_one:"执行了 {{count}} 次探索",exploreCount_other:"执行了 {{count}} 次探索",exploreCount:"执行了 {{count}} 次探索",separator:",",collapse:"收起探索过程",fetchCount_one:"获取 {{count}} 个网页",fetchCount_other:"获取 {{count}} 个网页",fetchCount:"获取 {{count}} 个网页",otherToolCount_one:"执行 {{count}} 个其他工具",otherToolCount_other:"执行 {{count}} 个其他工具",otherToolCount:"执行 {{count}} 个其他工具"},n$={model:"模型",modelExplanation:"模型说明",modelSelection:"选择模型",currentMode:"当前模式",primaryModel:"Primary 模型",fastModel:"Fast 模型",modelNotConfigured:"未配置"},o$={title:"推理深度",tooltip:"调整模型推理深度(仅 Responses API)",default:"默认",low:"Low",lowDesc:"快速响应,轻度推理",medium:"Medium",mediumDesc:"平衡速度与推理深度",high:"High",highDesc:"深度推理",xhigh:"Extra High",xhighDesc:"最大推理深度(较慢)"},s$={title:"选择办公助理工作区",description:"办公助理需要一个工作区目录用于读写文件。你可以使用当前项目,或选择另一个目录。",recommended:"推荐",current:{title:"当前工作区",subtitle:"已打开:{{name}}",description:"产物保存在当前项目中。适合需要读取或修改项目文件的任务。"},global:{title:"其他目录",subtitle:"选择目录",description:"用于在另一个目录中进行办公助理任务。输出会保存在该目录下。"},errors:{noWorkspace:"当前没有打开的工作区",openFailed:"打开办公助理工作区失败"}},i$={title:"示例",addPlugin:"添加插件",addPluginDialogTitle:"选择插件文件夹",addPluginSuccess:"插件安装成功:{{name}}",addPluginFailed:"插件安装失败:{{error}}",refresh:"换一换",close:"关闭",items:{desktop_cleanup:{title:"整理桌面截图",description:"对最近的截图分组、重命名并归档。",prompt:`请帮我整理桌面上最近的截图。 + +第一步:先扫描我的桌面,统计有多少张截图/图片,并告诉我: + +- 总数量 + +- 时间范围(最早到最新) + +第二步:只关注最近 14 天的截图。对每一张: + +- 识别它展示了什么 + +- 建议一个更描述性的文件名 + +- 建议它应该放到哪个文件夹(或是否可以删除) + +把相似的截图分组。开始任何改动之前,先把你的整理方案给我确认。 + +我确认后:先只整理 10 个文件作为预览。如果总数超过 10 个,继续之前先跟我确认是否要处理剩下的。`},vacation_plan:{title:"计划一下我的假期",description:"把行程拆到每天,并考虑预算、交通与备选方案。",prompt:`请帮我规划一次假期行程。 + +基本信息: +- 出发地: +- 目的地(可多个备选): +- 时间:起止日期、总天数 +- 人数与偏好(亲子/情侣/朋友/独行): +- 预算范围: +- 重点偏好(美食/自然/博物馆/购物/放松): +- 不能接受的点(早起/转机/长途自驾等): + +请输出: +1) 2-3 个目的地建议(含优缺点) +2) 最优方案的按天行程(上午/下午/晚上) +3) 交通与住宿建议 +4) 预算拆分 +5) 雨天/突发情况备选方案`},make_ppt:{title:"做一个 PPT",description:"先给大纲与每页要点,再给讲稿与视觉风格建议。",prompt:`请帮我做一个 PPT。 + +主题: +受众: +时长: +场景(汇报/路演/培训/分享): +希望的风格(简洁/商务/活泼/极简): + +最终交付: +1) 目录结构 +2) 每一页的标题 + 3-5 个要点 +3) 关键页的讲稿(逐页,简短即可) +4) 图表/配图建议(用什么图表达什么结论) +5) 导出为 PPTX 文件(保存到 artifacts/)`},todo_breakdown:{title:"把事情拆成待办",description:"把目标拆到可执行任务,并给优先级与时间预估。",prompt:`请把下面这件事拆成可执行的待办清单,并给出优先级与时间预估。 + +目标: +截止时间: +当前进度: +可用资源(人/预算/工具): +风险/不确定因素: + +请输出: +1) 分阶段目标 +2) 具体任务列表(每项包含:负责人/预计耗时/前置条件/验收标准) +3) 关键路径与风险点 +4) 明天就能开始的 3 件小事`},optimize_week:{title:"优化一下我的一周",description:"从杂乱记录中找出规律、主题与行动点。",prompt:`请帮我从 [语音备忘录 / 会议纪要 / 文档 / 日记 / 指定文件夹] 中找出模式与洞察。我有一堆杂乱、非结构化的文件,想知道最近出现了哪些主题。 + +第一步:先扫描文件夹并给我一个摘要: +- 文件总数 +- 时间范围(最早到最新) +- 内容类型分布 + +在深入分析前,请先问我: +- 我希望发现什么(重复主题 / 矛盾点 / 思考的演化 / 行动项 / 其它) +- 是否需要优先某些文件或时间段 +- 我希望最终以什么形式呈现(摘要 / 报告 / 行动清单 / 时间线 / 其它) + +如果文件超过 20 个,请先只分析最近的 10 个。 + +请给出你发现的 3-5 个主要模式,每个模式提供 2-3 个具体例子。等我确认方向正确后,再继续分析剩余文件。`},weekly_plan:{title:"做一份本周计划",description:"结合优先级、会议与深度工作时间,排出可落地的周计划。",prompt:`请帮我做一份本周工作计划。 + +输入信息: +- 本周关键目标(最多 3 个): +- 已确定会议/固定安排: +- 预计深度工作可用时段: +- 本周必须完成的事项: +- 可推迟的事项: + +请输出: +1) 本周优先级排序 +2) 按天安排(每天 2-3 个核心任务) +3) 风险与缓冲时间建议 +4) 每天收尾复盘清单(5 分钟)`},meeting_minutes:{title:"整理会议纪要",description:"把讨论内容结构化成结论、行动项与风险。",prompt:`请帮我把会议内容整理成一份会议纪要。 + +会议主题: +参会人: +时间: +原始记录(可粘贴): + +请输出: +1) 会议结论(3-6 条) +2) 决策项(Decision) +3) 行动项(Action Items:负责人/截止时间/验收标准) +4) 风险与待确认问题(Open Questions) +5) 下次会议建议议程`},reply_email:{title:"写一封邮件回复",description:"给出礼貌、清晰、可复制的邮件模板(含不同语气版本)。",prompt:`请帮我写一封邮件回复。 + +对方邮件内容(可粘贴): +我的目标(确认/拒绝/推进/澄清): +语气(正式/友好/强硬但礼貌): +需要包含的信息点: + +请输出: +1) 主题(Subject)建议 +2) 邮件正文(2 个版本:更正式/更简洁) +3) 需要对方确认的问题列表(如有)`},make_docx:{title:"写一份 Word 文档",description:"把内容结构化成文档,并导出为 DOCX。",prompt:`请帮我写一份文档,并导出为 .docx 文件。 + +文档类型(PRD/方案/复盘/报告/SOP): +受众: +语气(正式/友好/简洁): +必须包含的信息点: +期望长度: + +最终交付: +1) 建议目录结构 +2) 完整正文内容 +3) 导出为 DOCX 文件(保存到 artifacts/)`},make_spreadsheet:{title:"做一张表格",description:"设计字段与公式,让表格能自动汇总与复用。",prompt:`请帮我设计一张表格结构(字段 + 示例行),用于下面的用途: + +用途: +数据来源: +需要的统计口径/汇总方式: +输出格式偏好(周报/仪表盘/清单): + +请输出: +1) 推荐字段列表(含字段类型与说明) +2) 示例数据(3-5 行) +3) 常用公式/透视表建议 +4) 数据校验与填表规范`},budget_plan:{title:"做个预算规划",description:"把预算拆到类别与时间,并给出控制与复盘方法。",prompt:`请帮我做一个预算规划。 + +背景: +- 预算周期(按月/按季度/按项目): +- 总预算: +- 固定支出: +- 可变支出: +- 目标(省钱/更可控/为某目标攒钱): + +请输出: +1) 预算分类与比例建议 +2) 具体到类别的预算表(可复制到表格) +3) 超支预案与调整规则 +4) 每周/每月复盘清单`}}},a$={activity:{thinking:"正在思考",usingTools:"正在使用工具",waitingApproval:"等待确认",writing:"正在回复",compacting:"正在整理上下文",finishing:"即将完成",starting:"正在启动",working:"正在工作",needsInput:"需要输入",needsApproval:"需要确认",completed:"已完成",interrupted:"已中断",failed:"失败"},menu:{openMain:"打开 Sparo OS",openLatestTask:"打开最近任务",settings:"宠物设置",hide:"隐藏宠物"}},r$={emptyState:_L,panel:TL,layout:PL,scroll:FL,message:RL,contextMenu:NL,input:DL,inputQueue:IL,context:ML,contextBudget:jL,agent:EL,model:LL,toolbar:$L,status:OL,error:BL,planner:WL,fileMention:zL,copyOutput:UL,smartRecommendations:HL,btw:qL,hostScan:VL,flowChatHeader:GL,timelineTimeFilter:KL,agenticOsTimeline:QL,sessionFilesBadge:JL,sessionFileModificationsBar:YL,snapshotSystem:ZL,exportImage:XL,modelRound:e$,exploreRegion:t$,modelSelector:n$,reasoningEffort:o$,coworkScope:s$,coworkExamples:i$,agentCompanion:a$},l$="描述你希望 Sparo 怎样工作",c$="附加 Agent、图片或 Skill",d$="发起侧问",u$="引用文件或文件夹",p$="Skills",m$="正在加载 Skills…",g$="暂无已启用的 Skill",h$="没有匹配的 Skill",f$="搜索 Skill 或套装…",y$="Skill 套装",w$="独立 Skills",v$="展开套装成员",b$="收起套装成员",k$="已选择",S$="管理 Skills…",x$="恢复默认 Agent",C$="快捷操作",A$="压缩会话",_$="当前没有可用于 /compact 的会话",T$="请等待当前会话空闲后再使用 /compact。",P$="请直接使用 /compact,不要附加额外参数。",F$="会话压缩失败",R$="生成 AGENTS.md",N$="目标模式",D$="当前没有可用于 /goal 的会话",I$="此会话不支持目标模式。",M$="目标指令执行失败",j$="请先描述要完成的目标。",E$="当前没有可用于 /init 的会话",L$="请等待当前会话空闲后再使用 /init。",$$="请直接使用 /init,不要附加额外参数。",O$="初始化 AGENTS.md 失败",B$="请根据当前项目内容生成或更新 AGENTS.md",W$="请对当前主机做一次扫描,并更新 host overview 文档,为后续路由提供实用指引。",z$="当前 Agent: {{agent}}",U$="没有匹配的 Agent",H$="没有匹配的命令",q$="↑↓ 选择 · Enter 确认 · Esc 取消",V$="当前",G$="正在加载 MCP prompts...",K$="这个 MCP prompt 需要参数:{{args}}",Q$="MCP prompt 执行失败",J$="此运行时不可用该 Agent",Y$={title:"命令",groups:{target:"目标","send-with":"随消息发送","session-action":"会话操作",app:"应用动作",template:"Prompt 模板"},btwDescription:"在聚焦的侧线程中提问",contextDescription:"附加工作区文件或文件夹",imageDescription:"把图片附加到下一条消息",skillsDescription:"插入 Skill 提及",goalDescription:"持续跟踪这个请求直到完成",compactDescription:"压缩当前会话上下文",initDescription:"生成或更新工作区指令"},Z$={remove:"移除",targetBtwDraft:"侧问",targetBtwThread:"侧会话",goalDraft:"目标模式",goalActive:"目标进行中",goalPaused:"目标已暂停",goalPending:"目标处理中",promptTemplate:"Prompt"},X$={included:"已附带表格焦点",excluded:"未附带表格焦点",includeAction:"随下一条消息发送",excludeAction:"不随下一条消息发送",partialCache:"选区预览不完整,Agent 将重新读取范围",staleFormulas:"所选公式结果已过期,重算前不可作为可信数值",modes:{inspect:"查看",edit:"编辑",author:"创作"}},eO="专业模式",tO="设计师模式",nO="开发中",oO="发送到",sO="对话目标",iO="主会话",aO="当前侧问",rO="主会话:{{title}}",lO="侧问会话:{{title}}",cO={Runno:"Runno:系统原生通用执行,覆盖规划、自动化、实现与验证","bitfun-coder":"BitFun Coder:构建、调试、自动化并验证软件改动","bitfun-plan":"Plan:先明确需求并制定实施计划,再进行编码","bitfun-debug":"Debug:基于证据诊断代码问题,并聚焦修复路径","bitfun-team":"Team:以团队式工作流协同推进软件交付",Cowork:"办公助理:先澄清再推进,轻量跟踪进度,随时验证结果",Design:"设计师:创建 HTML 原型、视觉稿和更完整的设计交付物",ComputerUse:"独立电脑操作智能体:感知本机环境,操作应用、浏览器与系统界面",DeepResearch:"深度研究:并行派发多个子 Agent 同时调研不同章节,快速生成高质量研究报告",AppBuilder:"应用构建器:围绕工作对象、主界面、组件和运行反馈设计 Product App"},dO={Runno:"Runno","bitfun-coder":"BitFun Coder","bitfun-plan":"Plan","bitfun-debug":"Debug","bitfun-team":"Team",Cowork:"办公助理",Design:"设计师",ComputerUse:"Computer Use",DeepResearch:"深度研究",AppBuilder:"应用构建器"},uO="打开文件夹…",pO="选择工作区目录",mO="切换工作区失败:{{error}}",gO="切换 Agent",hO={title:"请先配置 AI 模型",message:"会话已可正常使用,但发送消息前需要配置并启用一个主模型。",action:"打开模型设置"},fO={deciding:"Agentic OS 正在判断处理方式",creating_work:"正在创建 Work",needs_input:"需要你补充信息",failed:"接手未完成",cancelled:"接手已取消"},yO={settingsPlaceholder:l$,addBoostTooltip:c$,boostStartBtw:d$,boostAddContext:u$,boostSkills:p$,boostSkillsLoading:m$,boostSkillsEmpty:g$,boostSkillsNoMatch:h$,boostSkillsSearch:f$,boostSkillsSuites:y$,boostSkillsStandalone:w$,expandSkillSuite:v$,collapseSkillSuite:b$,skillSelected:k$,openSkillsLibrary:S$,resetToAgentic:x$,quickAction:C$,compactAction:A$,compactNoSession:_$,compactBusy:T$,compactUsage:P$,compactFailed:F$,initAction:R$,goalAction:N$,goalNoSession:D$,goalUnsupported:I$,goalFailed:M$,goalEmpty:j$,initNoSession:E$,initBusy:L$,initUsage:$$,initFailed:O$,initPrompt:B$,scanHostPrompt:W$,currentAgent:z$,noMatchingAgent:U$,noMatchingCommand:H$,selectHint:q$,current:V$,loadingMcpPrompts:G$,mcpPromptMissingArgs:K$,mcpPromptFailed:Q$,agentUnavailable:J$,composerCommands:Y$,intentChips:Z$,spreadsheetFocus:X$,professionalMode:eO,designMode:tO,wip:nO,sendTarget:oO,conversationTarget:sO,targetMain:iO,targetBtw:aO,sendingToMain:rO,sendingToBtw:lO,agentDescriptions:cO,agentNames:dO,openFolder:uO,selectWorkspaceTitle:pO,switchWorkspaceFailed:mO,switchAgent:gO,modelRequired:hO,osHandoff:fO},wO={time:{justNow:"刚刚",minutesAgo:"{{count}} 分钟前",hoursAgo:"{{count}} 小时前"},lockAge:{seconds:"{{count}} 秒",minutes:"{{count}} 分钟",hours:"{{count}} 小时"},phase:{scaffold:"脚手架",finishing:"收尾",sampling:"取样",iterating:"迭代"},emptyTitle:"设计画布",emptySubtitle:"尚未载入产物。设计 Agent 下次改动后会自动填充此面板。",loadingFile:"正在加载文件…",diffFrom:"从",diffTo:"到",diffCurrentWorkingCopy:"当前(工作副本)",diffNoSnapshots:"暂无快照 — Diff 用于比较两次已保存的版本",historyTitle:"版本历史",historyEmpty:"暂无快照。让 Agent 调用 DesignArtifact.snapshot,或点击相机按钮手动生成快照;另外,编辑 45 秒后系统会自动为你生成一次防抖快照。",lockBanner:{stale:"锁已过期",agentEditing:"Agent 正在编辑此产物",holderLead:"(持有者:",heldFor:",已持有 {{duration}}",suffixStale:")— 可安全接管",suffixReadOnly:")— 代码只读",takeOver:"接管",takeOverNote:"接管已过期的锁"},notifications:{copyContextOk:"已复制选中上下文",copyContextFail:"复制失败",openExternalFail:"打开失败:无法在外部应用中预览",agentEditingBlocked:"Agent 正在编辑此产物(持有者:{{holder}})",saved:"已保存",versionConflict:"版本冲突:另一侧已更新此产物,请刷新后重试",editLocked:"产物被锁定,释放锁后再保存",saveFailed:"保存失败:{{message}}",snapshotOk:"已生成快照",snapshotFailed:"快照失败:{{message}}",snapshotPathPrefix:"已生成快照:",exportToPrefix:"已导出至 ",exportDesignFolder:"已导出至 .design/",exportingTitle:"正在导出",exportHtmlMessage:"正在准备 HTML 文件…",exportZipMessage:"正在打包 Zip…",exportFailed:"导出失败:{{message}}",screenshotInfo:"截图导出需要后台渲染器;当前已停止使用会卡住界面的主线程截图。",skillExportInserted:"已向聊天插入 {{format}} 导出指令",lockReleased:"已释放编辑锁",lockAcquired:"已获取编辑锁",lockToggleFailed:"锁操作失败:{{message}}",takeoverLockOk:"已接管编辑锁",takeoverLockFail:"接管失败:{{message}}"},snapshot:{autoSummary:"自动快照(编辑防抖)",promptMessage:"快照说明(可选):",promptDefault:"手动快照",manualSummaryDefault:"手动快照"},lock:{manualAcquireNote:"手动 UI 加锁"},savingHint:"正在写入 {{path}}…",mode:{preview:"预览",code:"代码",split:"分屏",diff:"对比",history:"历史"},pickerTitle:"选取元素",inspectorTitle:"检查器",snapshotTitle:"快照 + 缩略图",continueTitle:"让 Agent 继续",continueLabel:"继续",snapshotLabel:"快照",releaseLockTitle:"释放锁({{holder}})",acquireLockTitle:"获取编辑锁",exportTitle:"导出",exportEntryHtml:"入口 HTML",exportZip:"Zip 打包",exportScreenshotPng:"截图 PNG",exportPdf:"转 PDF",exportPptx:"转 PPTX",openExternalTitle:"在外部应用中打开",selectedLabel:"已选中",diffLoading:"正在加载对比…",diffLoadFailed:"加载对比失败:{{message}}",diffLabelCurrent:"当前"},vO={tabElement:"元素",tabTokens:"令牌",tabAssets:"资源",elementHint:"在工具栏启用取样器,然后点击预览中的任意元素以查看其计算样式。",path:"路径",text:"文字",box:"盒子",computedStyles:"计算样式",noStyleData:"暂无样式数据",copyContext:"复制选中上下文",tokensHead:"设计令牌",noCssVariables:"未在文档根节点发现 CSS 自定义属性。",assetKind:{page:"页面",style:"样式",script:"脚本",data:"数据",image:"图片",font:"字体",other:"其他"}},bO={searchPlaceholder:"搜索产物…",showArchived:"显示已归档",loading:"正在加载产物…",emptyTitle:"当前工作区还没有设计产物",emptyHint:"让设计 Agent 创建一个 — 完成后会自动出现在这里。",fileCount:"{{count}} 个文件",snapshotCount:"{{count}} 次快照",openInCanvas:"在画布打开",archive:"归档",unarchive:"取消归档"},kO={commitOk:"已采用此套令牌",commitFail:"采用失败:{{message}}",saveOk:"Token 修改已保存",saveFail:"保存失败:{{message}}",empty:"暂无令牌提案。先让设计 Agent 生成几套方向。",sidebarTitle:"方向",adoptedBadge:"已采用",proposalCount:"{{count}} 个方向",eyebrow:"设计令牌",recommit:"重新采用",adopt:"采用此套",editorTitle:"编辑 Token 提案",editorHint:"调整当前设计方向。保存后会写入 tokens.json,并立即更新预览。",editorName:"名称",editorMood:"气质",saveEdits:"保存修改",revert:"还原",typeScale:"字号阶梯",fontWeight:"字重",motionDuration:"动效时长",palette:"调色板",tokenCount:"{{count}} 个令牌",typography:"字体",emptySectionSchemaDefaults:"仅预览:在提案中写入对应字段前,先显示 schema 解析用的默认占位值。",typeRole:{display:"展示",headline:"大标题",title:"标题",body:"正文",caption:"说明"},noTypeScale:"未定义字号梯度",radius:"圆角",shadow:"阴影",spacing:"间距",noSpacingScale:"未定义间距梯度",componentPreview:"组件预览",previewPairCaption:"浅色画布 · 深色画布",nativeLight:"浅色画布(调色板原生)",nativeDark:"深色画布(调色板原生)",stressDark:"深色画布(压力测试)",stressLight:"浅色画布(压力测试)",previewNativeDesc:"按 tokens.json 中声明的调色板原生渲染。",previewStressDesc:"相同调色板在反向明度上的压力测试 — 检查文字、边框、强调色是否依然可读。",btnPrimary:"主要",btnSecondary:"次级",btnGhost:"幽灵",fieldEmail:"邮箱",fieldNotify:"通知",pillAccent:"强调",pillMuted:"次级",pillOutline:"描边",statRadius:"圆角",statShadow:"阴影",statMotion:"动效",typeSample:"The quick brown fox jumps over the lazy dog",previewNavAria:"预览导航",previewNavOverview:"概览",previewNavDesign:"设计",previewNavSettings:"设置",previewAppTitle:"产品控制台",previewMetricHealth:"健康度",previewMetricTasks:"任务",previewMetricRisk:"风险",previewActivityTitle:"工作流",previewFormTitle:"受众设置",previewStatusSuccess:"健康",previewStatusWarning:"待检查",previewStatusDanger:"阻塞",previewLandingNavAction:"联系",previewLandingTitle:"塑造第一印象",previewLandingNativeDesc:"用同一套令牌预览稀疏首页:留白、标题重量、表面色和主按钮的整体气质。",previewLandingStressDesc:"同一套稀疏首页在反向明度下的效果,用来先判断风格调性,再看组件密度。",previewLandingProofOne:"主色声音",previewLandingProofTwo:"强调细节",previewLandingProofThree:"信任信号",previewBitfunNavAria:"Sparo OS 官网导航",previewBitfunNavAgents:"Agents",previewBitfunNavWorkflows:"Workflows",previewBitfunNavDocs:"Docs",previewBitfunNavCta:"免费启动",previewBitfunEyebrow:"Sparo OS · Agentic OS",previewBitfunHeadingPrefix:"为 AI 时代打造的",previewBitfunHeadingSuffix:"操作系统",previewBitfunNativeDesc:"Sparo OS 以多 Agent 编排为核心,将推理、执行与记忆一体化,让 AI 真正落地到每一次日常决策。",previewBitfunStressDesc:"相同品牌语言在反向明度下的压力测试 — 先看标题气质、CTA 对比与编排节奏,再判断组件密度是否依然可读。",previewBitfunCtaPrimary:"启动 Agent",previewBitfunCtaSecondary:"查看架构",previewBitfunTagOne:"推理 · Reasoning",previewBitfunTagTwo:"执行 · Execution",previewBitfunProofOne:"内置 Agent 模板",previewBitfunProofTwo:"开源可审计",previewBitfunProofThree:"本地优先运行时",previewBitfunRuntimeHealthy:"Runtime 正常",previewBitfunNavConsoleAgents:"Agents",previewBitfunNavConsoleWorkflows:"Workflows",previewBitfunNavConsoleRuntime:"Runtime",previewBitfunConsoleTitle:"Agent 编排概览",previewBitfunConsoleDesc:"在一个控制台里查看所有正在工作的 Agent、待审批任务和运行时指标。",previewBitfunConsoleDeploy:"部署 Agent",previewBitfunConsoleLogs:"查看日志",previewBitfunMetricActive:"活跃 Agent",previewBitfunMetricTasks:"今日任务",previewBitfunMetricAlerts:"告警",previewBitfunAgentKicker:"当前 Agent",previewBitfunAgentTitle:"Research · 市场洞察",previewBitfunFieldEndpoint:"运行时端点",previewBitfunFieldAutoApprove:"自动放行",previewBitfunAlertRunning:"运行中 · 3",previewBitfunAlertQueued:"排队中 · 2",previewBitfunAlertReview:"需审批 · 1",previewBitfunTimelineAria:"Agent 运行时间线",previewBitfunTimelineKicker:"运行时间线",previewBitfunTimelineStepOne:"接收用户指令 · 意图路由",previewBitfunTimelineStepTwo:"调用研究 Agent · 收集背景资料",previewBitfunTimelineStepThree:"交给执行 Agent · 落地到工作流",previewBitfunDownloadBrand:"Sparo OS · Downloads",previewBitfunDownloadTitle:"下载 Sparo OS",previewBitfunDownloadDesc:"为 AI 时代打造的 Agent 操作系统,本地优先,开箱即用。",previewBitfunDownloadPlatformsAria:"可下载平台",previewBitfunDownloadCta:"下载",previewBitfunDownloadMetaSigned:"官方签名版本",previewBitfunDownloadMetaChecksum:"SHA-256 校验",previewBitfunDownloadMetaOss:"MIT 开源可审计"},SO={panel:wO,inspector:vO,browser:bO,studio:kO},xO="新建 Runno 会话",CO="新建办公助理会话",AO="新建设计师会话",_O="新建会话 {{count}}",TO="新建 Runno 会话 {{count}}",PO="新建 BitFun Coder 会话 {{count}}",FO="新建 DeepResearch 会话 {{count}}",RO="新建办公助理会话 {{count}}",NO="新建设计师会话 {{count}}",DO="应用构建器 {{count}}",IO="Product App 运行台 {{count}}",MO="Agentic OS",jO="会话",EO="与{{name}}的对话",LO="重命名会话",$O="确定要删除此会话吗?",OO="暂无会话",BO="未命名会话",WO="历史会话",zO="正在恢复会话…",UO="会话记录恢复失败。",HO="重试",qO="正在准备工作区…",VO="当前会话",GO="会话管理",KO="关闭",QO="{{count}} 轮对话",JO="暂无会话",YO="切换会话",ZO="创建新会话",XO="更多会话",e4="恢复主窗口",t4={ariaLabel:"当前目标",label:"目标",pendingObjective:"正在提取目标...",pause:"暂停",resume:"继续",review:"复核",clear:"清除",gap:"{{count}} 个缺口",gap_plural:"{{count}} 个缺口",budget:"{{used}}/{{max}} 轮",revision:"r{{revision}}",status:{active:"进行中",judging:"评审中",waiting_user:"等待用户",paused:"已暂停",blocked:"已阻塞",budget_limited:"预算受限",completed:"已完成",cancelled:"已取消"},phase:{extracting:"提取中",judging:"评审中",active:"进行中",waiting_user:"等待用户",paused:"已暂停",blocked:"已阻塞",budget_limited:"预算受限",completed:"已完成",cancelled:"已取消",failed:"失败",needs_clarification:"需澄清",rejected:"已拒绝"},extractionStatus:{queued:"排队中",running:"运行中",accepted:"已接受",needs_clarification:"需澄清",rejected:"已拒绝",failed:"失败"},judgeStatus:{queued:"排队中",running:"运行中",decided:"已判定",rejected:"已拒绝",failed:"失败",pass:"通过",continue:"进行中",needs_user:"需用户确认",blocked:"受阻"}},n4={new:"新建会话",newRunno:xO,newCowork:CO,newDesign:AO,newWithIndex:_O,newRunnoWithIndex:TO,newBitfunCoderWithIndex:PO,newDeepResearchWithIndex:FO,newCoworkWithIndex:RO,newDesignWithIndex:NO,newAppBuilderWithIndex:DO,newProductAppRuntimeWithIndex:IO,agenticOs:MO,title:jO,chatWithAgent:EO,rename:LO,delete:"删除会话",deleteConfirm:$O,empty:OO,untitled:BO,history:WO,loadingHistory:zO,historyLoadFailed:UO,retryHistory:HO,loadingSurface:qO,current:VO,management:GO,close:KO,dialogTurns:QO,noSession:JO,switchSession:YO,create:ZO,more:XO,restoreMain:e4,goal:t4},o4={title:"Agent 交接",agent:"Agent",agentBadge:"Agent",headerLine:"{{agentType}} 智能体:{{session}}",createdSession:"{{agentType}} 智能体:{{session}}",reusingSession:"正在复用会话:{{session}}",reusedSession:"已复用会话:{{session}}",preparingCreate:"准备创建 {{agent}}",creatingAgent:"正在创建 {{agent}}...",createdAgent:"已创建 {{agent}}",actionFailed:"Agent 交接失败",listingWorkspaces:"正在列出工作区...",foundWorkspaces:"找到 {{count}} 个工作区",checkingStatus:"正在检查 Agent 状态...",statusSessions:"{{count}} 个活跃 Agent 会话",sessionId:"会话 ID",workspace:"工作区",sessionCount:"{{count}} 个会话",noWorkspaces:"没有最近打开的工作区",noSessions:"Agentic OS 中尚未创建任何会话",sessionRunning:"会话执行中",sessionIdle:"空闲",globalTag:"全局",sessionUnavailable:"这个 Agent 会话已不可用,可能已被删除。",openSessionFailed:"无法打开这个 Agent 会话。"},s4={title:"Work",untitled:"未命名 Work",ownerDefault:"Agentic OS",open:"打开 Work",creating:"正在创建 Work:{{title}}",continuing:"正在继续 Work:{{title}}",controlling:"正在更新 Work:{{title}}",checking:"正在检查 Work",started:"Work 已创建:{{title}}",continued:"Work 已继续:{{title}}",controlled:"Work 已更新:{{title}}",checked:"Work 已检查:{{title}}",listedWorks:"找到 {{count}} 个 Work",failed:"Work 更新失败",cancelled:"Work 更新已取消",interrupted:"Work 更新已中断",globalWorkspace:"Agentic OS",detail:{objective:"目标",owner:"负责人",workspace:"工作区",surface:"入口",status:"状态",workId:"Work ID",controlAction:"控制"},surface:{os_agent_home:"Agentic OS",work_session:"Work 会话",agent_session:"Agent 会话",application_surface:"应用",work_center:"Work Center"},status:{draft:"草稿",active:"活跃",running:"运行中",waiting_user:"需要输入",blocked:"阻塞",paused:"已暂停",completed:"已完成",failed:"失败",cancelled:"已取消",interrupted:"已中断",archived:"已归档"}},i4={title:"目标",untitled:"当前目标",failed:"目标更新失败:{{error}}",unknownError:"未知错误",cancelled:"目标更新已取消",interrupted:"目标更新已中断",accepted:"已接受",notAccepted:"未接受",revision:"r{{revision}}",gapCount:"{{count}} 项缺口",summary:{get:"已查看目标状态",note:"已记录进展说明",blocked:"已报告阻塞"},pending:{get:"正在查看目标状态...",note:"正在记录说明...",blocked:"正在报告阻塞..."},sections:{blocker:"阻塞原因",progressNote:"进展说明",note:"说明",judgment:"评审",remainingGaps:"剩余缺口"},statuses:{active:"进行中",judging:"评审中",waiting_user:"等待用户",paused:"已暂停",blocked:"已阻塞",budget_limited:"预算受限",completed:"已完成",cancelled:"已取消"},judgeStates:{pass:"已通过",continue:"进行中",needs_user:"需要用户",blocked:"受阻"}},a4={title:"记忆",preparing:"准备保存记忆",saving:"正在保存记忆",saved:"已保存记忆",savedWithType:"已保存{{type}}:",failed:"记忆保存失败",cancelled:"记忆保存已取消",interrupted:"记忆保存已中断",remembered:"记住的内容",appliesTo:"作用范围",scopes:{global:"全局记忆",workspace:"当前项目",unknown:"记忆"},types:{user:"用户记忆",feedback:"反馈",project:"项目记忆",reference:"参考信息",memory:"记忆",unknown:"记忆"}},r4={title:"Outcome Review",preparing:"准备结果审查",receiving:"正在接收审查结论...",submitting:"正在提交审查结论...",submitted:"审查结论已提交",failed:"结果审查失败:{{error}}",unknownError:"未知错误",cancelled:"结果审查已取消",interrupted:"结果审查已中断",verdict:"结论",risk:"风险",confidence:"置信度",workId:"Work ID",finalEffect:"最终效果",nextStep:"下一步",revisionInstruction:"修订指令",acceptanceChecks:"验收检查",checkSummary:"{{passed}} 通过,{{unresolved}} 待处理,共 {{total}} 项",issues:"问题({{count}})",verificationGaps:"验证缺口",evidence:"证据",reasoning:"推理",impact:"影响",suggestedNextStep:"建议下一步",unnamedCheck:"验收检查",untitledIssue:"问题",verdictFallback:"审查",riskFallback:"风险",confidenceFallback:"置信度",nextActionFallback:"下一步",checkStatusFallback:"状态",severityFallback:"严重性",verdicts:{pass:"通过",pass_with_notes:"带备注通过",needs_revision:"需要修订",failed:"失败",inconclusive:"不确定",unknown:"审查"},riskLevels:{low:"低风险",medium:"中风险",high:"高风险",unknown:"风险"},confidenceLevels:{high:"高置信度",medium:"中等置信度",low:"低置信度",unknown:"置信度"},checkStatuses:{passed:"通过",failed:"失败",partial:"部分通过",unverified:"未验证",unknown:"状态"},severities:{blocker:"阻断",major:"主要",minor:"次要",unknown:"严重性"},nextActions:{report_to_user:"汇报给用户",continue_work:"继续 Work",start_specialist_review:"启动专项审查",ask_user:"询问用户",stop:"停止",unknown:"下一步"}},l4={write:"写入文件",edit:"编辑文件",delete:"删除文件",deletedLabel:"删除",failed:"失败",parsingPath:"解析文件路径中...",unknownFile:"未知文件",receivingParams:"接收参数中...",analyzing:"分析中...",expandPreview:"展开预览",collapsePreview:"收起预览",viewGitDiff:"查看 Diff",viewBaselineDiff:"查看基线 Diff",openInEditor:"在编辑器中打开"},c4={action:"文件计划",planning:"正在规划文件操作...",unavailable:"暂无可复核的计划",failed:"文件操作规划失败",summary:"{{title}} - {{count}} 项",highRisk:"{{count}} 个高风险",conflicts:"{{count}} 个冲突",moreItems:"还有 {{count}} 项",reviewInFiles:"在文件中复核"},d4={action:"配置计划",planning:"正在规划配置...",unavailable:"暂无配置计划",failed:"配置规划失败",summary:"{{count}} 项建议变更",applied:"已应用 {{count}} 项变更",rolledBack:"已回滚 {{count}} 项变更",blocked:"需要先回答 {{count}} 个问题",previewOnly:"仅预览",canApply:"可应用",appliedBadge:"已应用",rolledBackBadge:"已回滚",patchCount:"{{count}} 项变更",warningCount:"{{count}} 条提醒",questionsPending:"{{count}} 个问题需要回答",requiresConfirmation:"需要确认",effectUnknown:"生效范围未知",masked:"已遮罩",morePatches:"还有 {{count}} 项变更",risk:{low:"低",medium:"中",high:"高"}},u4={summaryLine:"{{action}}:{{summary}}",actions:{query:"查找设置",get:"读取设置",unknown:"检查设置"},status:{searching:"正在查找与请求相关的设置…",reading:"正在读取这项设置…",matched:"找到 {{count}} 项与请求相关的设置",readOne:"已读取这项设置",readOneNamed:"已读取“{{name}}”设置",failed:"未能找到相关设置",cancelled:"已停止查找设置"},results:{listLabel:"找到的设置",currentValue:"当前值",unnamed:"未命名设置",otherLocation:"其他设置",configured:"已配置",notConfigured:"未配置",defaultValue:"使用默认值",notSet:"未设置",enabled:"已开启",disabled:"已关闭",itemCount:"{{count}} 项"}},p4={title:"设置变更",status:{plan:{running:"正在检查相关设置…",confirming:"正在检查 {{count}} 项设置变更",completed:"已生成 {{count}} 项设置变更方案",failed:"无法生成设置变更方案",cancelled:"已取消检查设置"},apply:{running:"正在应用 {{count}} 项设置变更…",confirming:"将应用 {{count}} 项变更",completed:"已应用 {{count}} 项设置",failed:"设置变更未能应用",cancelled:"已取消设置变更"},undo:{running:"正在恢复 {{count}} 项设置…",confirming:"将恢复 {{count}} 项设置",completed:"已恢复 {{count}} 项设置",failed:"设置未能恢复",cancelled:"已取消恢复设置"},unknown:{running:"正在准备设置变更…",confirming:"设置变更等待确认",completed:"设置变更已完成",failed:"设置变更失败",cancelled:"已取消设置变更"},result:{applying:"设置已保存,仍在生效中",partial:"部分设置未能生效",restartRequired:"已应用 {{count}} 项变更,其中 {{restartCount}} 项需要重启",rolledBack:"已回滚 {{count}} 项设置变更",undone:"已撤销 {{count}} 项设置"}},actions:{viewManual:"在手动设置中查看",cancel:"取消",undo:"撤销",undoing:"正在撤销…",confirm:{plan:"确认",apply:"确认应用",undo:"确认恢复",unknown:"确认"}},values:{enabled:"开启",disabled:"关闭",notSet:"未设置",empty:"空值",updated:"已更新"},comparison:{before:"当前",after:"变更后"},sectionFallback:"其他设置",sectionChangeCount:"{{count}} 项变更",secret:{configured:"已设置",unconfigured:"未设置",willUpdate:"将更新"},risks:{safe:"低风险",elevated:"需要确认",destructive:"不允许修改"},effects:{reactive:"立即生效",adapter:"立即生效",restartRequired:"重启后生效",manualOnly:"需要手动完成",mixed:"生效方式不同"},receipts:{pending:"正在生效",applied:"已生效",restartRequired:"重启后生效",failed:"未能生效",superseded:"已被更新的设置替代",rolledBack:"已回滚"},warningCount:"有 {{count}} 项需要留意",previewUnavailable:"经过校验的变更预览已不可用。请取消本次操作,让助手重新检查设置。",partialNotice:"配置已经保存,但一个或多个运行时组件未能应用。请检查受影响的设置后再重试。",errors:{config:{manual_draft_conflict:"相关字段存在未保存的手动编辑。请先保存或放弃编辑,然后重试。",revision_conflict:"生成预览后设置又发生了变化。请让助手重新检查。",catalog_changed:"设置目录已经变化。请让助手重新生成预览。",plan_expired:"这份变更预览已经过期。请让助手重新生成。",confirmation_required:"这项变更仍需要确认。",idempotency_conflict:"本次设置请求与之前的请求冲突,请重试。",undo_conflict:"原始变更之后相关设置又发生了变化,无法安全恢复。",undo_token_invalid:"这项设置变更已经无法恢复。",commit_unknown:"找不到原始设置变更记录。",apply_retry_failed:"设置未能应用到当前运行的应用。",scope_unsupported:"当前不支持这个设置作用域。",setting_unavailable:"其中一项设置已经不可用。",setting_managed:"其中一项设置由其他位置管理,无法在这里修改。",recovery_read_only:"配置恢复期间设置暂时为只读。",operation_failed:"设置操作失败,没有应用未经确认的内容。"},ai:{model_not_configured:"请先配置并启用主 AI 模型,再使用 AI 设置。"}}},m4={diffFile:"文件差异",gettingDiff:"获取差异",preparing:"准备获取差异",failed:"获取差异失败"},g4={headerTooltip:"生成式UI",exportFileNamePrefix:"Sparo-GenerativeUI"},h4={title:"Git",commandFailed:"Git命令失败",executionFailed:"Git命令执行失败",failed:"失败",confirmExecute:"确认执行",cancel:"取消",expandOutput:"展开输出",collapseOutput:"收起输出",noOutput:"(无输出)",exitCode:"退出码: {{code}}",duration:"耗时: {{time}}",directory:"目录: {{dir}}",output:"输出:",warning:"警告:",error:"错误:",operation:"操作: git {{op}}",args:"参数: {{args}}",status:"状态",diff:"差异",log:"日志",add:"暂存",commit:"提交",branch:"分支",checkout:"切换",switch:"切换",pull:"拉取",push:"推送",fetch:"获取",merge:"合并",rebase:"变基",stash:"暂存",reset:"重置",restore:"恢复",show:"显示",tag:"标签",remote:"远程",clone:"克隆",init:"初始化",blame:"追溯",cherryPick:"挑选"},f4={title:"产品应用界面",operationInit:"初始化",skeletonReady:"已初始化",creatingShort:"…",untitled:"(未命名)",failed:"失败",createFailed:"无法创建产品应用界面",labelAppId:"app_id",labelVersion:"版本",labelPrimarySurface:"主界面",labelSurfaceMode:"界面模式",labelLaunchKind:"启动方式",labelLockDigest:"Lock 摘要",labelPath:"path",nameLabel:"应用:{{name}}"},y4={title:"产品应用界面",builderTitle:"应用构建器",recompile:"重新编译",probe:"诊断",matrix:"截图矩阵",syncing:"同步中",compiledSize:"{{size}}",probeSummary:"{{fatal}} 致命 · {{warning}} 警告 · {{noise}} 噪声",matrixRequested:"已请求截图矩阵",matrixStates:"{{count}} 个状态",openBuilder:"打开应用构建器"},w4={title:"校验",componentTitle:"校验组件",validating:"校验中",package:"产品应用包",componentPackage:"组件包",status:"状态",failed:"失败项",warnings:"警告项",appId:"app_id",componentId:"component_id",componentKind:"组件类型",version:"版本",path:"path",check:"检查项",failedMessage:"产品应用校验未通过"},v4={title:"预览",running:"运行预览",target:"目标",status:"状态",mode:"模式",failed:"失败项",warnings:"警告项",check:"检查项",failedMessage:"构建器预览未通过"},b4={title:"组件包",list:"目录",inspect:"查看",validate:"校验",createPackage:"创建组件包",create:"创建",update:"更新",tools:"可选工具",jsTool:"JS 工具",testJsTool:"测试 JS 工具",generic:"组件创作",scanning:"扫描中…",loading:"加载中…",validating:"校验中…",validOk:"清单校验通过",validFailed:"校验未通过",creatingJsTool:"正在创建 JS 工具…",testing:"测试中…",testingNamed:"正在测试 {{name}}…",testPass:"通过",testFail:"失败",appsCount:"{{count}} 个 Agent 组件",toolsCount:"{{count}} 个工具",moreApps:"另有 {{count}} 个应用未展开",moreTools:"另有 {{count}} 个工具未展开",unnamed:"(未命名)",readonly:"只读",fieldName:"名称",fieldDescription:"描述",fieldKind:"类型",fieldVersion:"版本",fieldModel:"模型",fieldCategory:"分类",fieldReadonly:"只读",fieldTools:"工具",fieldTags:"标签",fieldExamples:"示例",fieldPath:"路径",fieldToolName:"工具名",fieldSummary:"摘要",openAppsPanel:"打开组件中心",openBuilderPanel:"在应用构建器打开",previewPanelTitle:"应用构建器"},k4={title:"Bridge",preparing:"准备调用 {{capability}}",running:"正在调用 {{capability}} · {{action}}",completed:"已完成 {{capability}} · {{action}}",failed:"{{capability}} 的 Bridge 调用失败",unknownCapability:"未知能力",unknownAction:"操作",bridgeId:"Bridge ID",capabilityId:"能力 ID",action:"操作",mode:"模式",runId:"运行 ID",status:"状态",output:"输出",stderr:"stderr"},S4={executeCommand:"执行命令:",commandEmpty:"[命令为空 - 请编辑]",noCommand:"[无命令]",receivingCommand:"接收命令中...",commandUnavailable:"命令不可用",clickToEditCommand:"点击编辑命令",inputPlaceholder:"输入命令...",commandEmptyWarning:"命令为空,无法执行",commandStillReceivingWarning:"命令仍在接收中",executeCommandTitle:"执行命令",cancel:"取消",interrupt:"中断命令执行",openInPanel:"在右侧面板打开Terminal",expandOutput:"展开输出",collapseOutput:"收起输出",rejected:"已拒绝",cancelled:"已取消",completed:"已完成",failed:"执行失败",receivingParams:"接收参数中...",executingCommand:"正在执行命令...",workingDirectory:"工作目录:",exitCode:"退出码: {{code}}",commandInterrupted:"命令已被中断",executionFailed:"命令执行失败"},x4={loadingPlan:"正在加载计划...",generating:"生成中...",clickToOpenPlan:"点击打开计划文件",remainingTodos:"剩余 {{count}} 个待办",viewPlan:"查看计划",build:"构建",building:"构建中...",built:"已构建"},C4={confirm:"确认",cancel:"取消",loading:"加载中...",success:"成功",failed:"失败",error:"错误",expand:"展开",collapse:"收起",collapseContent:"收起内容",expandContent:"展开内容",copy:"复制",copied:"已复制",copyJson:"复制 JSON",truncated:"已截断",inputParams:"输入参数",executionResult:"执行结果",viewDetails:"查看详情",interruptedByRestart:"上次关闭应用时该工具尚未完成,已恢复为中断状态"},A4={headerAction:"询问用户",completed:"已完成",submittedWaiting:"已提交,等待处理",submitting:"提交中...",waitingAnswer:"等待回答",questionsCount:"{{count}} 个问题",answerAllBeforeSubmit:"请回答所有问题后再提交",submit:"提交",questionsAnswered:"{{count}} 个问题已回答",notAnswered:"未回答",timeout:"等待超时(10分钟)",parseError:"无法解析问题数据",validationError:"参数校验失败",loadingQuestions:"正在接收问题…",other:"其他",customInputHint:"提供自定义文本",pleaseSpecify:"请输入..."},_4={analysis:"思考分析",thinking:"思考中...",preparing:"准备思考",thinkingProcess:"思考过程",thinkingComplete:"已完成思考",thinkingCharacters:"思考了 {{count}} 字符"},T4={parsingSearchTerm:"解析搜索词中...",searchTitle:'网络搜索: "{{term}}"',resultsCount:"{{count}} 个结果",searching:'正在搜索 "{{term}}"...',preparingSearch:'准备搜索 "{{term}}"',clickToOpenLink:"点击打开链接",noTitle:"无标题"},P4={parsingUrl:"正在解析链接...",fetched:"已获取",fetching:"正在获取",preparing:"正在准备获取",openLink:"打开链接",copyContent:"复制内容"},F4={tasksCount:"{{count}} 项任务",progress:"({{completed}}/{{total}} 完成)",allCompleted:"任务全部完成",tasks:"任务",collapseList:"收起列表",expandList:"展开列表"},R4={headerLine:"{{agentType}} 智能体:{{description}}",defaultAgentKind:"子代理",waitingConfirm:"等待确认",executing:"执行中...",subAgentFailed:"子代理任务执行失败",subAgentTaskFailed:"子代理任务失败",failed:"失败",confirmDelegate:"确认委派",cancel:"取消",task:"任务",agent:"代理",collapseDetails:"收起详情",expandDetails:"展开详情",openInPanel:"在面板中打开详情"},N4={untitled:"未命名任务",statusLabel:"状态",promptLabel:"任务提示词",errorLabel:"错误信息",resultLabel:"执行结果",noData:"无法加载任务数据",executionContent:"执行内容",duration:"耗时",status:{pending:"等待中",running:"执行中",completed:"已完成",failed:"执行失败"}},D4={interactive:"交互图表:",preparing:"准备中",creating:"创建中"},I4={get:"获取模板:",getTemplate:"获取模板",loading:"加载中",loaded:"已加载",templateDetails:"模板详情",templateId:"模板 ID:",templateName:"模板名称:",contentSize:"内容大小:",characters:"{{count}} 字符",templateReady:"模板已就绪",templateReadyDesc:"模板结构已成功加载,可用于需求文档创建",templateLoadFailed:"模板加载失败",requirementFramework:"需求框架总览",productVision:"产品愿景",businessGoals:"业务目标",userPersonas:"用户画像",userStories:"用户故事",featureList:"功能清单",functionalSpecTemplate:"功能规格模板",nonFunctionalRequirements:"非功能需求",acceptanceCriteria:"验收标准"},M4={confirmExecute:"确认执行",cancel:"取消",loadingApp:"加载交互应用中...",appLoadError:"加载应用失败",interactiveApp:"交互应用",actionLabel:"MCP:",failedLabel:"MCP 失败",executionFailed:"MCP 执行失败"},j4={operationFailed:"设计产物操作失败",defaultTitle:"设计产物",openInCanvas:"在画布打开",writing:"正在写入",manifestSubtitle:"{{kind}} · {{filesCount}} 个文件 · {{versionsCount}} 次快照",listSubtitle:"共 {{count}} 个产物",actions:{create:"创建",update_file:"更新文件",delete_file:"删除文件",set_entry:"设为入口",snapshot:"快照",acquire_lock:"获取锁",release_lock:"释放锁",set_thumbnail:"更新缩略图",zip_export:"导出 zip",archive:"归档",get:"查看",list:"列表"},events:{created:"已创建","file-changed":"已更新","file-removed":"已删除","manifest-updated":"已更新清单","snapshot-committed":"已快照","lock-acquired":"已上锁","lock-released":"已解锁","thumbnail-updated":"缩略图已更新",exported:"已导出",archived:"已归档",listed:"列表",ok:"完成"}},E4={generationFailed:"设计令牌生成失败。",studioPanelTitle:"设计令牌",cardTitle:"设计方向提案",currentSystemSummary:"当前令牌体系:",documentsSummary:"设计令牌文档:",documentCountValue:"找到 {{count}} 个",awaitingYourChoice:"等待你的选择",adopted:"已采用",statusTimeout:"已超时",statusCancelled:"已取消",statusInvalid:"选择无效",openTokensStudio:"打开令牌工作台",untitledProposal:"未命名提案",defaultMood:"设计方向",streamingHint:"提案仍在传输中,完成后会显示完整预览。",previewModeNative:"原生",previewModeInverse:"反色",previewPrimary:"主要",previewGhost:"幽灵",previewPlaceholder:"占位",switchAriaLabel:"开关",expand:"展开",collapse:"收起",font:"字体",radius:"圆角",shadow:"阴影",submitting:"正在提交…",adoptThisSystem:"采用这套体系",switchToThisSystem:"切换到这套",openInStudio:"在工作台打开",noCommittedSystem:"尚未提交令牌体系",errorTitle:"令牌方向生成失败",preparingDirections:"正在准备方向…",receivingDirections:"正在接收方向提案…",streamingSelectHint:"正在接收方向提案,传输完成后再选择",reopenSelection:"重新打开选择"},L4={unknownSkill:"未知技能",unknown:"未知",loadSkillFailed:"加载技能失败",skillAction:"技能:",loadingSkill:"正在加载",preparingSkill:"准备加载"},$4={parsingParams:"解析参数中...",noFileSpecified:"未指定文件",readFile:"读取文件",readingFile:"正在读取",preparingRead:"准备读取"},O4={parsingParams:"解析参数中...",fallbackDisplayName:"其它会话",lineCompleted:"读取 {{name}} 的历史",lineRunning:"正在读取 {{name}} 的历史",linePending:"准备读取 {{name}} 的历史"},B4={terminatingSession:"正在终止终端",sessionKilled:"终端已终止",killFailed:"终止终端失败",preparingKill:"准备终止终端",interruptingSession:"正在中断终端",sessionInterrupted:"终端已中断",interruptFailed:"中断终端失败",preparingInterrupt:"准备中断终端"},W4={title:"会话",agenticScope:"Agentic OS",defaultSessionName:"新会话",unknownSession:"未知会话",preparingCreate:"准备创建会话 {{session}}",creatingSession:"正在创建会话 {{session}}",createdSession:"已创建会话 {{session}}",preparingCancel:"准备取消会话 {{session}}",cancellingSession:"正在取消会话 {{session}}",cancelledSession:"已请求取消 {{session}}",noActiveTurn:"{{session}} 当前没有可取消的活跃轮次",preparingDelete:"准备删除会话 {{session}}",deletingSession:"正在删除会话 {{session}}",deletedSession:"已删除会话 {{session}}",preparingList:"准备列出会话",listingSessions:"正在列出会话",listedSessions:"共找到 {{count}} 个会话",actionFailed:"会话操作失败",workspace:"工作区",sessionId:"会话ID",sessionName:"会话名称",agentType:"Agent 类型",cancelStatus:"取消状态",cancelRequestedStatus:"已请求取消",noActiveTurnStatus:"无活跃轮次",cancelledTurnId:"已取消轮次ID",hadActiveTurn:"取消前是否有活跃轮次",booleanYes:"是",booleanNo:"否",sessionCount:"会话数量",noSessions:"未找到会话"},z4={title:"会话",unknownSession:"未知会话",preparingSend:"准备向 {{session}} 发送消息",sendingMessage:"正在向 {{session}} 发送消息",messageAccepted:"消息已提交给 {{session}}",sendFailed:"向 {{session}} 发送消息失败",targetSession:"目标会话",workspace:"工作区",agentType:"Agent 类型",message:"消息内容"},U4={parsingAnalysisInfo:"解析分析信息中...",unknownImage:"未知图片",clipboardImage:"剪贴板图片",analyzeImageContent:"分析图片内容",imageAnalysis:"图片分析",completed:"已完成",analyzing:"正在分析",preparing:"准备分析",analysisPrompt:"分析提示",focusAreas:"关注点",analysisResult:"分析结果"},H4={beforeUserMessage:"用户消息前",toolBatchComplete:"工具批次完成",manualTrigger:"手动触发",autoTrigger:"自动触发",contextCompressionFailed:"上下文压缩失败",contextCompression:"上下文压缩:",localFallbackHeader:"模型请求异常,已改用本地结构化裁剪",localFallbackNotice:"本次压缩无法使用模型生成总结,因此改用了本地结构化裁剪。",noSummaryNotice:"本次压缩没有生成额外的总结内容。"},q4={parsingPattern:"解析搜索模式中...",currentDirectory:"当前目录",searchFile:"搜索文件",searchingFile:"正在搜索",preparingSearch:"准备搜索",filesCount:"{{count}} 个文件",directoriesCount:"{{count}} 个目录",filesAndDirs:"{{files}} 个文件,{{directories}} 个目录",moreFiles:"还有 {{count}} 个文件",labelPattern:"模式",labelPath:"路径",labelStats:"统计"},V4={parsingPattern:"解析搜索模式中...",currentDirectory:"当前目录",searchText:"搜索文本",searchingText:"正在搜索",preparingSearch:"准备搜索",matchesCount:"{{count}} 个匹配",matchesAndFiles:"{{matches}} 个匹配项,{{files}} 个文件",labelPattern:"模式",labelPath:"路径",labelStats:"统计"},G4={parsingOperation:"解析操作中...",configCenter:"配置中心",planner:"任务规划",terminal:"终端",fileViewer:"文件浏览器",codeEditor:"代码编辑器",navigateToPosition:"导航到指定位置",adjustIdeLayout:"调整IDE布局",manageTab:"管理标签页",focusView:"聚焦视图",executeIdeOperation:"执行IDE操作",operationType:"操作类型",panelType:"面板类型",configSection:"配置区域",sessionId:"会话ID",filePath:"文件路径",workspacePath:"工作区",panelPosition:"面板位置"},K4={parsingParams:"解析参数中...",checkFailed:"检查失败:",unknownError:"未知错误"},Q4={parsingPath:"解析路径中...",listDirectory:"列出目录",listingDirectory:"正在列出",preparingList:"准备列出",filesCount:"{{count}} 个文件",directoriesCount:"{{count}} 个目录",filesAndDirs:"{{files}} 个文件,{{directories}} 个目录",moreEntries:"还有 {{count}} 个条目",labelPath:"路径",labelStats:"统计",labelSort:"排序",sortByModifiedTime:"按修改时间(最新在前)"},J4={file:"文件",dir:"目录",code:"代码",img:"图片",cmd:"命令",chart:"图表",link:"链接"},Y4={pending:"等待中",paramsReceiving:"接收参数中",preparing:"准备中",running:"执行中",completed:"已完成",error:"失败",cancelled:"已取消"},Z4={executing:"执行中...",collapseChat:"收起对话",expandChat:"展开对话",aiProcessing:"AI 正在处理中...",inputMessage:"输入消息...",processing:"处理中...",startNewChat:"开始新对话...",openSessionMenu:"会话与新建",moreMenu:"更多",newBitfunCoderSessionItem:"BitFun Coder 会话",newCoworkSessionItem:"办公助理会话",newDesignSessionItem:"设计师会话"},X4={inputHint:"输入内容..."},e5={planner:"规划"},t5={brand:"PPT Live"},n5={title:"设计样稿",awaiting:"等待你的判断",approved:"已通过",revisionRequested:"已要求调整",preparing:"正在准备三张真实样页",failure:"未能记录设计样稿判断。",errorTitle:"设计样稿不可用",direction:"视觉方向",density:"信息密度",audienceFit:"受众适配",inferred:"已根据主题推断",previewAlt:"设计样稿预览:{{title}}",guidance:"请综合判断三张页面的配色、字体、密度、视觉语法与节奏。这个选择会应用到整套演示,而不是只修改当前页。",approveAction:"通过这个方向",adjustColor:"调整配色",adjustDensity:"调整密度",adjustLanguage:"更换视觉语言",feedbackPlaceholder:"描述一个适用于整套演示的系统性调整……",submitFeedback:"要求重新设计",revisionColorFeedback:"在保留论点和页面角色的前提下,为整套设计样稿换成更符合主题的配色方向。",revisionDensityFeedback:"为整套设计样稿调整信息密度和阅读节奏。",revisionLanguageFeedback:"为整套设计样稿更换视觉语言和构图语法。",approvedReceipt:"设计样稿已经通过,可以基于这套系统继续生成完整演示。",revisionReceipt:"已经要求系统性重做设计样稿;新样稿通过前不会继续生成完整演示。"},o5={rollback:"回滚",rollbackTooltip:"回滚到此轮"},s5={reviewResult:"审查结果",reviewingCode:"正在审查代码...",preparingReview:"准备代码审查",reviewFailed:"代码审查失败:{{error}}",unknownError:"未知错误",collapseDetails:"收起详情",expandDetails:"展开详情",overallAssessment:"总体评估",riskLevel:"风险等级",recommendedAction:"建议操作",contextLimitations:"上下文限制",issuesCount:"问题 ({{count}})",suggestion:"建议",codeStrengths:"代码优点",riskLevels:{low:"低风险",medium:"中风险",high:"高风险",critical:"严重风险"},actions:{approve:"通过",approve_with_suggestions:"有条件通过",request_changes:"需要修改",block:"阻止合并"},severities:{critical:"严重",high:"高",medium:"中",low:"低",info:"信息"},certainties:{confirmed:"已确认",likely:"可能",possible:"疑似"}},i5={agentHandoff:o4,work:s4,goal:i4,memory:a4,outcomeReview:r4,file:l4,fileOperationPlan:c4,configPlan:d4,settingsCatalog:u4,settingsChange:p4,getFileDiff:m4,generativeWidget:g4,git:h4,createProductApp:f4,appBuilder:y4,productAppValidation:w4,productAppPreview:v4,componentAuthoring:b4,bridgeCall:k4,terminal:S4,plan:x4,common:C4,askUser:A4,think:_4,webSearch:T4,webFetch:P4,todoWrite:F4,taskTool:R4,taskDetailPanel:N4,diagram:D4,template:I4,mcp:M4,default:{waitingConfirm:"等待确认",executing:"执行中...",completed:"已完成",cancelled:"已取消",failed:"执行失败",preparing:"准备中"},designArtifact:j4,designTokens:E4,skill:L4,readFile:$4,sessionHistory:O4,terminalControl:B4,sessionControl:W4,sessionMessage:z4,imageAnalysis:U4,contextCompression:H4,globSearch:q4,grepSearch:V4,ideControl:G4,linter:K4,ls:Q4,userMessage:J4,toolStatus:Y4,toolbar:Z4,chatInput:X4,plannerButton:e5,pptLive:t5,pptDesignCase:n5,turnRollback:o5,codeReview:s5},a5="早安",r5="新的一天,新的可能,让我们一起创造些什么",l5="下午好",c5="新的一天,新的可能,让我们一起创造些什么",d5="晚上好",u5="夜晚安静,最适合沉浸式编码",p5="夜深了",m5="灵感不眠,让我们继续",g5="编程搭档",h5="今天从一句话开始也很好。",f5="想到哪一步都行,Runno 会接住。",y5="灯还亮着,事情可以慢慢往前走。",w5="安静的时候,也适合让想法轻轻落地。",v5="Runno",b5="清晨头脑最清醒,把今天的想法和任务整理一下吧",k5="下午好,有什么要推进或整理的,一起来",S5="收尾、复盘、或是为明天做准备——都行",x5="夜深了,适合规划和沉淀,有什么想梳理的?",C5="办公助理",A5="趁头脑清醒,把概念变成看得见的设计吧",_5="现在很适合打磨流程、做原型,或者试试新的视觉方向",T5="一起抠细节、比方案,让设计更顺眼也更顺手",P5="安静的时间最适合视觉思考和精细打磨",F5="设计师",R5="深度研究",N5="趁思路清晰,先定好问题与范围,我来并行检索资料并帮你归纳要点",D5="正是深入调研的好时机:对照观点、核对来源,把结论写扎实",I5="安静时段适合精读材料、核对事实,写成可信的综述",M5="长程研究没有固定下班点,随时可以从上次进度继续",j5="Agentic OS",E5="今天,想让什么发生?",L5="阳光正好,别浪费了。",$5="白天的想法,今晚来实现。",O5="深夜出没的,都是认真的人。",B5="说出你想要的,我来让它发生。",W5="应用构建器",z5="把一个目标做成带工作对象、界面和组件的 Product App",U5="现在很适合梳理工作流、数据和交互模型",H5="把白天的产品想法收束成一个可再次打开的应用包",q5="灵感正在线,给它一个能长期演进的产品边界",V5="描述你想创建的 Product App:谁会打开它、它管理什么工作对象、需要哪种交互模型,以及 AI 应如何协作。我会把应用身份和内部组件分清楚。",G5="设置助手",K5="想调整什么设置?",Q5="描述你的目标,我会先检查相关设置,再告诉你将发生什么变化。",J5="说出想达到的效果,我来找到并调整相关设置。",Y5="不必翻找菜单,直接描述你希望 Sparo 怎样工作。",Z5="一起把使用习惯调整到更顺手的状态。",X5="用一句话说明需求,我会先核对再修改。",e3="我会读取当前设置、解释变更,并在需要时请你确认。",t3={heading:"开始一段新对话",tagline:"在下方输入你的想法、问题或需求。",narrative:"对话开始后,消息与执行过程会显示在这里。"},n3={title:"常用调整",items:{largerText:{title:"调大界面字号",description:"让界面和编辑器文字更容易阅读",prompt:"把界面和编辑器的字号调大一些,并保持整体布局协调。"},fewerConfirmations:{title:"减少低风险确认",description:"降低打断,同时保留高风险保护",prompt:"减少低风险操作的确认,但涉及高风险电脑操作时仍然需要我确认。"},debugLogging:{title:"启用 Debug 日志",description:"把运行日志级别调整为 debug",prompt:"把应用的日志级别改为 debug。"}}},o3={title:"想创建什么样的 Product App?",items:{starter:{title:"从想法开始",description:"把一个业务场景变成 Product App",prompt:"帮我创建一个 Product App:用于管理一个小团队的每日任务,工作对象是任务集合,主界面是交互型工作空间,包含负责人、截止时间、状态筛选和新增任务表单。"},dashboard:{title:"数据看板",description:"展示指标、趋势和可筛选列表",prompt:"帮我创建一个 Product App:销售数据看板,包含核心指标卡、趋势图、地区筛选、客户明细表和异常提醒区域。"},polish:{title:"打磨体验",description:"优化布局、状态、空页面和视觉细节",prompt:"帮我创建一个 Product App:活动报名管理工具,重点打磨表单体验、报名状态、空状态、移动端布局和视觉层次。"},debug:{title:"修复问题",description:"定位运行时错误并快速迭代",prompt:"帮我检查当前 Product App 界面的运行问题,修复报错、交互卡顿或数据显示异常,并说明你改了什么。"}}},s3="",i3="",a3="",r3="上次您正在处理:",l3="分支:",c3="领先 {{count}} 个提交",d3="落后 {{count}} 个提交",u3="{{count}} 个未暂存文件",p3="{{count}} 个已暂存文件",m3="{{count}} 个未推送提交",g3="上次提交:",h3="时间",f3="您可能想要:",y3="审查最近的更改",w3="审查最近的更改",v3="继续之前的工作",b3="继续之前的工作",k3="开始新功能",S3="开始新功能",x3="工作区",C3="未打开工作区",A3="打开其他项目...",_3="搜索工作区",T3="清空工作区搜索",P3="没有匹配的工作区",F3="还没有选择项目",R3="可以先说一句,或",N3="打开一个",D3="打开工作区",I3="开始吧。",M3="。",j3="我们正在",E3="工作。",L3="在",$3="正在",O3="当前在",B3="一切干净,可以放手大干了 ✦",W3="{{count}} 个文件",z3="{{count}} 个文件",U3="{{count}} 个提交",H3="等待暂存",q3="已暂存待提交",V3="待推送",G3="目前有",K3=",",Q3="。",J3="项目里工作。",Y3="项目里做设计。",Z3="。想做什么都可以说。",X3={greetingMorning:a5,subtitleMorning:r5,greetingAfternoon:l5,subtitleAfternoon:c5,greetingEvening:d5,subtitleEvening:u5,greetingNight:p5,subtitleNight:m5,aiPartner:g5,subtitleMorningRunno:h5,subtitleAfternoonRunno:f5,subtitleEveningRunno:y5,subtitleNightRunno:w5,aiPartnerRunno:v5,subtitleMorningCowork:b5,subtitleAfternoonCowork:k5,subtitleEveningCowork:S5,subtitleNightCowork:x5,aiPartnerCowork:C5,subtitleMorningDesign:A5,subtitleAfternoonDesign:_5,subtitleEveningDesign:T5,subtitleNightDesign:P5,aiPartnerDesign:F5,aiPartnerDeepResearch:R5,subtitleMorningDeepResearch:N5,subtitleAfternoonDeepResearch:D5,subtitleEveningDeepResearch:I5,subtitleNightDeepResearch:M5,aiPartnerAgenticOs:j5,subtitleMorningAgenticOs:E5,subtitleAfternoonAgenticOs:L5,subtitleEveningAgenticOs:$5,subtitleNightAgenticOs:O5,narrativeAgenticOs:B5,aiPartnerAppBuilder:W5,subtitleMorningAppBuilder:z5,subtitleAfternoonAppBuilder:U5,subtitleEveningAppBuilder:H5,subtitleNightAppBuilder:q5,narrativeAppBuilder:V5,aiPartnerSettings:G5,settingsHeading:K5,settingsTagline:Q5,subtitleMorningSettings:J5,subtitleAfternoonSettings:Y5,subtitleEveningSettings:Z5,subtitleNightSettings:X5,narrativeSettings:e3,fallback:t3,settingsPrompts:n3,appBuilderPrompts:o3,featureIntro:s3,featureIntroCowork:i3,featureIntroDesign:a3,lastTimeYouWere:r3,branch:l3,aheadCommits:c3,behindCommits:d3,unstagedFiles:u3,stagedFiles:p3,unpushedCommits:m3,timeSinceLastCommit:g3,timeIcon:h3,youMightWant:f3,defaultAction1:y3,defaultAction1Command:w3,defaultAction2:v3,defaultAction2Command:b3,defaultAction3:k3,defaultAction3Command:S3,workspace:x3,noWorkspace:C3,openOtherProject:A3,workspaceSearchPlaceholder:_3,clearWorkspaceSearch:T3,workspaceSearchEmpty:P3,noWorkspaceHint:F3,noWorkspaceHintRunno:R3,openOne:N3,openOneRunno:D3,toStart:I3,toStartRunno:M3,workingIn:j3,project:E3,workingInCowork:L3,workingInDesign:$3,workingInRunno:O3,gitClean:B3,gitUnstaged:W3,gitStaged:z3,gitUnpushed:U3,waitingToStage:H3,stagedReady:q3,toPush:V3,currentlyHas:G3,commaSeparator:K3,period:Q3,projectCowork:J3,projectDesign:Y3,projectRunno:Z3},eB={fileSaved:"文件已保存",fileCreated:"文件已创建",fileDeleted:"文件已删除",fileRenamed:"文件已重命名",folderCreated:"文件夹已创建",folderDeleted:"文件夹已删除",copied:"已复制到剪贴板",settingsSaved:"设置已保存",configImported:"配置已导入",configExported:"配置已导出",gitCommit:"提交成功",gitPush:"推送成功",gitPull:"拉取成功",gitStash:"已贮藏更改",gitStashApply:"已应用贮藏",snapshotCreated:"快照已创建",snapshotRestored:"快照已恢复",languageChanged:"语言已切换",themeChanged:"主题已切换",connectionEstablished:"连接已建立"},tB={fileSaveFailed:"保存文件失败",fileCreateFailed:"创建文件失败",fileDeleteFailed:"删除文件失败",operationFailed:"操作失败",networkError:"网络错误",unexpectedError:"发生意外错误"},nB={unsavedChanges:"有未保存的更改",largeFile:"文件较大,加载可能较慢",deprecatedFeature:"此功能即将弃用",experimentalFeature:"这是实验性功能",lowMemory:"内存不足",diskSpace:"磁盘空间不足"},oB={loading:"正在加载...",processing:"正在处理...",downloading:"正在下载...",uploading:"正在上传...",indexing:"正在索引文件...",searching:"正在搜索...",updating:"正在更新...",installing:"正在安装...",connecting:"正在连接...",syncing:"正在同步...",assistantBootstrapWaitingForModelConfiguration:"Assistant 引导正在等待 AI 模型配置。"},sB={common:{learn_more:"查看详情",got_it:"知道了",later:"稍后",close:"关闭",prev:"上一页",next:"下一页",done:"完成",never_show_again:"不再显示",page:"第",more_count:"还有 {{count}} 条"},welcome:{toast_title:"欢迎使用 Sparo OS",toast_desc:"AI 驱动的编程环境,助您事半功倍",modal_title:"欢迎来到 Sparo OS",modal_body:`Sparo OS 是一款以 AI 为核心的编程环境。 + +通过多轮对话与工具协作,让开发更高效。`}},iB={deleteFile:"确定要删除此文件吗?",deleteFolder:"确定要删除此文件夹及其所有内容吗?",discardChanges:"确定要放弃所有更改吗?",resetSettings:"确定要重置所有设置吗?",closeUnsaved:"有未保存的更改,确定要关闭吗?",exitApp:"确定要退出应用吗?"},aB={success:eB,error:tB,warning:nB,info:oB,announcements:sB,confirm:iB},rB="文件浏览器",lB={placeholder:"搜索工作区...",noResults:"未找到匹配的结果",enterKeyword:"输入关键词开始搜索",modeFiles:"文件",modeContent:"内容",limitReachedFiles:"当前仅显示前 {{count}} 个文件匹配结果,请继续缩小查询范围。",limitReachedContent:"当前仅显示前 {{count}} 个内容匹配结果,请继续缩小查询范围。"},cB={caseSensitive:"区分大小写 (Aa)",wholeWord:"全字匹配 (Ab)",useRegex:"使用正则表达式 (.*)"},dB={switchToSearch:"切换到搜索",switchToTree:"切换到文件树",retry:"重试"},uB={searchingFilename:"搜索文件名...",searchingContent:"搜索内容...",loadingFileTree:"正在加载文件树..."},pB={selectWorkspace:"选择工作区后将显示文件树"},mB={newFile:{title:"新建文件",placeholder:"请输入文件名",confirm:"创建",cancel:"取消"},newFolder:{title:"新建文件夹",placeholder:"请输入文件夹名",confirm:"创建",cancel:"取消"}},gB={invalidFilename:"文件名包含非法字符"},hB={downloading:"正在下载",uploading:"正在上传",missingConnection:"远程工作区缺少 SSH 连接信息。",failed:"文件传输失败:{{error}}",dropHint:"将文件拖放到此处以上传"},fB={createFileSuccess:"文件创建成功",createFileFailed:"创建文件失败: {{error}}",createFolderSuccess:"文件夹创建成功",createFolderFailed:"创建文件夹失败: {{error}}",renameSuccess:"重命名成功",renameFailed:"重命名失败: {{error}}",moveFailed:"移动失败: {{error}}",deleteSuccess:"删除成功",deleteFailed:"删除失败: {{error}}",pasteSuccess:"成功粘贴 {{count}} 个文件",pasteFailed:"{{count}} 个文件粘贴失败",pasteNoFiles:"剪贴板中没有文件",pastingFiles:"正在粘贴 {{count}} 个文件到 {{target}}...",openExplorerFailed:"打开文件管理器失败: {{error}}",selectWorkspaceFirst:"请先打开工作区"},yB={title:rB,search:lB,options:cB,actions:dB,status:uB,empty:pB,dialog:mB,validation:gB,transfer:hB,notifications:fB},wB="Git",vB={title:"初始化 Git",notRepository:"当前目录不是 Git 仓库",initButton:"初始化仓库",hint:"点击按钮后将通过 AI 助手帮你完成初始化",chatPrompt:"请帮我在当前工作区初始化 Git 仓库。"},bB={text:"加载Git信息...",hint:"如果加载时间过长,请点击刷新按钮"},kB={loading:"加载中...",retry:"重试",refresh:"刷新",saving:"正在保存...",processing:"处理中...",unknown:"未知",unknownError:"未知错误"},SB={refresh:"刷新Git状态",forceRefresh:"强制刷新",push:"推送",forcePush:"强推",pull:"拉取",stageAll:"暂存所有",stageSelected:"暂存选中的 {{count}} 个文件",selectFilesToStage:"请先选择要暂存的文件",commit:"提交",commitWithCount:"提交 ({{count}})",aiGenerateCommit:"AI 生成提交信息",cancelGenerate:"取消生成",aiCodeReview:"AI 代码审查",viewAllDiff:"查看所有差异",discardFile:"恢复此文件",deleteFile:"删除此文件",discardAllChanges:"恢复所有更改",copyCommitHash:"复制提交哈希",resetToCommit:"重置到此提交",createBranchFromCommit:"从此提交创建分支",switchBranch:"切换到此分支",createBranchFrom:"基于此分支新建分支",deleteBranch:"删除分支",viewBranchHistory:"点击查看提交历史",viewBranchGraph:"查看分支图"},xB={changes:"变更文件",commits:"提交历史",branches:"分支列表",changeDiff:"变更差异",branchGraph:"Git 分支图",branchCommitHistory:"{{branch}} 提交历史"},CB={files:"搜索文件...",commits:"搜索提交...",branches:"搜索分支...",clear:"清除搜索"},AB={loading:"正在加载 {{branch}} 的提交历史...",loadFailed:"加载提交历史失败",loadFailedWithMessage:"加载失败: {{error}}",retry:"重试",selection:{selectAll:"全选",deselectAll:"取消全选"},allAuthors:"全部作者",authorPlaceholder:"作者",cherryPick:"Cherry-pick",cherryPickRunning:"执行中...",cherryPickFailed:"Cherry-pick 失败",cherryPickOperationFailed:"Cherry-pick 操作失败",copied:"已复制",copy:"点击复制",refresh:"刷新",details:{fullHash:"完整哈希:",commitTime:"提交时间:"},notifications:{cherryPickSuccess:"成功 cherry-pick {{count}} 个提交到 {{branch}} 分支",cherryPickPartial:"已成功 cherry-pick {{count}} 个提交,但提交 {{hash}} 失败: {{error}}",cherryPickFailedWithError:"Cherry-pick 提交 {{hash}} 失败: {{error}}"}},_B={loading:"加载提交历史...",loadFailedWithMessage:"加载失败: {{error}}",empty:"没有提交历史",title:"提交历史",searchPlaceholder:"搜索提交信息、作者或哈希...",searchPrevious:"上一个结果 (Shift+Enter)",searchNext:"下一个结果 (Enter)",noResults:"无结果",tooltip:{author:"作者",hash:"哈希",time:"时间",refs:"引用:",currentRefSuffix:"(当前)"}},TB={errors:{repositoryPathEmpty:"仓库路径不能为空",loadFailed:"加载差异失败"},loading:"加载差异对比...",loadFailedTitle:"加载差异失败",workingTree:"工作区",staged:"暂存区",collapseAll:"折叠全部",expandAll:"展开全部",loadingData:"正在加载差异数据...",empty:{title:"没有发现差异",workingTreeClean:"工作区没有变更",noDiffBetweenCommits:"指定的提交之间没有差异",selectRepository:"请选择一个 Git 仓库来查看差异"}},PB={saveFailedWithMessage:"保存失败: {{error}}",confirmAcceptAll:`确定要接受所有更改并暂存文件吗? + +文件:{{filePath}} ++{{additions}} 行,-{{deletions}} 行`,acceptFailedWithMessage:"接受更改失败: {{error}}",confirmRejectAll:`确定要丢弃所有更改吗?此操作不可撤销! + +文件:{{filePath}} +将丢弃 {{changes}} 处更改`,rejectFailedWithMessage:"拒绝更改失败: {{error}}",completed:{acceptedTitle:"已接受所有更改",rejectedTitle:"已拒绝所有更改",stagedHint:"文件已暂存,可以提交了",rejectedHint:"所有更改已丢弃,文件已恢复"}},FB={noFilesToReview:"没有文件变更,无法进行代码审查",displayMessage:`审查 Git 变更文件: +{{files}}`,requestMessage:`请审查以下 Git 变更文件: + +{{files}}`,sendFailed:"发送代码审查请求失败"},RB={justNow:"刚刚",minutesAgo:"{{count}} 分钟前",hoursAgo:"{{count}} 小时前",daysAgo:"{{count}} 天前",weeksAgo:"{{count}} 周前",monthsAgo:"{{count}} 月前",yearsAgo:"{{count}} 年前"},NB={staged:"已暂存",unstaged:"未暂存",untracked:"未跟踪",ahead:"领先远程",behind:"落后远程",modified:"M",added:"A",deleted:"D",renamed:"R",untrackedBadge:"U"},DB={unstaged:"未暂存",untracked:"未跟踪",staged:"已暂存",unstagedWithCount:"未暂存 ({{count}})",untrackedWithCount:"未跟踪 ({{count}})",stagedWithCount:"已暂存 ({{count}})",unstagedWithFilter:"未暂存 ({{filtered}} / {{total}})",untrackedWithFilter:"未跟踪 ({{filtered}} / {{total}})",stagedWithFilter:"已暂存 ({{filtered}} / {{total}})",moreFiles:"还有 {{count}} 个文件未显示..."},IB={inputPlaceholder:"输入提交信息...",inputPlaceholderNoStaged:"暂存文件后输入提交信息...",changedFiles:"变更文件 ({{count}})",author:"作者",unknown:"Unknown"},MB={current:"当前"},jB={searchPlaceholder:"搜索分支...",loading:"加载中...",notifications:{switchSuccess:"已切换到分支 {{branch}}"},errors:{title:"Branch switch failed",switchFailed:"Failed to switch branch",switchFailedWithMessage:"Failed to switch branch: {{error}}",localChanges:"Please commit or stash local changes first",indexConflict:"Please resolve the current index conflicts first",unexpected:"Unexpected error while switching branches"}},EB={title:"选择或创建分支",inputPlaceholder:"输入新分支名...",loading:"加载中...",createNewLabel:"创建新分支:",openAfterCreate:{label:"创建后打开",description:"创建完成后,立即将新的 worktree 作为工作区打开。"},badges:{inUse:"已使用"},errors:{loadFailed:"Failed to load branch list"}},LB={selectAll:"全选所有未暂存文件",deselectAll:"取消全选",selectFolder:"选择此文件夹下所有文件",deselectFolder:"取消选择此文件夹",selectFile:"选择此文件",deselectFile:"取消选择"},$B={noChanges:"没有文件变更",noMatchingFiles:"没有匹配的文件",noCommits:"没有提交记录",noMatchingCommits:"没有匹配的提交",noBranches:"没有分支",noMatchingBranches:"没有匹配的分支"},OB={viewDiff:"点击查看差异",expandDetails:"展开详情",collapseDetails:"收起详情",resizeFileList:"拖拽调整文件列表与差异区域宽度"},BB={createBranch:{title:"从提交创建新分支",description:"将从提交 {{hash}} 创建新分支",placeholder:"请输入分支名称",confirm:"创建",cancel:"取消"},createNewBranch:{title:"创建新分支",baseBranch:"基于分支",nameLabel:"新分支名称",namePlaceholder:"例如: feature/new-feature 或 bugfix/issue-123",namingHintTitle:"分支命名建议:",namingHints:{featureLabel:"功能分支:",featureExample:"feature/功能名",bugfixLabel:"修复分支:",bugfixExample:"bugfix/问题描述",hotfixLabel:"热修复:",hotfixExample:"hotfix/修复内容",releaseLabel:"发布分支:",releaseExample:"release/版本号"},confirm:"创建分支",cancel:"取消"}},WB={branchNameInvalid:"分支名只能包含字母、数字、点、下划线、横线和斜杠",branchNameExists:"分支名已存在",branchNameEmpty:"分支名不能为空",branchNameContainsDoubleDot:'分支名不能包含 ".."',branchNameContainsDoubleSlash:'分支名不能包含 "//"',branchNameDotEdge:'分支名不能以 "." 开头或结尾',branchNameSlashEdge:'分支名不能以 "/" 开头或结尾',branchNameSpaces:"分支名不能包含空格",branchNameSpecialChars:"分支名不能包含特殊字符: ^ ~ : ? * [ \\",branchNameAtBrace:'分支名不能包含 "@{"',branchNameExistsWithName:'分支 "{{name}}" 已存在'},zB={addFilesTitle:"添加文件",commitChangesTitle:"提交更改",pushTitle:"推送变更",pushTitleForce:"推送变更(强制)",pushProgress:"正在推送到远程仓库...",pullTitle:"拉取变更",pullProgress:"正在从远程仓库拉取...",checkoutTitle:"切换到分支 {{branch}}",createBranchTitle:"创建分支 {{branch}}",deleteBranchTitle:"删除分支 {{branch}}",resetFilesTitle:"重置文件"},UB={merge:"合并分支",rebase:"变基操作",stash:"储藏变更",applyStash:"应用储藏",popStash:"弹出储藏",dropStash:"删除储藏",cherryPick:"Cherry-pick 提交",revert:"撤销提交",resetCommit:"重置提交"},HB={title:"Git 设置",loading:"加载 Git 设置...",loadFailedTitle:"Failed to load settings",retry:"重试",refresh:"刷新设置",saving:"保存中...",save:"保存设置",success:{saveConfig:"设置已成功保存"},errors:{loadConfigFailed:"Failed to load configuration",saveConfigFailed:"Failed to save configuration"},tabs:{user:"用户设置",repository:"仓库设置",advanced:"高级设置"},sections:{user:{title:"用户信息",description:"这些信息将用于 Git 提交的作者标识",nameLabel:"用户名",namePlaceholder:"输入您的姓名",emailLabel:"邮箱地址",emailPlaceholder:"输入您的邮箱"},editor:{title:"编辑器设置",defaultEditorLabel:"默认编辑器"},lineEndings:{title:"行结束符",autocrlfLabel:"自动转换 CRLF",options:{auto:"自动转换(Windows 推荐)",input:"仅输入转换(macOS/Linux 推荐)",disabled:"不转换"}},remotes:{title:"远程仓库",urlLabel:"URL",urlPlaceholder:"远程仓库 URL"},core:{title:"核心设置",ignoreCaseLabel:"忽略文件名大小写",ignoreCaseDescription:"在大小写不敏感的文件系统上启用此选项"},branch:{title:"分支配置",branchLabel:"分支: {{branch}}",remoteLabel:"远程",mergeLabel:"合并分支"}}},qB={addFailed:"Failed to add files",commitFailed:"Failed to commit",pushFailed:"Push failed",pushFailedWithCheck:"Push failed. Please check your network connection and permissions.",pullFailed:"Pull failed",pullFailedWithCheck:"Pull failed. Please check your network connection and permissions.",checkoutFailed:"Failed to switch branch",createBranchFailed:"Failed to create branch",deleteBranchFailed:"Failed to delete branch",resetFilesFailed:"Failed to reset files",resetCommitFailed:"Failed to reset to commit",cherryPickFailed:"Cherry-pick failed",cherryPickAbortFailed:"Failed to abort cherry-pick",cherryPickContinueFailed:"Failed to continue cherry-pick",refreshFailed:"Refresh failed",checkoutFailedTitle:"Failed to switch branch",createBranchFailedTitle:"Failed to create branch",deleteBranchFailedTitle:"Failed to delete branch",checkoutLocalChanges:"Please commit or stash local changes first",checkoutIndexConflict:"Please resolve the current index conflicts first (unfinished merge or rebase may exist)",branchNotFound:"Branch {{branch}} not found",branchAlreadyExists:"Branch {{branch}} already exists",branchNotMerged:"Branch {{branch}} is not fully merged. Use force delete if needed.",cannotDeleteCurrentBranch:"Cannot delete the currently checked out branch {{branch}}"},VB={stageSuccess:"已暂存 {{count}} 个文件",stageFailed:"暂存失败: {{error}}",commitSuccess:"提交成功",commitFailed:"提交失败: {{error}}",fileRestored:"文件已恢复",fileRestoreFailed:"恢复文件失败: {{error}}",allChangesRestored:"已成功恢复所有更改",restoreFailed:"恢复更改失败: {{error}}",resetSuccess:"已重置到提交 {{hash}}",resetFailed:"重置失败: {{error}}",aiGenerateFailed:"AI 生成提交信息失败: {{error}}",noFilesToGenerate:"没有文件变更,无法生成提交信息",noStagedFiles:"没有已暂存的文件可以提交",enterCommitMessage:"请输入提交信息",selectFilesToStage:"请先选择要暂存的文件",cannotDeleteCurrentBranch:"无法删除当前分支",openDiffFailed:"打开文件差异失败: {{error}}",openDiffFailedWithPath:`打开文件差异失败: {{error}} +文件: {{file}}`,pushUpstreamSuccess:"已设置上游分支并推送到远程仓库",pushSuccess:"已推送到远程仓库",pushForceSuccess:"已强制推送到远程仓库",pullSuccess:"已从远程仓库拉取最新变更",checkoutSuccess:"已切换到分支 {{branch}}",createBranchSuccess:"已创建分支 {{branch}}",deleteBranchSuccess:"已删除分支 {{branch}}"},GB={discardFile:`警告:确定要恢复文件 "{{file}}" 吗? + +此操作不可恢复!`,deleteFile:`警告:确定要删除文件 "{{file}}" 吗? + +此操作不可恢复!`,discardAllChanges:`警告:此操作将会: + +1. 回退所有暂存区的更改 +2. 回退所有工作区的更改 +3. 删除所有未跟踪的文件 + +此操作不可恢复!确定要继续吗?`,resetToCommit:`确定要重置到提交 {{hash}} 吗? + +这将移动当前分支指针到此提交。`,deleteBranch:'确定要删除分支 "{{branch}}" 吗?'},KB={title:wB,init:vB,loading:bB,common:kB,actions:SB,tabs:xB,search:CB,branchHistory:AB,graph:_B,diffView:TB,diffEditor:PB,review:FB,relativeTime:RB,status:NB,fileGroups:DB,commit:IB,branch:MB,quickSwitch:jB,branchSelect:EB,selection:LB,empty:$B,tooltips:OB,dialog:BB,validation:WB,operations:zB,advancedOperations:UB,settingsView:HB,errors:qB,notifications:VB,confirm:GB},QB="终端",JB="在左侧列表中新建或打开终端",YB={editTerminal:{title:"编辑终端",nameLabel:"名称",namePlaceholder:"终端名称",workingDirectoryLabel:"启动路径",workingDirectoryPlaceholder:"终端启动时打开的路径",workingDirectoryHint:"重新打开已保存的终端时会使用这个路径",startupCommandLabel:"启动命令(可选)",startupCommandPlaceholder:"终端启动后自动执行的命令",startupCommandHint:"终端启动后将自动执行此命令",cancel:"取消",save:"保存"}},ZB={title:QB,emptyState:JB,dialog:YB},XB={title:"应用构建器",description:"创建带有明确目标、工作对象、主界面和组件图的 Product App。"},eW={title:"应用草稿",draftBadge:"可编辑草稿",derivedFrom:"基于 Release {{releaseId}},不会修改原版本。",newDraft:"全新应用草稿;正式工作只会使用发布后的 Release。",tabsLabel:"应用草稿工作台",tabs:{preview:"预览",quality:"验证",release:"Release"},actions:{refreshPreview:"刷新预览",validate:"验证草稿",createRelease:"生成 Release",activate:"设为当前使用版本",continueEditing:"基于此 Release 继续编辑",retry:"重试",cancel:"取消",close:"关闭"},empty:{title:"没有绑定应用草稿",description:"从应用中心创建或定制一个应用后,再进入构建器。"},preview:{loading:"正在生成隔离预览…",failed:"无法预览这个草稿",timeout:"草稿预览启动超时。",ready:"预览已就绪",starting:"正在启动",isolated:"预览使用临时制品,不会创建正式 Work 或改变当前应用。"},quality:{validation:"发布门槛",validationDescription:"包契约、权限、数据迁移与运行时检查必须通过。",evaluation:"独立评测",evaluationDescription:"尚未产生相对于当前 Release 的可靠性证据。",notRun:"未验证",failed:"失败",warnings:"警告",issues:"问题",cases:"评测用例"},release:{immutable:"不可变",ready:"Release {{version}} 已生成",description:"该制品不会再被修改。激活只会切换新工作使用的版本,已有 Work 保持原版本。",releaseId:"Release ID",artifact:"制品摘要",emptyTitle:"还没有新的 Release",emptyDescription:"验证草稿后生成不可变 Release;生成本身不会改变当前应用。"},publish:{title:"生成不可变 Release",description:"输入面向用户的版本号。发布门槛未通过时系统会拒绝生成。",invalidVersion:"请输入有效的语义版本号,例如 1.0.0。"},capabilities:{title:"审查应用能力",description:"此 Release 请求以下系统能力,请在激活前逐项确认。",scopeNote:"授权仅绑定到当前应用和能力指纹;能力变化后必须重新审查。",approveAndActivate:"授权并激活",count:"{{count}} 项",columns:{capability:"能力用途",permission:"允许操作",usedBy:"使用方"},permissionLabels:{ai:"使用 AI 能力",modelInvoke:"调用配置的模型",sessionRead:"读取当前会话",toolInvoke:"调用应用工具",componentRun:"运行应用组件",filesystem:"访问文件系统",network:"访问网络",appData:"访问应用数据目录",networkAny:"访问外部网络"},sources:{app:"应用",system:"系统"},groups:{ai:{title:"AI 与模型",description:"使用应用智能体并调用当前配置的模型。"},files:{title:"应用文件",description:"访问应用自身的数据目录。"},network:{title:"网络访问",description:"访问用户提供的来源或外部资源。"},session:{title:"会话上下文",description:"读取当前工作会话的必要上下文。"},tools:{title:"工具调用",description:"调用应用声明的工具能力。"},runtime:{title:"组件运行",description:"启动并协调应用内组件。"},other:{title:"其他能力",description:"应用声明的其他系统能力。"}}},messages:{validationStarted:"验证已交给 App Builder",releaseCreated:"Release {{version}} 已生成",activated:"新 Release 已设为当前使用版本"}},tW={title:"应用构建器",reload:"刷新预览",openInApps:"打开 Product App",emptyTitle:"Builder 正在为你打草稿",emptyDescription:"生成第一个可运行版本后,预览会自动出现在这里。",loading:"正在加载预览",loadFailed:"加载预览失败",retry:"重试",updating:"正在更新预览…",menu:{recompile:"重新编译",installDeps:"安装依赖",openInApps:"在应用中打开",reload:"刷新预览",viewPermissions:"权限",copyAppId:"复制 App ID",moreActions:"更多操作",theme:"主题:{{theme}}",language:"语言:{{lang}}"},actions:{restartWorker:"重启 Worker",stop:"停止"}},nW={tabsLabel:"App Builder 工作台分区",tabs:{blueprint:"蓝图",preview:"预览",issues:"问题",components:"组件",agent:"Agent",data:"数据",eval:"评测",validation:"验证",versions:"版本",permissions:"权限",share:"分享"},sections:{userBlueprint:"用户层蓝图",userBlueprintDesc:"用普通产品语言说明这个应用承诺什么。",technicalBlueprint:"技术层蓝图",technicalBlueprintDesc:"稳定的 package、surface、runtime 和组件事实。",issueSummary:"Builder 问题",issueSummaryDesc:"来自预览、Worker 和后端事件的运行事实。",components:"组件图",componentsDesc:"App Builder 当前知道的主界面和后端绑定。",agent:"Agent 后端",agentDesc:"通过声明式 backend binding 暴露的 AI 动作。",data:"数据与记忆",dataDesc:"这个应用会读取、保存、记住或从外部获取什么。",eval:"Agent 评测",evalDesc:"智能行为可靠性检查;缺少证据时保持未验证。",validation:"验证门槛",validationDesc:"Package、预览、运行时、权限、数据和评测的就绪状态。",versions:"版本",versionsDesc:"草稿、修订、lock、checkpoint 和 release 事实。",permissions:"权限",permissionsDesc:"当前 package 声明的最小访问范围。",share:"分享",shareDesc:"应用将安装到哪里,哪些私有数据不会被带走。"},facts:{primarySurface:"主界面",surfaceMode:"界面模式",sourceFiles:"源文件",backend:"组件",launchKind:"启动类型",whatItDoes:"它做什么",howIUseIt:"我怎么使用",whatAiDoes:"AI 做什么",whatData:"使用什么数据",howReady:"如何证明就绪",appId:"App ID",componentId:"组件 ID",componentKind:"组件类型",packageRoot:"Package 根目录",version:"版本",category:"分类",tags:"标签",runtimeRevision:"运行时修订",fatalIssues:"致命问题",warnings:"警告",runtimeLogs:"运行日志",backendActions:"后端动作",memoryScope:"记忆范围",sessionPolicy:"会话策略",inputData:"输入数据",workingState:"工作状态",externalFacts:"外部事实",retention:"保留策略",deletion:"删除策略",migration:"迁移策略",sharePolicy:"分享策略",currentDraft:"当前草稿",sourceRevision:"源修订",lockDigest:"Lock 摘要",releaseStatus:"发布状态",latestRelease:"最新发布版本",releaseId:"发布 ID",releaseCreated:"创建时间",releasePackage:"发布包",releaseNotes:"发布说明",latestPublishedRelease:"最新已发布来源",releasePublished:"发布时间",evalStatus:"评测状态",evalCases:"评测用例",evalDetail:"评测详情",visibility:"可见性",installLocation:"安装位置",privateData:"私有数据"},permissions:{workspaceRead:"读取工作区",workspaceWrite:"写入工作区",shell:"Shell",network:"网络",ai:"AI",worker:"Worker",reviewElevated:"审阅权限",recordReview:"记录权限审阅",reviewRecorded:"权限审阅已记录。"},versions:{openRelease:"打开",copyRelease:"复制",compareRelease:"对比",useAsTemplate:"作为模板",restoreRelease:"回滚到发布版本",restoreTitle:"回滚到发布版本",restoreMessage:"请求 App Builder 从发布版本 {{releaseId}} 恢复 package source。这不会回滚已安装用户数据、Work 历史、运行时存储或私有记忆。",restoreConfirm:"请求回滚",restoreCancel:"取消",restoreDisplay:"回滚到发布版本 {{releaseId}}",restoreSent:"已发送回滚请求给 App Builder。",releaseCopied:"已复制发布版本详情。",compareDisplay:"对比发布版本 {{releaseId}}",compareSent:"已发送发布版本对比请求给 App Builder。",templateDisplay:"用发布版本 {{releaseId}} 作为模板",templateSent:"已发送模板化请求给 App Builder。"},validation:{package:"Package",criticalPath:"关键路径",validation:"验证",preview:"预览",runtime:"运行时",runtimeReady:"运行时就绪",runtimeStorage:"运行时存储",runtimeDependencies:"运行时依赖",surfaceMode:"界面形态",hostFrame:"宿主框架",visualRoot:"视觉根节点",viewport:"视口",interactionSurface:"交互面",issues:"问题",permissions:"权限",permissionReview:"权限审阅",data:"数据边界",dataLifecycle:"数据生命周期",dataSummary:"数据摘要",userPath:"用户路径",userPathContract:"用户路径契约",componentSchema:"组件结构",componentContract:"组件契约",capabilities:"能力声明",capabilitySchema:"能力结构",capabilityCall:"能力调用",capabilityLogs:"能力日志",capabilityTrace:"能力轨迹",dependencies:"依赖边界",implementation:"实现引用",consumerCompatibility:"消费者兼容性",agentEval:"Agent 评测",evalLogs:"评测日志",evalTrace:"评测轨迹",releaseGate:"发布门槛"},values:{standalone:"独立运行",enabled:"已启用",disabled:"未启用",loaded:"已加载",waiting:"等待中",failing:"失败",running:"运行中",needsAttention:"需要处理",ready:"就绪",notVerified:"未验证",blocked:"已阻塞",notSpecified:"未声明",sidecarPreview:"对话 + 右侧面板",agentPreview:"Agent 会话",fullPreview:"可运行应用预览",noBackendActions:"未声明后端动作",packageAndRuntimeState:"Package 元数据和运行时状态",componentConsumerUse:"由 Product App package 引用",componentCapability:"可复用组件能力",componentPackageState:"组件 package 元数据与契约文件",componentReadiness:"仍需完成契约与消费者验证",runtimeIssues:"运行问题正在阻塞就绪",previewLoaded:"预览已加载,未捕获致命问题",uncategorized:"未分类",none:"无",unknown:"未知",workspaceReadable:"可能读取工作区文件",userProvidedOnly:"仅用户提供输入",runtimeScoped:"限定在当前 Product App Work",externalAccess:"已声明外部访问",noExternalAccess:"未声明外部访问",appStorage:"应用 package 与运行时存储",lifecycleWorkRuntimeScoped:"限定在 Work 运行时",lifecycleSessionScoped:"限定在会话内",lifecycleUserManaged:"由用户管理",lifecycleExternalSystem:"外部系统",lifecycleDeleteWithWork:"随 Work 删除",lifecycleDeleteOnUserRequest:"按用户请求删除",lifecycleNoDurableData:"无持久数据",lifecycleNotSupported:"暂不支持",lifecycleExportImport:"导出/导入",lifecycleSchemaVersioned:"按 schema 版本迁移",lifecycleExcludeRuntimePrivateData:"排除运行时私有数据",lifecycleDeclaredWorkObjectsOnly:"仅声明的 Work Object",lifecycleExternalReferenceOnly:"仅外部引用",notAvailable:"暂不可用",privateDraft:"私有草稿",privateRelease:"私有发布版本",catalogSource:"目录来源",workspaceInstall:"当前工作区",systemInstall:"系统应用存储",privateDataExcluded:"私有数据不会进入分享载荷"},empty:{noApp:"这个 Builder 会话还没有绑定 Product App。",noAgent:"还没有声明 Agent 后端。"}},oW={readWorkspace:"可读取工作区",noWorkspaceRead:"不可读取工作区",writeWorkspace:"可写入工作区",noWorkspaceWrite:"不可写入工作区",shellEnabled:"Shell 已启用",shellDisabled:"Shell 已禁用",netEnabled:"网络已启用",netDisabled:"网络已禁用",aiEnabled:"AI 已启用",aiDisabled:"AI 已禁用",nodeEnabled:"Worker 已启用",nodeDisabled:"Worker 已禁用"},sW={toggleOn:"检查预览元素",toggleOff:"停止检查",inspecting:"正在检查元素",hovering:"正在检查 {{target}}",contextLabel:"元素",addContext:"添加上下文",added:"已将预览元素添加到聊天上下文",alreadyAdded:"该预览元素已在聊天上下文中",clear:"清除选择"},iW={title:"运行时",ok:"运行正常",empty:"暂无运行时错误",logsEmpty:"暂无运行日志",issuesTab:"问题",logsTab:"日志",fatalCount:"{{count}} 个错误",warningCount:"{{count}} 个警告",sendToAi:"发送给 AI 修复",sendDisplay:"修复 Product App 运行问题",sent:"已发送给 AI",clear:"清除",expand:"展开",collapse:"收起",copy:"复制",copied:"已复制",copyAppId:"App ID 已复制",filterAll:"全部",filterError:"错误",filterWarn:"警告",filterInfo:"信息",followTail:"跟随",pauseTail:"已暂停",newMessages:"{{count}} 条新日志",searchPlaceholder:"过滤…",permissionsTitle:"权限",showStack:"调用栈",hideStack:"收起调用栈",fixWithAi:"修复",truncatedHint:"仅显示最近 {{max}} 条 · 完整日志在 {{path}}",buildMarker:"— 构建于 {{time}} —",groups:{fatal:"致命错误",warning:"警告",logs:"运行日志"},hints:{"runtime-unavailable":"请安装 JS 运行时以启用 Worker 功能。","deps-install":'执行"安装依赖"以解决缺失的包。',permission:"请检查应用的权限策略。","workspace-access":"请在应用权限中授予工作区路径。","unknown-method":"调用的桥接方法当前运行时不支持。"}},aW={entry:XB,draftWorkbench:eW,panel:tW,workbench:nW,permissions:oW,previewSelection:sW,diagnostics:iW},rW={files:"文件",coding:"编程",documents:"文档",analysis:"分析",testing:"测试",creative:"创意",operations:"运维",productivity:"效率",automation:"自动化",data:"数据",gui:"图形界面",cli:"命令行",sdk:"SDK",service:"服务",mcp:"MCP",daemon:"守护进程"},lW=JSON.parse('{"eyebrow":"应用系统","title":"应用","subtitle":"继续产品工作、启动已安装的产品应用,并检查每个运行时背后的组件图。","searchLabel":"搜索产品应用","searchPlaceholder":"搜索应用、进行中的工作、组件或标签...","loading":"正在加载产品应用...","meta":{"apps":"{{count}} 个应用","components":"{{count}} 个组件"},"navigation":{"label":"应用中心视图","home":"应用中心","manage":"管理","components":"组件"},"launch":{"title":"智能应用","subtitle":"你的双域智能应用台,连接知识与行动","searchPlaceholder":"搜索应用、能力或进行中的工作...","continueDescription":"先回到已经展开的工作。","emptyTitle":"没有找到匹配的应用或工作","emptyDescription":"可以换一个应用名称、能力、标签或工作标题试试。"},"homeRail":{"label":"应用运行状态","running":"运行中","idle":"暂无运行中应用","closeRunningApp":"关闭 {{name}}","previousRunningApps":"查看前面的运行中应用","nextRunningApps":"查看更多运行中应用","workStates":"应用任务状态","pinnedApps":"置顶应用","states":{"waiting":"等待处理","running":"正在执行","paused":"已暂停"}},"homeViews":{"label":"应用中心内容","installed":"我的应用","discover":"发现"},"manage":{"title":"应用管理","subtitle":"维护已安装应用、创作与组件","railTitle":"管理","railSubtitle":"应用与组件","sections":{"apps":"全部应用","updates":"可更新","disabled":"已停用","creations":"我的智能应用","drafts":"草稿","components":"组件"},"sectionTitles":{"apps":"全部应用","updates":"可更新应用","disabled":"已停用应用","creations":"我的智能应用","drafts":"草稿","components":"组件"},"sectionDescriptions":{"apps":"查看和维护所有已安装应用。","updates":"安装可用更新并查看发布说明。","disabled":"重新启用或移除已停用应用。","creations":"管理你开发或 AI 生成的智能应用。","drafts":"继续尚未发布的创作。","components":"检查应用共享与私有的构建单元。"},"drafts":{"updated":"更新于 {{time}}","missingApp":"无法找到该草稿对应的应用。","emptyTitle":"没有草稿","emptyDescription":"新建或编辑智能应用后,草稿会显示在这里。","actions":{"open":"打开草稿“{{name}}”","delete":"删除草稿“{{name}}”"},"deleteDialog":{"title":"删除这个草稿?","message":"这会永久删除“{{name}}”中尚未发布的更改,且无法恢复。已发布版本不受影响,但使用此草稿的应用构建工作将无法继续。","confirm":"删除草稿"},"messages":{"deleted":"已删除草稿“{{name}}”","deleteFailed":"删除草稿“{{name}}”失败:{{error}}"}},"searchLabel":"搜索被管理的应用","searchPlaceholder":"按应用、分类、描述、标签或组件摘要搜索...","emptyTitle":"没有匹配的应用","emptyDescription":"调整搜索或筛选条件,查看其他应用组。","listLabel":"已管理应用列表","install":"安装","update":"更新","updateAvailable":"可更新","updateAvailableVersion":"可更新至 {{version}}","updateTitle":"更新应用","updateMessage":"让「{{name}}」的新工作使用下面的发布版本。已有工作继续绑定原版本,并会完整保留。","updateConfirm":"更新","updateCloseLabel":"关闭更新对话框","updateCurrentVersion":"当前版本","updateTargetVersion":"更新后","updatePreviewVersion":"版本","updatePreviewRelease":"发布版本","updatePreviewReleaseId":"发布 ID","updatePreviewPublished":"发布时间","updatePreviewNotes":"发布说明","updatePreviewNoNotes":"未提供发布说明。","updatePreviewComponentLock":"组件锁","updatePreviewPackage":"包摘要","enable":"启用","disable":"禁用","moreActions":"更多操作","uninstall":"卸载","uninstallTitle":"卸载应用","uninstallMessage":"这会将「{{name}}」从应用目录移除,并阻止新的启动。已有工作仍会保留在工作中心。","uninstallConfirm":"卸载","installedToast":"{{name}} 已安装","updatedToast":"{{name}} 已更新","uninstalledToast":"{{name}} 已卸载","enabledToast":"{{name}} 已启用","disabledToast":"{{name}} 已禁用","packageIssue":"有问题","updateFailed":"更新 {{name}} 失败:{{error}}","installFailed":"安装 {{name}} 失败:{{error}}","uninstallFailed":"卸载 {{name}} 失败:{{error}}","sortLabel":"排序被管理的应用","sortBy":"排序方式","sortOptions":{"attention":"待处理优先","name":"名称","status":"状态"},"categoriesLabel":"应用筛选","viewModeLabel":"视图模式","viewMode":{"list":"列表","cards":"卡片"}},"actions":{"pin":"置顶 {{name}}","unpin":"取消置顶 {{name}}","components":"组件","createComponent":"创建组件","createApp":"创建应用","refresh":"刷新","retry":"重试","openComponentCenter":"打开组件中心","details":"详情","work":"工作","launch":"启动","stop":"停止","newWork":"新建","continue":"继续","back":"返回","close":"关闭","cancel":"取消","inspect":"检查","customize":"派生并定制","edit":"编辑草稿","syncUpstream":"审查上游更新"},"capabilities":{"title":"审查应用能力","description":"{{name}} 请求以下系统能力。请在激活此 Release 前逐项确认。","scopeNote":"授权只绑定当前应用与能力指纹;能力发生变化后必须重新审查。","approveAndActivate":"授权并激活","count":"{{count}} 项","columns":{"capability":"能力用途","permission":"允许操作","usedBy":"使用方"},"permissionLabels":{"ai":"使用 AI 能力","modelInvoke":"调用配置的模型","sessionRead":"读取当前会话","toolInvoke":"调用应用工具","componentRun":"运行应用组件","filesystem":"访问文件系统","network":"访问网络","appData":"访问应用数据目录","networkAny":"访问外部网络"},"sources":{"app":"应用","system":"系统"},"groups":{"ai":{"title":"AI 与模型","description":"使用应用智能体并调用当前配置的模型。"},"files":{"title":"应用文件","description":"访问应用自身的数据目录。"},"network":{"title":"网络访问","description":"访问用户提供的来源或外部资源。"},"session":{"title":"会话上下文","description":"读取当前工作会话的必要上下文。"},"tools":{"title":"工具调用","description":"调用应用声明的工具能力。"},"runtime":{"title":"组件运行","description":"启动并协调应用内组件。"},"other":{"title":"其他能力","description":"应用声明的其他系统能力。"}}},"messages":{"installBeforeLaunch":"请先安装 {{name}},再启动它。","noLaunch":"{{name}} 没有启动目标。","launchFailed":"启动 {{name}} 失败:{{error}}","stopped":"{{name}} 已停止","stopFailed":"停止 {{name}} 失败:{{error}}","closeWorkFailed":"关闭工作 {{name}} 失败:{{error}}","catalogPartialFailureTitle":"Product App 问题","catalogPartialFailureOne":"无法加载 {{target}}:{{error}}","catalogPartialFailureMany":"{{count}} 个 Product App 包无法加载。首个问题:{{target}}:{{error}}"},"surfaceFallback":"产品应用界面","filters":{"label":"产品应用筛选","all":"全部","installed":"已安装","discover":"可发现","conversation":"对话型","interactive":"交互型"},"continue":{"title":"继续工作","count":"{{count}} 个进行中","description":"直接回到已经展开的事情。","viewAll":"全部","closeWork":"关闭工作「{{title}}」","expandRelated":"选择相关工作","relatedLabel":"相关工作","emptyTitle":"暂无进行中的工作","emptyDescription":"启动一个产品应用后,第一条工作实例会显示在这里。"},"myApps":{"title":"我的应用","count":"{{count}} 个已安装","description":"打开熟悉的应用,或者选择一个开始新的工作。","syncing":"同步中","syncingRemaining":"同步 {{count}} 个","loadingProductApps":"正在加载已安装的产品应用","loadingProductAppsDetail":"原生应用已就绪,包应用仍在同步。","revealingProductAppsDetail":"还有 {{count}} 个应用正在加入页面。","emptyTitle":"暂无已安装的产品应用","emptyDescription":"安装或创建一个产品应用后,它会显示在这里。"},"discover":{"emptyTitle":"暂无新应用","emptyDescription":"有新的可安装应用时,会显示在这里。","title":"发现更多","description":"当现有应用不够用时,在这里增加新的能力。","count":"{{count}} 个可用","loadingBadge":"加载中","syncingRemaining":"同步 {{count}} 个","loading":"正在加载可发现应用","loadingDetail":"仍在检查市场和包来源。","revealingDetail":"还有 {{count}} 个可发现应用正在加入页面。"},"components":{"title":"高级组件","noDependencies":"无组件依赖","searchLabel":"搜索组件","searchPlaceholder":"搜索组件、能力、所属应用或实现引用...","filterLabel":"组件类型","allKinds":"全部类型","emptyTitle":"未找到组件","emptyDescription":"调整搜索或筛选条件,查看其他组件组。","listTitle":"组件包","listDescription":"产品应用使用的共享和应用私有构建块。","summaryTitle":"组件摘要","summaryDescription":"选择一个组件,检查它的包身份、能力和使用关系。","health":"健康状态","healthChecking":"正在检查组件健康状态...","healthUnavailable":"暂无健康状态。","healthFailed":"组件健康检查失败。","healthStatus":{"available":"可用","degraded":"需处理","checking":"检查中"},"healthCheck":{"contract":"契约","dependencies":"依赖安装","runtime":"运行时","healthAction":"健康动作"},"actionStatus":{"available":"可用","blocked":"受阻","empty":"暂无","degraded":"需处理"},"diagnosticAction":{"installDependency":"安装依赖","runHealthAction":"运行健康动作","openRuntimeLogs":"查看运行日志","inspectRuntimeUsage":"检查运行时使用"},"actionTooltip":{"installDependency":"检查或恢复这个依赖","runHealthAction":"重新运行健康检查","openRuntimeLogs":"打开最近包含运行日志的工作","inspectRuntimeUsage":"打开最近使用该组件的工作"},"runtimeRuns":"{{count}} 次运行","runtimeFailures":"{{count}} 次失败","runtimeErrors":"{{count}} 个错误","runtimeWarnings":"{{count}} 个警告","recentFailures":"最近失败","recentLogs":"最近日志","runtimeUsage":"运行时使用","runtimeUsageDetail":"工作 {{workId}}:{{runs}} 次运行,{{issues}} 个问题。","openOwningWork":"打开所属工作","capabilities":"能力","dependenciesTab":"能力与依赖","noCapabilities":"未声明能力","usedBy":"被谁使用","noUsage":"暂无产品应用使用","categoriesLabel":"组件类型","inspect":"查看详情","usedByCount":"{{count}} 个应用使用","unusedHint":"暂无产品应用依赖这个组件"},"workStack":{"continueLabel":"继续「{{title}}」","moreCount":"查看全部 {{count}} 个工作","collapse":"收起","relatedLabel":"{{name}} 的相关工作","attentionBadge":"{{count}} 项待处理"},"inspector":{"emptyTitle":"选择一个应用","emptyDescription":"检查器会显示启动范围、最近工作、组件图和维护操作。","launchPlan":"启动计划","recentWork":"最近工作","noRecentWork":"这个应用暂无进行中的工作。","componentGraph":"组件图","noComponents":"这个应用没有已解析的组件引用。","permissions":"权限","maintenance":"维护"},"componentKinds":{"surface":"界面","agent":"智能体","bridge":"桥接","runtime":"运行时","tool":"工具","skill":"技能"},"interaction":{"conversation":"对话型","interactiveWorkspace":"交互工作区"},"owner":{"system":"系统应用","user":"我的应用","organization":"组织应用"},"componentSource":{"appPrivate":"应用私有","shared":"共享"},"catalogSource":{"installedPackage":"已安装包","builtinMarketplace":"市场来源","publishedRelease":"已发布版本"},"componentRefSource":{"private":"私有","shared":"共享"},"status":{"draft":"草稿","active":"活跃","running":"运行中","waiting_user":"等待用户","blocked":"受阻","paused":"已暂停","completed":"已完成","cancelled":"已取消","failed":"失败","archived":"已归档"},"detail":{"enabled":"已启用","disabled":"已禁用","dialogLabel":"{{name}} 详情","topBar":{"backToApps":"应用中心"},"header":{"chooseWorkspace":"选择工作区","installed":"已安装","native":"原生","notInstalled":"未安装","workCount":"{{count}} 个工作","workMode":"工作模式"},"sectionsLabel":"详情内容","journeys":{"overview":{"label":"概览","description":"先理解它的价值,以及当前最合适的下一步。"},"work":{"label":"工作","description":"继续已有工作,或开始一项新的工作。"},"customize":{"label":"定制与演进","description":"编辑、派生,并审查上游变化。"},"control":{"label":"管理与信任","description":"版本、权限、数据与技术组成。"}},"overview":{"recentWork":"最近的工作","recentWorkDescription":"从上次停下的位置继续,不必重新开始。","viewAllWork":"查看全部 {{count}} 项"},"customize":{"systemTitle":"变成自己的应用,同时不修改系统原版","systemDescription":"从当前 Release 创建个人派生版本。系统更新保持独立,直到你主动审查和合并。","userTitle":"继续演进你的应用","userDescription":"基于当前激活 Release 打开可编辑 Draft;已有 Work 仍固定使用原来的 Release。","upstreamBadge":"上游有更新","upstreamTitle":"来源应用已经继续演进","upstreamDescription":"在 Rebase Draft 中审查上游 Release、处理差异,确认满意后再发布。","versionTitle":"发布与恢复","versionDescription":"发布会生成不可变 Release;激活只影响之后新建的 Work。","activeRelease":"当前激活 Release","availableRelease":"可用 Release","owner":"所有权"},"control":{"componentsTitle":"组件与能力","technicalTitle":"技术与包详情","technicalHint":"高级信息"},"tabs":{"summary":"摘要","work":"工作","package":"包信息","overview":"概览","start":"启动与工作","workObjects":"工作对象","components":"组件","permissions":"权限","source":"版本与来源","technical":"组件关系"},"sectionDescription":{"work":"在同一处启动新工作,或继续这个应用关联的已有工作。","package":"安装包、目录发布、更新、依赖与组件关系事实。","start":"在同一个位置启动新的工作,或继续已有工作。","components":"这个应用依赖的界面、智能体、桥接、运行时、工具和技能组件。","permissions":"应用权限、组件能力和数据生命周期策略。","source":"安装包、目录发布、更新和依赖事实。","technical":"从 app.json 和 component.json 推导出的组件组合与依赖调用关系。"},"advanced":{"launchConfig":"启动配置"},"sections":{"permissions":"权限"},"summary":{"availability":"可用性","permissionCount":"已启用 {{enabled}} / {{total}}","permissions":"权限","status":"状态"},"start":{"bestAction":"推荐下一步","launchHint":"这个应用可以从当前系统上下文启动,也可以继续已有工作。","launchTitle":"启动目标","continueTitle":"继续工作","workTitle":"相关工作","noWorkTitle":"暂无工作","noWorkDescription":"从这个应用创建的工作会显示在这里。","workspaceRequiredHint":"这个应用需要先选择工作区,才能启动新的工作。"},"workObjects":{"emptyTitle":"暂无工作对象","emptyDescription":"这个产品应用尚未声明持久工作对象类型。"},"components":{"capabilityCount":"{{count}} 项能力","graphSummary":"组件关系图","unresolved":"组件包未安装或未解析。"},"permissions":{"appTitle":"应用权限","componentTitle":"组件能力","dataTitle":"数据生命周期"},"source":{"catalogSource":"目录来源","dependencySummary":"依赖","installedStatus":"安装状态"},"runtime":{"identityTitle":"运行时身份"},"technical":{"appNode":"产品应用","canvasDescription":"基于 JSON 推导出的关系图:app.components 形成第一层组合,component.dependencies 继续展开调用链。","canvasTitle":"组件关系图","dependencyEdges":"依赖调用","dependencyNode":"依赖","directComponents":"直接组件","directNode":"直接","edgeKind":{"appComposition":"组合","componentDependency":"调用"},"edgesDescription":"关系边来自 app.components 和 component.dependencies。","edgesTitle":"组合与调用","emptyDescription":"这个条目没有暴露 Product App 组件 JSON。","emptyTitle":"暂无组件关系","filter":{"all":"全部","composition":"组合","dependencies":"调用","permissions":"权限","unresolved":"未解析"},"filterLabel":"组件关系图筛选","from":"来源","implementation":"实现引用","incoming":"入边","inspectorTitle":"选中 JSON","nodesDescription":"直接应用组件和仅作为依赖出现的组件会一起展示。","nodesTitle":"组件","outgoing":"出边","primarySurface":"主界面","relation":"关系","role":"角色","selectApp":"检查应用 {{name}}","selectComponent":"检查组件 {{name}}","selectRelation":"检查 {{from}} 到 {{to}} 的 {{role}} 关系","selectedAppTitle":"选中的应用","selectedComponentTitle":"选中的组件","selectedEdgeTitle":"选中的关系","to":"目标","unresolved":"未解析"}},"workMultiplicity":{"multiple":"多个工作","singleton":"单一工作"},"dataLifecycle":{"fields":{"retention":"保留","deletion":"删除","migration":"迁移","share":"分享"},"retention":{"workRuntimeScoped":"随工作运行时保留","sessionScoped":"随会话保留","userManaged":"用户管理","externalSystem":"外部系统"},"deletion":{"deleteWithWork":"随工作删除","deleteOnUserRequest":"按用户请求删除","noDurableData":"无持久数据","externalSystem":"外部系统"},"migration":{"notSupported":"不支持","exportImport":"导出 / 导入","schemaVersioned":"按 Schema 版本迁移","externalSystem":"外部系统"},"share":{"excludeRuntimePrivateData":"排除运行时私有数据","declaredWorkObjectsOnly":"仅声明的工作对象","externalReferenceOnly":"仅外部引用"}},"launchKind":{"agentSession":"启动由智能体支持的工作会话。","applicationSurface":"打开交互式应用界面。","appBuilder":"打开应用构建器。","none":"无启动目标"},"launchScope":{"systemAllowed":"允许系统级启动","workspaceOptional":"可选工作区","workspaceRequired":"需要工作区"},"fields":{"id":"ID","kind":"类型","version":"版本","author":"作者","authors":"作者","target":"目标","surface":"界面","agent":"智能体","scope":"范围","appId":"应用 ID","surfaceMode":"界面模式","truthSource":"事实来源","visibility":"可见性","componentLockId":"组件锁 ID"},"workObjectScope":{"global":"全局","workspace":"工作区","project":"项目","asset":"资产","device":"设备","runtime":"运行时"},"permission":{"fs":"文件系统","net":"网络","shell":"Shell","gui":"图形界面","secrets":"密钥","ai":"模型访问"},"catalogVisibility":{"discoverable":"可发现","installedOnly":"仅已安装","hidden":"隐藏"},"surfaceMode":{"chatPrimary":"以聊天为主","sidecarLinked":"关联侧边应用","immersivePrimary":"沉浸式主界面","embeddedObject":"嵌入式对象"},"truthSource":{"ownedObjectState":"自有对象状态","runtimeFact":"运行时事实"}}'),cW={badges:{multiAgentComponent:"多智能体",standaloneAgentComponent:"单智能体",evolutionLab:"Evolution Lab"},agenticOs:{name:"Sparo OS",description:"用于编排和生命周期协调的系统中枢,不作为应用入口展示。"},runno:{name:"Runno",description:"Sparo OS 的通用执行单元,灵活、高效、目标感强,适合处理各种类型任务。"},bitfunCoder:{name:"BitFun Coder",description:"来自开源社区的高效、高完成率 Code Agent,全面处理实现、调试、重构、排障等软件开发任务。"},cowork:{name:"办公助理",description:"面向办公交付的 Agent,擅长文档、表格、PPT 和资料整理,把日常工作推进成清晰成稿。"},design:{name:"设计师",description:"面向产品与界面设计的 Agent,把想法、需求和参考图转成原型、界面和视觉方案。"},deepResearch:{name:"深度研究",description:"面向深度研究的 Agent,适合查资料、比观点、梳理依据,把复杂问题沉淀为清晰结论。"},productAppRuntime:{name:"产品应用运行台",description:"承载 Product App 的运行时界面:左侧 FlowChat,右侧应用自有工具和运行状态。"},appBuilder:{name:"应用构建器",description:"为你打造专属智能应用,理解需求或解析既有应用,重组功能、流程与方法,让应用更贴合你的工作方式。"}},dW={scene:{loading:"加载中...",updating:"正在更新预览...",loadFailed:"加载失败:{{error}}",retry:"重试",reload:"刷新"},messages:{recompiled:"Product App 运行时已重新编译。",recompileFailed:"重新编译 Product App 运行时失败:{{error}}",installDepsFailedGeneric:"安装运行时依赖失败。",installDepsOk:"运行时依赖已安装。",installDepsFailed:"安装运行时依赖失败:{{error}}",workerStopped:"Product App Worker 已停止。",workerStopFailed:"停止 Product App Worker 失败:{{error}}"}},uW={toolUpdateFailed:"工具更新失败",componentStatusUpdateFailed:"组件状态更新失败",toolResetFailed:"工具重置失败",skillUpdateFailed:"技能更新失败",subagentUpdateFailed:"子智能体更新失败"},pW={appCategories:rW,productSystem:lW,apps:cW,productAppRuntime:dW,messages:uW},mW="Skill",gW="智能体",hW="MCP",fW="刷新能力状态",yW="重连",wW="{{count}} 个 MCP 服务状态异常",vW="能力状态加载失败",bW="能力开关更新失败",kW="{{name}} 重连成功",SW="{{name}} 重连失败",xW="暂无 Skill,可在设置中添加",CW="暂无智能体",AW="暂无智能体",_W="暂无 MCP 服务",TW="路径",PW="工具数",FW="类型",RW="点击复制路径",NW="路径已复制",DW="复制路径失败",IW={skills:mW,subagents:gW,mcp:hW,refresh:fW,reconnect:yW,mcpWarning:wW,loadFailed:vW,toggleFailed:bW,mcpReconnectSuccess:kW,mcpReconnectFailed:SW,emptySkills:xW,emptySubagents:CW,emptyAgents:AW,emptyMcp:_W,path:TW,toolCount:PW,serverType:FW,clickToCopy:RW,pathCopied:NW,pathCopyFailed:DW},MW="今日来信",jW={label:"今日来信导航",eyebrow:"Letters",today:"今天",todayEmpty:"还没有来信",empty:"还没有来信",allLetters:"全部来信",filteredEmpty:"没有符合条件的来信。",total:"共 {{count}} 封"},EW={loading:"正在找信",generating:"写信中...",noDate:"未选择日期"},LW={loadFailed:"加载今日来信失败。",generateFailed:"生成今日来信失败。",generateDisabled:"每日来信已在设置中关闭。",generateNoResult:"这次没有写出新的来信,请稍后再试。",receiptFailed:"提交回执失败。",sealFailed:"封存今日来信失败。"},$W={chip:"写信中",title:"我在整理今天",body:"正在把今天真正留下来的东西轻轻收好,写成一封可以慢慢读的信。",hint:"写好后这封信会自动展开,你可以先去做别的事。",elapsed:"已写 {{seconds}} 秒",elapsedMinutes:"已写 {{minutes}} 分 {{seconds}} 秒"},OW={label:"来信全文",eyebrow:"今日来信",writtenAt:"写于 {{time}}",pending:"还有 {{count}} 条记忆等你回执",signature:"来信"},BW={generate:"轻催来信",full:"展信阅读",receipt:"给回执",seal:"封存今天",close:"关闭"},WW={label:"日期",title:"选择日期范围",from:"从",to:"到",clear:"清除日期",hint:"先点选开始日期,再点选结束日期。",summary:"{{start}} - {{end}}",pickEndHint:"请选择结束日期(已开始:{{start}})。",pickEndError:"请点选结束日期以完成范围。",previousMonth:"上一月",nextMonth:"下一月",cancel:"取消",apply:"应用"},zW={agenticOs:"全局",workspace:"工作区"},UW={title:"今天还没有来信",body:"Sparo 每天都会写一封信。今天这封还在路上。",loadingBody:"正在寻找已经抵达的来信。"},HW={ready:"已写好",insufficient_context:"安静的一天",needs_receipt:"待回执",sealed:"已封存"},qW={label:"回执建议",title:"等你回执",empty:"这封信里没有需要你确认的记忆。",accept:"收下",edit:"修订",dismiss:"略过",editPrompt:"收下前可以先修订这条记忆",editTitle:"改一下再留",status:{pending:"待回执",accepted:"已收下",edited:"已修订",dismissed:"已略过"}},VW={label:"App 想法",title:"P.S."},GW={label:"今日来信到达提示",title:"信到了",later:"先放一放",chipLabel:"今天的信还在这儿"},KW={title:MW,rail:jW,states:EW,messages:LW,writing:$W,paper:OW,actions:BW,date:WW,scope:zW,empty:UW,status:HW,receipt:qW,app:VW,arrival:GW},QW="文件管理器",JW={aria:"文件管理器导航",home:"首页",workspaces:"工作区",system:"此电脑",pinned:"收藏",recent:"最近"},YW={addToChat:"加入对话",ask:"唤醒 Sparo",back:"后退",collapseSidebar:"收起侧栏",copyPath:"复制路径",expandSidebar:"展开侧栏",forward:"前进",openExternally:"外部打开",openInSparo:"在 Sparo 中打开",openInExcelLive:"在 Excel Live 中打开",openAsWorkspace:"打开为工作区",pin:"收藏",refresh:"刷新",up:"上一级"},ZW={placeholder:"输入路径,例如 D:\\\\Projects 或 ~/Downloads"},XW={recentWorkspaces:"最近工作区",welcomeTitle:"浏览、整理、操作文件",welcomeDescription:"在左侧选择工作区、磁盘或收藏路径,或让 Filer 帮你整理、查找、清理文件。"},e8={title:"试试让 Filer 帮你",organize:{label:"整理这个文件夹",hint:"按类型和日期分组",prompt:"整理当前位置:把文件按类型和日期分组,移动前先给我一份预览计划。"},duplicates:{label:"查找重复文件",hint:"找出冗余副本",prompt:"在当前位置查找重复或近似重复的文件,并建议保留哪一份。"},space:{label:"释放空间",hint:"找出大文件和旧文件",prompt:"列出当前位置最占空间的文件,并标出可以安全删除或归档的大文件、旧文件。"},summarize:{label:"总结这个文件夹",hint:"看看里面有什么",prompt:"总结当前位置有什么:文件类型、值得注意的内容,以及它的组织方式。"}},t8={drives:"磁盘",quickFolders:"快捷目录"},n8={folder:"文件夹",loading:"正在加载目录...",noPath:"未选择路径",noResults:"没有匹配文件",searchPlaceholder:"搜索当前位置...",sortBy:"文件排序",toggleSortOrder:"切换排序方向"},o8={modified:"修改时间",name:"名称",size:"大小",type:"类型"},s8={archive:"压缩包",audio:"音频",document:"文档",folder:"文件夹",image:"图片",other:"其他",text:"文本",video:"视频"},i8={ask:"询问 Sparo",open:"打开",openAsWorkspace:"打开为工作区",pin:"收藏",reveal:"在系统中显示"},a8={addToChat:"加入对话",askSparo:"带着这些文件询问 Sparo",copyPath:"复制路径",findDuplicates:"查找重复文件",openAsWorkspace:"打开为工作区",openExternal:"外部打开",openInSparo:"在 Sparo 中打开",operationPlan:"创建操作计划",organize:"让 Filer 整理",preview:"预览",reveal:"在系统中显示",summarize:"总结"},r8={items:"{{count}} 项",selected:"已选 {{count}} 项",disk:"可用 {{free}} / 共 {{total}}"},l8={actions:"操作",emptyDescription:"选择文件或文件夹后,可在这里预览、加入对话,或交给 Sparo 处理。",emptyTitle:"未选择内容",items:"项目",preview:"预览",previewLoading:"正在加载预览...",previewUnavailable:"无法预览",plan:"操作计划",planDraftDescription:"文件变更会先整理为经过审查、可恢复的计划。确认计划前不会执行任何操作。",planDraftReason:"将选中文件移动到 File Workbench 回收区,并保留恢复路径。",planDraftTitle:"可恢复的文件清理",planExecuting:"正在执行...",planExecuted:"计划已执行",planPartiallyFailed:"计划部分失败",planResultItems:"{{count}} 个结果",confirmExecute:"确认并执行",planNeedsTarget:"不可恢复",planLoading:"正在生成计划...",planUnavailable:"无法生成计划",planHighRisk:"{{count}} 个高风险",planConflicts:"{{count}} 个冲突",planItems:"{{count}} 个计划项",requiresPlan:"需计划",selectionCount:"已选 {{count}} 项",title:"工作台",totalSize:"总大小",unknown:"未知"},c8={aria:"视图模式",grid:"大图格",list:"列表"},d8={today:"今天 {{time}} 修改",week:"{{weekday}} 修改"},u8={brand:QW,activity:JW,actions:YW,address:ZW,home:XW,suggestions:e8,system:t8,browser:n8,columns:o8,categories:s8,context:i8,recommendations:a8,status:r8,workbench:l8,view:c8,recency:d8},p8="记忆库",m8="查看 Agentic OS 长期记住的用户偏好、协作反馈和工作区背景。",g8="正在读取记忆…",h8="搜索记忆、类型或内容…",f8={category:"类别",status:"状态"},y8={showing:"显示 {{shown}} / {{total}} 条记忆"},w8={scope:"范围",settings:"设置",storage:"存储位置",noWorkspace:"未打开工作区",workspaceUnavailable:"当前工作区记忆不可用"},v8={all:"全部记忆",global:"Agentic OS",workspace:"当前工作区",workspace_overview:"工作区概览"},b8={both:"全部范围",global:"全局记忆",workspace:"工作区记忆"},k8={active:"活跃",archived:"已归档",tentative:"试探中",confirmed:"已确认",consolidated:"已整理"},S8={normal:"普通",private:"私密",secret:"机密"},x8={all:"全部",memory:"记忆",soul:"灵魂",user:"用户",milestone:"里程碑",host_overview:"主机概览",memory_log:"记忆日志",workspace_overview:"工作区概览",unknown:"未分类"},C8={title:"自动记忆",loading:"正在读取自动记忆状态…",summary:"全局:{{global}};工作区:{{workspace}}。",enabledEvery:"每 {{count}} 轮",disabled:"已关闭"},A8={openSettings:"自动记忆设置",refresh:"刷新",openStorage:"打开",edit:"编辑",save:"保存",cancel:"取消",reveal:"打开位置",forget:"遗忘",archive:"归档",pin:"置顶",triggerConsolidation:"触发整理",forgetByTag:"按标签遗忘",consolidation:{memory_consolidation:"运行记忆沉淀",host_scan:"运行主机扫描",workspace_overview:"刷新工作区概览",milestone:"刷新里程碑"}},_8={memory:"当前范围内的主记忆文件。",soul:"助手人格和长期全局行为锚点。",user:"这类记忆会影响 Agent 如何理解用户身份、偏好和沟通方式。",milestone:"从日报中提炼出的长期全局里程碑。",host_overview:"这类记忆帮助 Agentic OS 理解当前设备上的目录、工具和工作应如何落位。",memory_log:"最近自动收集的追加式记忆日志。",workspace_overview:"这类记忆帮助 Agentic OS 判断工作应路由到哪个工作区。",unknown:"这条记忆缺少明确类型;建议补充 frontmatter 以便未来更准确地使用。"},T8={noResults:"没有匹配的记忆",noSelection:"选择一条记忆查看详情",emptyFile:"这个记忆文件还是空的。",unavailable:"当前不可用"},P8={loadFailed:"记忆加载失败",saveSuccess:"记忆已保存",saveFailed:"记忆保存失败",revealFailed:"打开位置失败",deleteSuccess:"记忆已遗忘",deleteFailed:"遗忘失败",archiveSuccess:"记忆已归档",archiveFailed:"归档失败",consolidationTriggered:"整理任务已触发",consolidationFailed:"触发整理失败"},F8={title:"遗忘这条记忆?",message:"“{{name}}” 将从记忆库中移除,未来 Agent 不会再主动使用它。"},R8={title:"归档这条记忆?",message:"“{{name}}” 将被移入归档,不再出现在活跃上下文中。"},N8={modes:{graph:"星图",list:"列表"},summary:"共 {{total}} 条记忆 · 全局 {{global}} · 工作区 {{workspaces}}",workspaceCount:"{{count}} 个工作区轨道",hint:"点击节点查看详情 · 滚轮缩放 · 拖拽平移"},D8={tabs:{summary:"概要",content:"内容",relations:"关联"},stats:{updated:"最近更新",words:"字数",lines:"行数",related:"关联节点"},sections:{description:"描述"},sourceSession:"来源会话",relations:{empty:"暂无与之相关的记忆",reasons:{index:"同范围索引","same-folder":"同目录","cross-scope":"跨范围桥接"}}},I8={title:p8,subtitle:m8,loading:g8,searchPlaceholder:h8,filters:f8,results:y8,sidebar:w8,scopeFilters:v8,scopes:b8,statuses:k8,sensitivity:S8,types:x8,autoMemory:C8,actions:A8,usageHints:_8,empty:T8,messages:P8,deleteDialog:F8,archiveDialog:R8,overview:N8,drawer:D8},M8={title:"Skills"},j8={titleAll:"Skill 资源库",summary:"当前环境共有 {{count}} 个管理单元"},E8={listLabel:"Skill 管理单元",detailLabel:"所选管理单元详情"},L8={searchPlaceholder:"搜索套装、独立 Skill 或成员…",addPackage:"添加管理单元"},$8={typeLabel:"管理单元类型",sourceLabel:"资源来源",type:{all:"全部",suite:"套装",standalone:"独立 Skill"},source:{all:"全部来源",builtin:"内置",user:"用户",project:"项目"}},O8={runtime:"调用信息",command:"调用命令",type:"类型",status:"状态",level:"位置",path:"路径",router:"路由 Skill",tags:"标签",members:"套装成员",member:"套装成员",memberCount:"{{count}} 个成员",missingMembers:"缺失成员",noMembers:"此套装当前没有可用成员。",healthReady:"完整可用",healthMissing:"缺失 {{count}} 项",reveal:"打开管理单元目录",deletePackage:"删除管理单元",backToSuite:"返回套装",emptyTitle:"选择一个 Skill 管理单元",emptyDescription:"选择套装或独立 Skill,查看调用命令、来源和内部结构。"},B8={title:"管理设置",agentLabel:"应用到 Agent",availabilityLabel:"允许此 Agent 使用",availabilityEnabled:"{{agent}} 可在运行时调用此管理单元。",availabilityDisabled:"此管理单元已对 {{agent}} 屏蔽。",noAgents:"没有可配置的 Agent",filesTitle:"文件与安装",builtinDescription:"内置管理单元可以屏蔽或恢复,但不能删除。",removableDescription:"打开管理单元目录,或从当前资源库中永久删除。",openFolder:"打开目录",delete:"删除"},W8={title:"Skill 市场",subtitle:"发现可复用的 Skill,并安装到当前项目。",searchPlaceholder:"搜索市场 Skill…",resultsInfo:"“{{query}}”共有 {{count}} 个结果",empty:{noMatch:"没有符合当前搜索的市场 Skill。",noSkills:"市场暂无可用 Skill。"},item:{sourceLabel:"来源",downloadProject:"安装到项目",installed:"已安装",downloading:"安装中…"},pagination:{info:"{{current}} / {{total}}",infoMore:"第 {{current}} 页"},detail:{linkLabel:"链接"}},z8={title:"添加 Skill 管理单元",level:{label:"安装位置",user:"用户资源库(全局)",project:"项目资源库(当前工作区)",projectDisabled:" — 请先打开工作区",selectedProjectPath:"当前项目:{{path}}"},path:{label:"管理单元目录",placeholder:"选择 Skill 或套装目录",browseTooltip:"浏览目录",hint:"独立 Skill 包含 SKILL.md;套装包含 suite.json 及其成员目录。"},validating:"正在校验管理单元…",actions:{close:"关闭添加卡片",cancel:"取消",add:"添加管理单元",adding:"正在添加…"}},U8={empty:{noMatch:"没有符合当前筛选条件的管理单元。",noSkills:"尚未安装任何 Skill 管理单元。"}},H8={title:"删除 Skill 管理单元",message:"删除{{type}}“{{name}}”?其整个管理单元目录都会被移除。",cancel:"取消",delete:"删除管理单元"},q8={invalidPath:"请选择有效的 Skill 管理单元目录。",noWorkspace:"请先打开工作区,再添加项目级管理单元。",addSuccess:"已添加“{{name}}”。",addFailed:"添加失败:{{error}}",deleteSuccess:"已删除“{{name}}”。",deleteFailed:"删除失败:{{error}}",disableSuccess:"已对当前 Agent 屏蔽“{{name}}”。",enableSuccess:"已为当前 Agent 恢复“{{name}}”。",availabilityUpdateFailed:"无法更新 Agent 可用性:{{error}}",marketDownloadSuccess:"已安装 Skill“{{name}}”。",marketDownloadFailed:"Skill 安装失败:{{error}}",revealPathFailed:"无法打开管理单元目录:{{error}}"},V8={nav:M8,installed:j8,library:E8,toolbar:L8,filters:$8,detail:O8,management:B8,market:W8,form:z8,list:U8,deleteModal:H8,messages:q8},G8={title:"子代理",subtitle:"集中查看、管理和维护可供顶层 Agent 调用的子代理。",searchPlaceholder:"搜索名称、描述或模型",clearSearch:"清空搜索",newSubagent:"新建子代理",refresh:"刷新"},K8={Explore:{name:"代码探索",description:"只读型子代理,用于大范围代码库探索。优先用 Grep、Glob 缩小范围,再阅读少量相关文件。"},FileFinder:{name:"文件定位",description:"根据语义描述搜索并定位相关文件与目录,适合在不知道确切路径时使用。"},ComputerUse:{name:"计算机操控",description:"感知本地环境并操作应用、浏览器与系统界面的桌面自动化子代理。"},DesignReview:{name:"设计评审",description:"只读型设计产物评审子代理,聚焦 HTML/CSS/JS 的语法、引用、设计令牌与布局风险。"}},Q8={all:"全部",ready:"可调用",readonly:"只读",sources:"来源",builtin:"内置",user:"用户级",project:"项目级"},J8={resultCount:"{{count}} 个结果",empty:"当前筛选下没有子代理",noDescription:"暂无说明"},Y8={empty:"选择一个子代理查看详情",noDescription:"这个子代理还没有填写职责说明。",edit:"编辑",delete:"删除",availabilityHint:"启用后,顶层 Agent 或编排流程可以继续引用它;停用后保留定义但不建议调用。",readonlyHint:"当前为只读型子代理,更适合检索、分析、整理等场景。",writeHint:"当前允许执行带写入能力的任务,适合更强的执行型场景。",toolCount:"已配置 {{count}} 个工具能力",defaultToolsFallback:"未单独指定工具,将沿用默认工具集。",callReady:"当前状态允许被上层 Agent 调用。",callBlocked:"当前已停用,不建议被上层 Agent 调用。",sections:{availability:"可用性",positioning:"角色定位",tools:"工具范围",calling:"调用状态"}},Z8={createTitle:"新建子代理",createSubtitle:"先填写最小定义,创建后即可继续补充和调整。",editTitle:"编辑子代理",editSubtitle:"修改描述、提示词、工具范围和启用状态。",cancel:"取消",create:"创建",save:"保存",readonlyOn:"仅执行只读任务",readonlyOff:"允许执行带写入能力的任务",enabledOn:"已启用",enabledOff:"已停用",noTools:"当前没有可选工具,保存后将使用默认工具集。",fields:{name:"名称",level:"级别",readonly:"只读模式",enabled:"启用状态",description:"职责说明",prompt:"系统提示词",tools:"工具范围"},levels:{user:"用户级",project:"项目级"},placeholders:{name:"字母开头,可包含字母、数字、下划线和连字符",description:"用一句话描述这个子代理负责什么",prompt:"输入系统提示词,说明它擅长什么、边界是什么、如何协作"},validation:{nameRequired:"请输入名称",nameFormat:"名称需以字母开头,并只包含字母、数字、下划线和连字符",descriptionRequired:"请输入职责说明",promptRequired:"请输入系统提示词",projectWorkspaceRequired:"项目级子代理需要先打开工作区"}},X8={builtin:"内置",user:"用户级",project:"项目级",readonly:"只读",disabled:"已停用"},e6={ready:"可直接调用",incomplete:"定义待补充",disabled:"暂不可调用"},t6={title:"删除子代理",message:"确定要删除“{{name}}”吗?删除后将无法恢复。",confirm:"删除",cancel:"取消"},n6={loadDetailFailed:"加载详情失败:",toggleFailed:"切换状态失败:",enabledSuccess:"已启用 {{name}}",disabledSuccess:"已停用 {{name}}",deleteSuccess:"已删除 {{name}}",deleteFailed:"删除失败:",createSuccess:"已创建 {{name}}",createFailed:"创建失败:",updateSuccess:"已保存 {{name}}",updateFailed:"保存失败:"},o6={loading:"加载中..."},s6={page:G8,builtin:K8,sidebar:Q8,list:J8,detail:Y8,editor:Z8,badges:X8,readiness:e6,deleteDialog:t6,messages:n6,status:o6},i6={title:"工具箱",subtitle:"浏览 Agent 可调用的动作与权限边界",learnMore:"了解 Agent 如何装配工具"},a6={builtin:"内置",mcp:"MCP",manageServers:"管理 MCP",noServers:"暂无 MCP Server",toolsUnder:"{{count}} 个工具"},r6={all:"全部",file:"文件",navigate:"导航检索",shell:"终端",web:"网络",desktop:"桌面操作",plan:"规划",session:"会话",interact:"人机交互",delegate:"委派",mcpMeta:"MCP 元工具"},l6={read:"只读",write:"写入",danger:"高风险"},c6={sourceLabel:"工具来源",categoryLabel:"工具分类",connectedServers:"{{count}} 个 Server 已连接",allPermissions:"全部权限",enabledOnly:"仅已启用"},d6={placeholder:"搜索工具…"},u6={listLabel:"工具列表",detailLabel:"工具详情",countSuffix:"共 {{count}} 项",pagination:"工具列表分页",emptyAll:"没有匹配当前筛选条件的工具。",emptyCategory:"该分类下没有工具。"},p6={selectHint:"在左侧选择一个工具,查看其说明。",languageToggle:"文档语言",langToggleZh:"中文",langToggleEn:"EN",sections:{what:"功能说明",when:"何时使用",whenNot:"不适用场景",inputs:"输入",outputs:"输出",related:"相邻工具",notes:"注意事项"},sourceBuiltin:"内置",sourceMcp:"MCP · {{server}}",inputsNone:"无显式输入。",outputsNone:"返回结构化结果。",relatedNone:"暂无直接相关的工具。",notesNone:"无额外注意事项。"},m6={header:{serversTotal:"{{count}} 个 Server",toolsTotal:"{{count}} 个 Tool",errors:"{{count}} 异常"},actions:{add:"添加 Server",refresh:"刷新",editConfig:"编辑配置"},empty:{title:"还没有 MCP Server",hint:"添加一个 MCP Server 以扩展可用工具。",cta:"添加 MCP Server"},server:{toolsSection:"工具({{count}})",configSection:"配置",noTools:"该 Server 当前未暴露任何工具。",start:"启动",stop:"停止",restart:"重启",delete:"删除",deleteConfirmTitle:"删除 MCP Server?",deleteConfirmMessage:'将移除 "{{id}}",此操作不可撤销。',transport:"传输",url:"URL",command:"命令"},editor:{title:"MCP JSON 配置",hint:"请使用标准 mcpServers 格式。保存后会重启相关 Server。",examples:{localProcess:"本地进程(stdio)",remoteService:"远程服务(sse)"},save:"保存",cancel:"取消",saveSuccess:"MCP 配置已保存。",saveFailed:"保存 MCP 配置失败:{{error}}",loadFailed:"加载 MCP 配置失败:{{error}}"}},g6={AgentHandoff:{name:"AgentHandoff",summary:"将工作交接给合适的 Agent 会话。",what:"当 OSAgent 判断某项工作需要专门能力承接时,创建或复用一个聚焦的 Agent 会话,并返回目标会话与工作区上下文。",when:["一段边界清晰的工作应由专门 Agent 承接","任务应延续到已有的聚焦会话中"],whenNot:["OSAgent 可以在当前上下文内高质量完成","只需要一次简单澄清"],related:[{name:"Task",note:"真正将子任务派发给 Subagent 执行。"}],notes:"作为 OSAgent 的交接工具使用;普通工作型 Agent 通常不需要。"},LS:{name:"LS",summary:"列出目录内容。",what:"列出指定路径下的文件和子目录,常作为项目探索的第一步。",when:["快速浏览某个目录","在决定要读哪些文件前"],whenNot:["按名称模式搜索——用 Glob","按内容搜索——用 Grep"],related:[{name:"Glob",note:"按模式匹配路径(如 **/*.ts)。"},{name:"Grep",note:"在文件内容中搜索。"}]},Read:{name:"Read",summary:"读取文件内容。",what:"读取工作区内的文件并带行号返回。支持 offset/limit 处理大文件。",when:["编辑前先查看源码","在回答中精确引用代码"],whenNot:["二进制文件请用文件查看器","全工程检索——用 Grep"],related:[{name:"Edit",note:"读取后再对精确位置进行修改。"},{name:"Grep",note:"先定位,再 Read 指定区域。"}]},Glob:{name:"Glob",summary:"按 glob 模式查找文件。",what:"使用 glob 语法匹配路径,如 **/*.tsx。结果按修改时间排序。",when:["按名称或后缀找文件","在 Grep 前缩小搜索范围"],whenNot:["搜索文件内容——用 Grep"],related:[{name:"Grep",note:"在匹配到的子集中做内容搜索。"}]},Grep:{name:"Grep",summary:"使用 ripgrep 搜索文件内容。",what:"在工作区内执行 ripgrep 搜索。支持正则、文件过滤、大小写选项与上下文行。",when:["定位符号或关键字","重构前审计使用位置"],whenNot:["只需要文件名——用 Glob","只扫单个文件——用 Read"],related:[{name:"Glob",note:"先限定文件集合。"},{name:"Read",note:"打开具体命中位置查看完整上下文。"}]},Write:{name:"Write",summary:"新建或整体覆盖一个文件。",what:"将给定内容写入文件;若不存在则创建。原有内容会被整体替换。",when:["新建文件","从零生成文件"],whenNot:["对已有文件做局部修改——用 Edit","二进制文件"],related:[{name:"Edit",note:"对已有文件进行局部编辑更安全。"},{name:"GetFileDiff",note:"写入后查看改动。"}],notes:"具破坏性——使用前请确认意图。"},Edit:{name:"Edit",summary:"对文件执行精确字符串替换。",what:"替换文件中唯一匹配的字符串,保留周边内容与原有行尾符。",when:["精确的局部修改","重命名或打补丁"],whenNot:["大段重写——用 Write","锚点不唯一时"],related:[{name:"Read",note:"先读取以构造唯一锚点。"},{name:"GetFileDiff",note:"查看改动集。"}]},Delete:{name:"Delete",summary:"删除工作区中的文件。",what:"移除指定路径;若不存在则平和失败。",when:["删除生成物或过时文件"],whenNot:["不确定是否仍有引用时"],related:[{name:"Grep",note:"删除前先搜索引用。"}],notes:"不可逆——批量删除前建议先 commit。"},Bash:{name:"Bash",summary:"在工作区终端执行 shell 命令。",what:"执行 shell 命令并实时输出 stdout/stderr,支持后台模式运行长任务。",when:["执行构建/测试命令","调用 CLI(git、pnpm、cargo)"],whenNot:["有专用文件工具时优先使用 Read/Edit/LS"],related:[{name:"TerminalControl",note:"管理已运行的终端会话。"}],notes:"可能影响宿主系统——视为高风险,破坏性命令请先确认。"},TerminalControl:{name:"TerminalControl",summary:"管理长时间运行的终端会话。",what:"读取输出、写入输入,或终止由 Bash 启动的后台终端。",when:["与开发服务器交互","轮询长任务"],whenNot:["一次性命令——直接用 Bash"],related:[{name:"Bash",note:"先启动终端。"}]},SessionControl:{name:"SessionControl",summary:"控制当前 Agent 会话的流程。",what:"在明确条件下暂停、恢复或结束当前会话。",when:["显式交还给用户","给出最终答案后结束"],whenNot:["常规轮次——由协调器自动处理"]},SessionMessage:{name:"SessionMessage",summary:"向会话记录中发布一条结构化消息。",what:"向当前会话写入一条头等消息(状态、通知、总结)以展示给用户。",when:["发布阶段性进展","分享结构化总结"],whenNot:["常规助手回复——直接回答即可"]},SessionHistory:{name:"SessionHistory",summary:"回看会话中的历史轮次。",what:"返回当前会话中较早消息的精简视图。",when:["上下文压缩","回溯过去的决策"],whenNot:["跨会话搜索——使用项目级搜索工具"]},TodoWrite:{name:"TodoWrite",summary:"为当前任务维护一个结构化 Todo 列表。",what:"创建或更新一个带状态(pending / in_progress / completed / cancelled)的有序 Todo 列表。",when:["3 步及以上的任务","多文件长重构"],whenNot:["单步简单任务"],related:[{name:"CreatePlan",note:"更大型的任务建议先出 Plan 文档。"}]},Cron:{name:"Cron",summary:"调度周期性或延后任务。",what:"创建、列出、删除定时任务:按时间或间隔将 prompt 发送到会话。",when:["每日简报","周期性轮询任务"],whenNot:["一次性立即执行"]},Task:{name:"Task",summary:"将有边界的子任务派发给 Subagent。",what:"以独立的 prompt 与边界启动一个专门的 Subagent,返回其最终结果。",when:["可并行的研究类子任务","边界清晰的子问题"],whenNot:["需要与用户紧密来回的工作"],related:[{name:"AgentHandoff",note:"当工作归属清晰时交给专门会话承接。"}]},Skill:{name:"Skill",summary:"调用已安装的 Skill(配方)。",what:"执行已注册的 Skill 配置,包含 prompt、工具策略和知识。",when:["已有 Skill 的可复用工作流"],whenNot:["没必要沉淀为 Skill 的一次性工作"]},AskUserQuestion:{name:"AskUserQuestion",summary:"向用户抛出一个多选问题。",what:"以结构化选择题形式向用户提问,回答前阻塞后续工具调用。",when:["需求含糊","多种方案需要抉择"],whenNot:["可以安全假设并继续时"]},WebSearch:{name:"WebSearch",summary:"网页搜索。",what:"执行网页搜索,返回一组标题与摘要。",when:["需要最新外部信息","查阅库或 API 参考"],whenNot:["项目内部问题——用 Grep"]},WebFetch:{name:"WebFetch",summary:"抓取 URL 并转成可读文本。",what:"下载网页并转为 markdown 文本。常与 WebSearch 配合使用。",when:["阅读文章或文档页面","从 URL 提取结构化文本"],whenNot:["二进制资源或需登录的内容"],related:[{name:"WebSearch",note:"先搜索确定 URL,再抓取。"}]},ListMCPResources:{name:"ListMCPResources",summary:"列出某个 MCP Server 暴露的资源。",what:"探查 MCP Server 提供的资源(文件、数据集、文档)。",when:["探索某个 MCP Server 的能力"]},ReadMCPResource:{name:"ReadMCPResource",summary:"读取某个 MCP 资源的内容。",what:"获取 MCP Server 上某个资源的内容。"},ListMCPPrompts:{name:"ListMCPPrompts",summary:"列出 MCP Server 暴露的 Prompt 模板。",what:"发现 MCP Server 对外提供的 prompt 模板。"},GetMCPPrompt:{name:"GetMCPPrompt",summary:"渲染一个 MCP Prompt 模板。",what:"以给定参数渲染 Server 提供的 prompt 模板。"},GenerativeUI:{name:"GenerativeUI",summary:"在对话中渲染交互式控件。",what:"在对话内嵌入一个小型交互 UI(表单、选择控件、进度卡)。",when:["需要超出 Yes/No 的结构化输入","展示长任务的进度"]},GetFileDiff:{name:"GetFileDiff",summary:"获取文件的 unified diff。",what:"返回某文件当前工作区版本与基线之间的 unified diff。"},Log:{name:"Log",summary:"追加一条结构化日志。",what:"写入结构化日志条目,便于排查复杂 Agent 运行过程。"},CreatePlan:{name:"CreatePlan",summary:"为任务创建 Plan 文档。",what:"创建或更新一份 markdown 计划文档,描述任务目标、步骤与风险。",related:[{name:"TodoWrite",note:"把 Plan 步骤转为运行时 Todo。"}]},CodeReview:{name:"CodeReview",summary:"对近期改动执行代码审查。",what:"对最近的 diff 运行一次代码审查,返回发现的问题。"},CreateProductApp:{name:"CreateProductApp",summary:"初始化一个 Product App 项目骨架。",what:"用默认模板初始化一个新的产品应用项目。"},CreateProductAppComponent:{name:"CreateProductAppComponent",summary:"创建 Product App 的 app-private Component 脚手架。",what:"向已有 Product App package 添加 Surface、Agent、Bridge、Runtime、Tool 或 Skill 组件脚手架,并刷新组件锁。"},GetProductAppPackage:{name:"GetProductAppPackage",summary:"读取 Product App package。",what:"读取 app.json、app.lock.json、私有组件、解析后的组件和 package 计划,不修改文件。"},UpdateProductAppPackage:{name:"UpdateProductAppPackage",summary:"更新 Product App package 元数据。",what:"更新结构化 Product App 元数据、启动方式、主 surface、交互模型和 Work 数量策略,并刷新组件锁。"},RefreshProductAppLock:{name:"RefreshProductAppLock",summary:"刷新 Product App 组件锁。",what:"解析 Product App package,更新 app.json 中的组件锁摘要,并重写 app.lock.json。"},ResolveBuilderPreviewTarget:{name:"ResolveBuilderPreviewTarget",summary:"解析 Builder 预览目标。",what:"解析 Product App 预览身份、模式、Workbench 位置和证据边界,但不声称已经执行运行时预览。"},ComputerUse:{name:"ComputerUse",summary:"自动化桌面(鼠标、键盘、截图)。",what:"统一的桌面自动化:点击、鼠标移动、滚动、拖拽、截图、屏幕定位、键位组合、输入文本、等待。",when:["操作没有 API 的 GUI 应用","截图作为执行证据"],whenNot:["可通过 CLI 或文件系统完成的事情"],notes:"可影响宿主上任何应用——视为高风险,破坏性动作前先确认。"}},h6={page:i6,sidebar:a6,categories:r6,permissions:l6,filters:c6,search:d6,list:u6,detail:p6,mcp:m6,builtin:g6},f6="欢迎使用",y6="欢迎回到",w6="欢迎使用",v6="开始",b6="Sparo OS Workspace",k6="真实工作台,而不只是一个聊天框",S6="有个性,有记忆,帮你做事的 AI 助理。会话流与 Product App 围绕同一个工作流协同展开,AI 在做事,不只是回答。",x6="新建 BitFun Coder 会话",C6="接住一个目标,灵活执行、调试、自动化并交付经过验证的结果",A6="新建办公助理会话",_6="适合整理需求、推进任务、起草内容和日常协作",T6="项目与工作区",P6="打开项目开始 Code 或办公助理,也可以切换到最近使用的工作区。",F6="暂无最近工作区",R6={message1:"欢迎回来,继续把想法变成现实。",message2:"嗨,今天也来整点好玩的。",message3:"你的创作搭子已上线,随时开工。",message4:"欢迎使用 Sparo OS,开始做点有意思的事。"},N6={workspace:{title:"AI 在做事",description:"思考链、终端命令、代码差异与任务规划都会实时出现,过程透明,不只是回答。"},team:{title:"你的 AI 团队",description:"为不同场景配置 Code、办公助理和更多 Agent,让它们分工协作,完成复杂任务。"},assistant:{title:"会持续成长的工作区",description:"共享运行时工作区会保留上下文,适合持续协作。"}},D6="即将推出",I6="切换工作区",M6="打开",j6="从最近列表移除",E6="新建",L6="暂无其他工作区",$6="选一个场景,开始今天的创作吧",O6={title:"欢迎使用 Sparo OS",subtitle:"你的 AI 编程伙伴,让创意瞬间成为现实",noWorkspaceHint:"尚未打开任何工作区",openProject:"打开项目",openProjectDesc:"选择一个已有的项目目录,开始你的 AI 编程之旅",newProject:"新建项目",newProjectDesc:"从零开始创建一个全新的项目"},B6={tabLabel:f6,welcomeBack:y6,welcomeTabTitle:w6,quickStart:v6,heroBadge:b6,heroTitle:k6,heroDescription:S6,newBitfunCoderSession:x6,newBitfunCoderSessionDesc:C6,newCoworkSession:A6,newCoworkSessionDesc:_6,workspaceSectionTitle:T6,workspaceSectionHint:P6,noRecentWorkspaces:F6,messages:R6,features:N6,comingSoon:D6,recentWorkspaces:I6,openOtherProject:M6,removeFromRecent:j6,newProject:E6,noOtherWorkspaces:L6,emptyHint:$6,firstTime:O6},W6="工作中心",z6={eyebrow:"SPARO OS",quiet:"暂无进行中的工作"},U6={placeholder:"搜索工作..."},H6={label:"工作范围",actionSection:"行动入口",todaySection:"队列",continuitySection:"持续事项",librarySection:"全部",typeSection:"工作类型",systemSection:"系统",workspaceSection:"工作区",attention:"需要你处理",openWork:"可继续工作",openWorkCount:"{{count}} 个可继续",allWork:"未归档工作",unarchivedWork:"未归档工作",unarchivedWorkCount:"{{count}} 个未归档",completedWork:"已完成",completedWorkCount:"{{count}} 个已完成",archivedWork:"已归档",archivedWorkCount:"{{count}} 个已归档",activeWorkspaces:"活跃工作区",workspaces:"工作区",system:"全局工作",running:"{{count}} 个运行中",runningWorks:"运行中的工作",needsAttention:"{{count}} 个需要处理",allWorkHint:"查看所有未归档工作",openWorkspaces:"{{count}} 个已打开",historyWorkspaces:"{{count}} 个历史",total:"共 {{count}} 个",workspace:"工作区",backgroundProcesses:"系统事项"},q6={immediate:"即时事项",long_term:"长期事项",topic:"Topic",recurring:"周期事项",system:"系统事项"},V6={foreground:"前台运行",background:"后台运行"},G6={emptyValue:"--",columns:{name:"名称",type:"类型",status:"状态",scope:"范围",kind:"工作类型",phase:"阶段",runtime:"运行时长",updated:"更新",actions:"操作"}},K6={newWork:"新建工作",clearFilters:"清除筛选",cancelWork:"取消运行",removeWork:"归档工作"},Q6={label:"工作看板"},J6={label:"批量工作操作",selectAllVisible:"选择当前可见工作",selectWork:"选择 {{title}}",selectHint:"从当前 {{count}} 个工作中选择",selectedCount:"已选择 {{count}} / {{total}}",archive:"归档 {{count}}",reopen:"重开 {{count}}",cancel:"取消 {{count}}",delete:"删除",clearSelection:"清除选择",deleteDialog:{title:"删除 {{count}} 个工作项",description:"这会从工作中心移除所选工作。产物和记忆会保留。",deleteLinkedSessionsLabel:"同时删除关联会话",deleteLinkedSessionsDescription:"通过 Work 生命周期清理 Hook 随工作删除关联的代理会话。",cancel:"取消",confirm:"删除工作",deleting:"正在删除..."}},Y6={title:"后台进程",subtitle:"{{running}} 个运行中 · {{attention}} 个需关注 · 共 {{total}} 个",searchPlaceholder:"搜索进程...",emptyValue:"--",duration:{seconds:"{{count}} 秒",minutes:"{{count}} 分钟",hours:"{{count}} 小时"},filters:{railLabel:"后台进程筛选",status:{all:"全部进程",attention:"需关注",running:"运行中",queued:"排队中",scheduled:"已计划",idle:"空闲"},category:{all:"全部类别"}},rail:{eyebrow:"进程类别",summary:"{{running}} 个运行中 · {{attention}} 个需关注"},columns:{process:"进程",status:"状态",scope:"范围",trigger:"触发",phase:"阶段",lastRun:"最近运行起止",runtime:"运行时长",nextRun:"下次运行",result:"最近结果",actions:"操作"},kinds:{auto_memory_extraction:"自动记忆提取",memory_consolidation:"记忆合并",host_scan:"主机扫描",workspace_overview_refresh:"工作区概览刷新",global_daily_report:"全局日报",daily_letter:"今日来信",global_milestone:"全局里程碑"},categories:{memory:"记忆",workspace:"工作区",report:"报告",system:"系统"},status:{idle:"空闲",disabled:"已停用",scheduled:"已计划",queued:"排队中",running:"运行中",succeeded:"成功",failed:"失败",cancelled:"已取消",skipped:"已跳过",cooling_down:"冷却中"},trigger:{auto:"自动",manual:"手动",startup_catch_up:"启动补跑",post_turn:"轮次结束",retry:"重试",scheduled:"计划",system:"系统"},phase:{idle:"空闲",waiting_schedule:"等待计划",waiting_retry:"等待重试",queued:"排队中",running_hidden_agent:"隐藏 Agent 运行",scanning_host:"扫描主机",refreshing_workspace_overview:"刷新工作区概览",consolidating_memory:"合并记忆",extracting_memory:"提取记忆",generating_report:"生成报告",writing_daily_letter:"写今日来信"},scopeLabel:{system:"系统"},actions:{runNow:"立即运行",retry:"重试",openOutput:"打开输出",openSettings:"设置",refresh:"刷新",clearSearch:"清除搜索"},empty:{noProcesses:"暂无后台进程",noMatches:"没有匹配的进程"},messages:{runStarted:"进程已启动",runSkipped:"{{reason}}",runSkippedDefault:"进程未启动",runFailed:"运行进程失败",loadFailed:"加载后台进程失败",noOutput:"暂无输出路径",openOutputFailed:"打开输出失败"},footer:{generatedAt:"更新于 {{time}}",notLoaded:"尚未加载"}},Z6={noMatches:"没有匹配的工作",clearSearch:"清除搜索",showAllWork:"查看未归档工作",noRunning:"当前没有运行中的工作"},X6={label:"工作详情",close:"关闭详情",openPrimary:"打开主入口",openSurface:"打开入口",openArtifact:"打开产物",copyReference:"复制引用",copied:"已复制",openDetailsFor:"查看 {{title}} 的详情",loading:"正在加载工作详情",navigation:{position:"第 {{current}} / {{total}} 项工作",positionCompact:"{{current}} / {{total}}",previous:"上一项工作",next:"下一项工作"},tabs:{overview:"概览",outputs:"产出与入口",runtime:"运行记录"},currentState:{title:"当前情况",fallback:"打开这项工作,查看最新上下文。",systemManaged:"由 Sparo OS 自动维护,无需手动处理。",memorySourcesTracked:"系统已整理来自 {{count}} 个来源的记忆。",systemHealthy:"最近一次运行已完成,系统会继续自动维护。",systemRunning:"系统正在后台处理,完成后会自动更新结果。",systemScheduled:"系统已安排下一次运行,无需手动处理。",systemAttention:"最近一次运行未完成,可在运行记录中查看详情。",systemDisabled:"这项系统任务当前已停用。"},systemStatus:{healthy:"运行正常",running:"正在运行",scheduled:"等待运行",attention:"需要处理",disabled:"已停用"},systemOverview:{title:"自动运行",automatic:"自动维护",trigger:"运行方式",lastFinished:"最近完成"},systemActivity:{running:"正在运行",lastRun:"最近一次运行:{{status}}"},primaryAction:{handle:"去处理",inspectProgress:"进入工作台",viewResult:"查看结果",enter:"进入工作台",resume:"继续工作",reopen:"重新打开",openAndHandle:"打开并处理"},appendInstruction:{label:"追加指令",placeholder:"告诉这项工作接下来要做什么...",send:"发送指令",cancel:"取消"},more:{label:"更多操作",collapse:"收起操作",changeType:"更改类型",reopen:"重新打开工作"},context:{title:"工作上下文"},outputs:{artifacts:"产出",destinations:"继续入口",primary:"主入口"},runtimeEvents:"运行事件",technical:{show:"显示技术信息",hide:"收起技术信息",workId:"工作 ID",runtimeInstanceId:"运行实例 ID"},empty:{outputs:"暂无产出或入口",activity:"暂无最近动态",runtime:"暂无运行记录"},command:{open:"打开",advance:"继续",cancel:"取消",archive:"归档"},brief:"工作概览",objective:"目标",emptyObjective:"暂无目标记录",editObjective:"编辑目标",objectivePlaceholder:"描述这个工作要达成的目标...",saveObjective:"保存目标",cancelEdit:"取消",summary:"摘要",noSummary:"暂无摘要",advance:"继续",advancePlaceholder:"告诉这个工作接下来要做什么...",sendAdvance:"发送指令",workspace:"工作区",globalWorkspace:"全局",created:"创建时间",updated:"更新时间",updatedAt:"{{time}} 更新",links:"关联入口",activity:"最近动态",surfaces:"入口",execution:"执行",executionGraph:"执行图",graphLoading:"正在加载执行图",graphArtifacts:"{{count}} 个图产物",noRuntimeRuns:"暂无运行时执行",noExecution:"暂无执行绑定",lifecycle:"状态历史",noLifecycle:"暂无状态历史",artifacts:"{{count}} 个产物",memories:"{{count}} 条记忆",sessions:"{{count}} 个会话",runtimeInstanceCount:"{{count}} 个运行实例",runtimeInstances:"运行实例",runtimeRuns:"{{count}} 次运行时执行",runtimeIssues:"{{count}} 条诊断",runtimeLogs:"{{count}} 条运行日志",runtimeRunMeta:"{{component}} · {{action}}",runtimeLogMeta:"{{category}} · {{component}}",runtimeVersion:"v{{version}} · {{lock}}",runtimeRelease:"Release {{release}} · 配置 {{config}}",runtimeSurface:"{{surface}} · {{component}}",runtimeLogLevel:{debug:"调试",info:"信息",warn:"警告",error:"错误"},surface:{workSession:"工作会话",agentSession:"智能体会话",application:"应用入口",agentHome:"Agentic OS 首页"},assignment:{label:"负责人",unassigned:"未分配",unknown:"未知",agent:"智能体:{{label}}",assistant:"助手:{{label}}",application:"应用:{{label}}",human:"人员:{{label}}",external:"外部:{{label}}"},executionStatus:{queued:"已排队",running:"运行中",waiting_user:"等待你",completed:"已完成",failed:"失败",cancelled:"已取消",interrupted:"已中断"},executionSource:{agentSessionRun:"智能体会话运行",delegatedWorkRun:"委派工作",applicationAction:"应用动作",runtimeInstanceRun:"运行实例执行",runtimeSubagentRun:"运行时子智能体",external:"外部执行"},runtimeStatus:{idle:"空闲",running:"运行中",waiting_user:"等待你",completed:"已完成",degraded:"异常"},runtimeRunStatus:{pending:"排队中",running:"运行中",waiting_user:"等待你",completed:"已完成",failed:"失败",cancelled:"已取消"},runtimeIssueSeverity:{fatal:"运行时错误",warning:"运行时警告",noise:"运行时提示"},lifecycleEvent:{created:"工作已创建",advanced:"指令已发送",paused:"工作已暂停",resumed:"工作已继续",archived:"工作已归档",reopened:"工作已重新打开",statusUpdated:"状态已更新",applicationSurfaceWorkflowStarted:"应用界面流程已启动",currentExecutionCancelled:"当前运行已取消",agentSessionContinued:"智能体会话已继续",agentSessionTurnCompleted:"智能体轮次已完成",agentSessionTurnCancelled:"智能体轮次已取消",agentSessionFailed:"智能体会话失败",agentSessionFailedWithReason:"智能体会话失败:{{reason}}",agentSessionWaitingUser:"等待你处理",agentSessionResumed:"智能体会话已恢复"},classify:{title:"分类",asTopic:"标记为 Topic",asTracking:"标记为长期跟踪",asLongRunning:"标记为长期运行",asRecurring:"标记为周期事项",asImmediate:"标记为即时事项",updated:"分类已更新"},attachments:{title:"挂靠",topic:"Topic",systemProcess:"系统进程",none:"未挂靠 Topic"},systemRuntime:{title:"运行与调度",nextRun:"下次运行",runNow:"立即运行",unavailable:"进程运行态不可用"}},ez={all:"全部工作区",searchPlaceholder:"查找工作区"},tz={all:"全部应用",searchPlaceholder:"查找应用",kind:{product_app:"{{count}} 个产品应用工作"}},nz={searchPlaceholder:"搜索工作区...",empty:"暂无工作区",noMatches:"没有匹配的工作区",activeSection:"活跃工作区",historySection:"历史记录",noActive:"暂无活跃工作区",noHistory:"暂无历史记录",openWorkspace:"打开工作区",openingWorkspace:"正在打开...",openDialogTitle:"打开工作区",switchWorkspace:"设为当前",openHistoryWorkspace:"打开",closeWorkspace:"关闭工作区",removeHistoryWorkspace:"从历史移除",workCount:"{{count}} 个工作",runningCount:"{{count}} 个运行中",attentionCount:"{{count}} 个需要你",quiet:"暂无工作",drillIn:"查看工作",openWorkFor:"查看 {{title}} 中的工作",status:{attention:"需要你",running:"运行中",active:"活跃",quiet:"安静"}},oz={label:"工作分组",priority:"焦点",kind:"类型",status:"状态",time:"时间"},sz={immediate:"即时事项",long_term:"长期事项",recurring:"周期事项"},iz={needs_attention:"需要你处理",running:"正在运行",recurring:"周期事项",long_term:"长期事项",immediate:"即时事项",done:"已完成"},az={draft:"草稿",active:"可继续",running:"运行中",waiting_user:"等待你",blocked:"受阻",paused:"已暂停",completed:"已完成",failed:"失败",cancelled:"已取消",interrupted:"已中断",archived:"已归档"},rz={"one-shot":"普通工作","multi-step":"多步骤工作","long-running-session":"长期工作",recurring:"周期工作",tracking:"追踪工作",topic:"主题工作","app-workflow":"智能应用工作","delegated-work":"委派工作",system:"系统工作"},lz={today:"今天",week:"本周",older:"更早"},cz={unknown:"未知",versionIncompatible:"此 Work 由 {{appId}} {{createdWithVersion}} 创建,数据版本为 {{workDataSchemaVersion}}。当前安装版本 {{installedVersion}}(数据版本 {{installedDataSchemaVersion}})无法接管其数据或运行契约;历史应用版本已被清除。",appUnavailable:"无法运行此 Work,因为尚未安装 {{appId}};系统不会保留或恢复它的历史应用版本。",appDisabled:"无法运行此 Work,因为 {{appId}} 已停用。",appSelectionChanged:"此 Work 属于 {{appId}},但该应用槽位当前选择的是 {{installedAppId}};系统不会使用历史应用版本。"},dz={openFailed:"打开工作失败",openSurfaceFailed:"打开入口失败",openArtifactFailed:"打开产物失败",cancelFailed:"取消工作失败",pauseFailed:"暂停工作失败",resumeFailed:"继续工作失败",reopenFailed:"重新打开工作失败",removeFailed:"移除工作失败",objectiveRequired:"目标不能为空",updateObjectiveFailed:"更新目标失败",advanceRequired:"请先输入指令",advanceFailed:"发送指令失败",openWorkspaceFailed:"打开工作区失败",switchWorkspaceFailed:"切换工作区失败",closeWorkspaceFailed:"关闭工作区失败",removeWorkspaceFailed:"移除工作区历史失败",bulkActionFailed:"{{count}} 个所选工作更新失败",bulkDeleteFailed:"{{count}} 个所选工作删除失败",reclassifyFailed:"更新分类失败"},uz={objectiveSaved:"目标已更新",advanceSent:"指令已发送",paused:"工作已暂停",resumed:"工作已继续",reopened:"工作已重新打开",archived:"工作已归档",bulkArchived:"已归档 {{count}} 个工作项",bulkReopened:"已重开 {{count}} 个工作项",bulkCancelled:"已取消 {{count}} 个工作运行",bulkDeleted:"已删除 {{count}} 个工作项",bulkDeletedWithSessions:"已删除 {{count}} 个工作项和 {{sessions}} 个关联会话",bulkDeletedWithCleanupWarnings:"已删除 {{count}} 个工作项,但 {{failed}} 个关联会话清理项失败"},pz={title:W6,header:z6,search:U6,scope:H6,rail:q6,runtime:V6,runningTable:G6,actions:K6,board:Q6,bulk:J6,background:Y6,emptyState:Z6,detail:X6,workspaceFilter:ez,appFilter:tz,workspaceOverview:nz,grouping:oz,category:sz,priority:iz,status:az,kind:rz,time:lz,compatibility:cz,errors:dz,messages:uz},mz="设置",gz={title:"通用",language:{title:"语言",description:"选择界面显示语言",auto:"自动检测"},theme:{title:"主题",description:"选择界面主题",light:"浅色",dark:"深色",system:"跟随系统"},startup:{title:"启动",restoreSession:"恢复上次会话",showWelcome:"显示欢迎页面"}},hz={title:"编辑器",font:{title:"字体",family:"字体族",size:"字体大小",lineHeight:"行高"},display:{title:"显示",wordWrap:"自动换行",minimap:"显示缩略图",lineNumbers:"显示行号",breadcrumbs:"显示面包屑",whitespace:"显示空白字符"},behavior:{title:"行为",autoSave:"自动保存",autoSaveDelay:"自动保存延迟",formatOnSave:"保存时格式化",formatOnPaste:"粘贴时格式化"},indentation:{title:"缩进",type:"缩进类型",spaces:"空格",tabs:"制表符",size:"缩进大小"}},fz={title:"AI 设置",model:{title:"模型",select:"选择模型",provider:"服务商",apiKey:"API 密钥",baseUrl:"基础 URL",add:"添加模型",edit:"编辑模型",delete:"删除模型"},behavior:{title:"行为",streaming:"流式输出",temperature:"温度",maxTokens:"最大令牌数",contextLength:"上下文长度"},agent:{title:"智能体",defaultAgent:"默认智能体",customAgents:"自定义智能体"}},yz={title:"终端",shell:{title:"Shell",default:"默认 Shell",profiles:"Shell 配置"},display:{title:"显示",fontSize:"字体大小",fontFamily:"字体族",cursorStyle:"光标样式",scrollback:"回滚行数"}},wz={title:"工作区",files:{title:"文件",exclude:"排除文件",watcherExclude:"排除监视",associations:"文件关联"},search:{title:"搜索",exclude:"排除搜索",useIgnoreFiles:"使用忽略文件"}},vz={title:"高级",experimental:{title:"实验性功能",description:"这些功能可能不稳定"},debug:{title:"调试",logging:"启用日志",developerTools:"开发者工具"},data:{title:"数据",export:"导出设置",import:"导入设置",reset:"重置所有设置",resetConfirm:"确定要重置所有设置吗?此操作不可撤销。"}},bz={title:"关于",version:"版本",checkUpdate:"检查更新",changelog:"更新日志",license:"许可证",openSource:"开源许可",feedback:"反馈",reportIssue:"报告问题",documentation:"文档"},kz={title:"模型配置",subtitle:"配置 AI 模型和 API 密钥",addModel:"添加模型",editModel:"编辑模型配置",newModel:"新建模型配置",editSubtitle:"基础模型参数配置",deleteModel:"删除模型",confirmDelete:"确定删除此配置?",modelName:"模型名称",modelId:"模型 ID",provider:"请求规范",providerPlaceholder:"选择请求格式",apiKey:"API密钥",apiKeyPlaceholder:"输入您的 API Key",baseUrl:"API地址",baseUrlPlaceholder:"请输入 API 地址(可选)",configName:"配置名称",configNamePlaceholder:"为此配置起个名字",maxTokens:"最大输出Tokens",maxTokensHint:"单次请求时限制模型输出的最大token数量(影响响应长度)",contextWindow:"上下文窗口大小",contextWindowHint:"模型支持的最大上下文窗口大小(用于计算token占用百分比)",temperature:"温度",streaming:"流式输出",enabled:"启用",test:"测试连接",testing:"测试中...",testSuccess:"连接成功",testFailed:"连接失败",noModels:"暂无模型配置",noModelsHint:"点击上方按钮添加您的第一个 AI 模型",createFirst:"创建第一个配置",noMatchingModels:"没有找到匹配的模型",searchPlaceholder:"搜索模型名称、提供商...",newConfig:"新建配置",save:"保存",cancel:"取消",edit:"编辑",delete:"删除",description:"描述",descriptionPlaceholder:"配置说明(可选)",tabs:{api:"API配置",proxy:"代理配置"},categories:{all:"全部",text:"文本",multimodal:"图像",other:"辅助"},category:{label:"模型分类",placeholder:"选择模型分类",general_chat:"文本生成",multimodal:"图像理解",image_generation:"图像生成",speech_recognition:"语音识别"},categoryHints:{general_chat:"文本生成:生成文本回复、代码等,适用于大多数对话场景",multimodal:"图像理解:理解图片内容并进行图文混合对话",image_generation:"图像生成:根据文字描述生成图片",speech_recognition:"语音识别:将语音转换为文字(如智谱 GLM-ASR)"},modelNameHint:"智谱 GLM-ASR 使用 glm-asr,其他语音模型填写对应的模型名称",thinking:{enable:"启用思考",enableHint:"需要模型支持思考模式"},details:{basicInfo:"基本信息",modelName:"模型名称",provider:"请求规范",apiUrl:"API地址",contextWindow:"上下文窗口",maxOutput:"最大输出",description:"描述",tokens:"tokens"},proxy:{enable:"启用代理",enableHint:"启用后所有AI请求将通过代理发送(需重启IDE生效)",url:"代理地址",urlPlaceholder:"http://127.0.0.1:7890 或 socks5://127.0.0.1:1080",urlHint:"支持 HTTP/HTTPS/SOCKS5 代理,格式:协议://地址:端口",username:"用户名(可选)",usernamePlaceholder:"代理认证用户名",password:"密码(可选)",passwordPlaceholder:"代理认证密码",save:"保存代理配置",saveSuccess:"代理配置已保存,重启IDE后生效"},messages:{fillRequired:"请填写必要字段",fillModelName:"请填写模型名称",saveFailed:"保存失败",deleteFailed:"删除配置失败",loadFailed:"加载AI配置失败",errorDetails:"详细错误"},capabilities:{text_chat:"对话",image_understanding:"多模态",image_generation:"绘图",search:"搜索",function_calling:"工具",speech_recognition:"语音"}},Sz={title:"Super Agent",subtitle:"配置主智能体的模型分配",textChat:"文本对话",textChatDesc:"处理日常对话和问答",codeGeneration:"代码生成",codeGenerationDesc:"生成和补全代码",codeReview:"代码审查",codeReviewDesc:"审查和优化代码",planning:"任务规划",planningDesc:"分解和规划复杂任务",selectModel:"选择模型",notConfigured:"未配置",configured:"已配置",modelUpdated:"{{capability}}已更新为 {{modelName}}",capabilities:{text_chat:"文本对话模型",image_understanding:"图片理解模型",image_generation:"图片生成模型",search:"搜索API模型",speech_recognition:"语音识别模型"},capabilityDescs:{text_chat:"处理所有文本对话、代码生成、工具调用等任务",image_understanding:"当主模型不支持图片输入时,用于分析和理解图片内容",image_generation:"根据文字描述生成图片(如 DALL-E、Stable Diffusion)",search:"实时搜索网络信息,提供最新数据支持",speech_recognition:"将语音转换为文字,支持语音输入功能(如智谱 GLM-ASR)"}},xz={title:"智能特性",subtitle:"配置 AI 增强功能",codeCompletion:"代码补全",codeCompletionDesc:"智能代码补全建议",inlineChat:"行内对话",inlineChatDesc:"在编辑器中直接与 AI 对话",semanticSearch:"语义搜索",semanticSearchDesc:"基于语义理解的代码搜索",autoFix:"自动修复",autoFixDesc:"自动修复代码错误和警告"},Cz={title:"模式",subtitle:"配置不同的工作模式",agentMode:"Agent 模式",agentModeDesc:"AI 可以执行代码和使用工具",chatMode:"对话模式",chatModeDesc:"纯对话,不执行任何操作",askMode:"Ask 模式",askModeDesc:"只读模式,仅回答问题"},Az={title:"工具设置",subtitle:"配置 Agentic 工具权限和行为",fileOperations:"文件操作",fileOperationsDesc:"允许 AI 读写文件",terminalAccess:"终端访问",terminalAccessDesc:"允许 AI 执行终端命令",webSearch:"网络搜索",webSearchDesc:"允许 AI 搜索网络信息",browserControl:"浏览器控制",browserControlDesc:"允许 AI 控制浏览器"},_z={title:"技能",subtitle:"管理 AI 技能扩展",addSkill:"添加技能",noSkills:"暂无技能",noSkillsHint:"技能可以扩展 AI 的能力"},Tz={title:"智能体",subtitle:"配置智能体",addAgent:"添加智能体",noAgents:"暂无子智能体",noAgentsHint:"子智能体可以处理特定类型的任务"},Pz={title:"MCP",subtitle:"管理 MCP 服务器连接",addServer:"添加服务器",serverName:"服务器名称",serverUrl:"服务器地址",connected:"已连接",disconnected:"已断开",noServers:"暂无 MCP 服务器",noServersHint:"添加 MCP 服务器以扩展功能"},Fz={title:"编辑器",subtitle:"配置代码编辑器",fontSize:"字体大小",fontFamily:"字体",lineHeight:"行高",tabSize:"Tab 大小",wordWrap:"自动换行",minimap:"显示缩略图",lineNumbers:"显示行号"},Rz={title:"语言服务",subtitle:"配置语言服务器",installedServers:"已安装的语言服务器",noServers:"暂无语言服务器",noServersHint:"语言服务器提供代码智能功能"},Nz={title:"调试",subtitle:"配置调试选项",enableLogging:"启用日志",logLevel:"日志级别",developerTools:"开发者工具"},Dz={title:"终端",subtitle:"配置集成终端",shell:"默认 Shell",fontSize:"字体大小",fontFamily:"字体",cursorStyle:"光标样式",scrollback:"回滚行数"},Iz={basic:{title:"基础配置"},apiNetwork:{title:"API & 网络",subtitle:"配置和管理系统中的 AI 模型,包括 API 密钥、默认模型等设置"},learning:{title:"学习 & 知识",subtitle:"管理 AI 记忆、知识库和技能配置",import:"导入",addMemory:"添加记忆"},agents:{title:"智能体配置",subtitle:"配置和管理系统中的智能体,包括功能代理、超级代理等",create:"创建智能体"},theme:{title:"主题配置",subtitle:"自定义应用的外观和主题色彩",import:"导入主题",export:"导出当前主题"}},Mz={title:mz,general:gz,editor:hz,ai:fz,terminal:yz,workspace:wz,advanced:vz,about:bz,aiModel:kz,superAgent:Sz,aiFeatures:xz,modes:Cz,agenticTools:Az,skills:_z,agents:Tz,mcp:Pz,editorConfig:Fz,lspConfig:Rz,debugConfig:Nz,terminalConfig:Dz,configPageHeaderExample:Iz},jz="工具设置",Ez="工具执行配置与可用工具列表",Lz={config:{title:"执行行为",description:"控制工具调用时的确认与超时策略。"},list:{title:"工具列表",description:"共 {{count}} 个可用工具。"}},$z={autoExecute:"自动执行",autoExecuteDesc:"跳过工具执行前的用户确认步骤。",confirmTimeout:"确认超时",confirmTimeoutDesc:"等待用户确认工具调用的最长时间(秒)。",executionTimeout:"执行超时",executionTimeoutDesc:"工具执行的最长时间(秒)。",seconds:"秒"},Oz={all:"全部",readonly:"只读",writable:"可写"},Bz={placeholder:"搜索工具..."},Wz={readonly:"只读",writable:"可写",concurrent:"并发安全",permission:"需要权限"},zz={title:"工具属性",readonlyMode:"只读模式",concurrencySafe:"并发安全",needsPermission:"需要权限",yes:"是",no:"否"},Uz={title:"输入参数结构"},Hz={loading:"加载中...",loadFailed:"加载失败",retry:"重试",noTools:"暂无可用工具",noMatchingTools:"没有找到匹配的工具",autoExecuteEnabled:"已启用自动执行工具",autoExecuteDisabled:"已关闭自动执行工具",saveFailed:"保存失败"},qz={title:jz,subtitle:Ez,section:Lz,config:$z,filters:Oz,search:Bz,badges:Wz,properties:zz,schema:Uz,messages:Hz},Vz="智能体",Gz="管理用户级和项目级智能体",Kz={searchPlaceholder:"搜索Agent...",refreshTooltip:"刷新 Agent 列表",refreshSuccess:"Agent 列表已刷新",addTooltip:"添加Agent"},Qz={all:"所有",builtin:"内置",user:"用户级",project:"项目级"},Jz={builtin:{description:"系统内置的 AI 子 Agent 与工作模式。"},user:{description:"当前用户自定义的 Agent。"},project:{description:"当前工作区的项目级 Agent。"},customAgents:{title:"自定义 Agent",description:"用户级与项目级 Agent,通过下方标签切换。"}},Yz={titleEdit:"编辑Agent",titleCreate:"添加Agent",fields:{level:"级别",levelUser:"用户级(全局)",levelProject:"项目级(工作区路径)",levelProjectDisabled:" - 需要先打开工作区",selectedProjectPath:"所选项目路径: {{path}}",name:"Agent名称 *",namePlaceholder:"例如: code-writer",description:"描述 *",descriptionPlaceholder:"简短描述Agent的功能",tools:"工具",toolsOptional:"可选",toolsPlaceholder:"例如: FileReadTool, FileWriteTool, BashTool",color:"颜色",colors:{blue:"蓝色",red:"红色",green:"绿色",purple:"紫色",orange:"橙色",yellow:"黄色"},systemPrompt:"系统提示词(Markdown格式)*",systemPromptPlaceholder:"输入Agent的系统提示词...",readonly:"只读",readonlyDescription:"只读 Agent 仅使用只读工具,可与其它任务并发执行。",enabled:"启用状态"},actions:{cancel:"取消",save:"保存",create:"创建"}},Zz={loading:"加载中...",loadingBuiltin:"加载内置 Sub-Agent...",errorPrefix:"加载失败: ",empty:{noMatch:"没有找到匹配的 Agent",noMatchBuiltin:"没有找到匹配的内置 Sub-Agent"},item:{builtin:"内置",subAgent:"子智能体",mode:"模式",toolsCount:"{{count}} 工具",editTooltip:"编辑",deleteTooltip:"删除",toolsLabel:"可用工具:",modelLabel:"模型配置",systemPromptLabel:"系统提示词:",updateTimePrefix:"更新时间: "}},Xz={noWorkspaceForProject:"请先打开一个工作区才能创建项目级Agent",nameRequired:"请输入Agent名称",nameFormatError:"名称必须以英文字母开头,仅允许英文字母、数字、-、_",descriptionRequired:"请输入Agent描述",toolsRequired:"请至少添加一个工具",contentRequired:"请输入系统提示词",updateSuccess:'Agent"{{name}}"更新成功',createSuccess:'Agent"{{name}}"创建成功',operationFailed:"{{operation}}Agent失败: {{error}}",deleteSuccess:'Agent"{{name}}"已删除',deleteFailed:"删除失败: {{error}}",confirmDeleteSubagent:"确定要删除 Agent「{{name}}」吗?将删除对应文件并从列表中移除。",toggleSuccess:'Agent"{{name}}"已{{status}}',toggleFailed:"切换状态失败: {{error}}",subagentToggleSuccess:'Sub Agent "{{name}}" 已{{status}}',subagentToggleFailed:"切换状态失败: {{error}}",enabled:"启用",disabled:"禁用",update:"更新",create:"创建",modelUpdated:'"{{name}}" 将使用 {{model}}',modelUpdateFailed:"模型设置失败",saveFailed:"保存失败"},eU={primary:"主力模型",fast:"快速模型"},tU={tools:{label:"可用工具",selectAll:"全选",clear:"清空",reset:"重置为默认",expand:"展开",collapse:"折叠",enabled:"已启用"},messages:{confirmReset:"确定要重置该模式的工具配置吗?",resetSuccess:"工具配置已重置",resetFailed:"重置失败",confirmSelectAll:"确定要启用所有工具吗?",confirmClearAll:"确定要清空所有工具吗?",allToolsEnabled:"已启用所有工具",allToolsDisabled:"已清空所有工具",toolEnabled:'"{{name}}" 已启用工具: {{tool}}',toolDisabled:'"{{name}}" 已禁用工具: {{tool}}',toolToggleFailed:"工具切换失败",modelUpdated:'"{{name}}" 将使用 {{model}}',modelUpdateFailed:"模型设置失败"}},nU={title:Vz,subtitle:Gz,toolbar:Kz,filters:Qz,section:Jz,form:Yz,list:Zz,messages:Xz,model:eU,mode:tU},oU="AI 功能",sU={all:"全部",switches:"功能开关",models:"模型配置"},iU={interaction:"交互增强",development:"开发增强",analysis:"分析功能"},aU={sessionTitle:{title:"会话标题自动生成",warning:"会话标题将使用用户消息的前20个字符"},compression:{title:"上下文压缩"}},rU={label:"模型",primary:"主力模型",fast:"快速模型",notConfigured:"未配置",fastUsesPrimary:"使用旗舰"},lU={enable:"启用",reset:"重置",save:"保存",saving:"保存中..."},cU={empty:"暂无可用模型,请先在「模型」中添加模型。",placeholder:"使用主Agent模型",updateSuccess:"{{agentName}} 将使用 {{modelName}}"},dU={"git-func-agent":{displayName:"Git 功能",description:"提交信息、代码审查"},"session-title-func-agent":{displayName:"会话标题",description:"自动生成对话标题"}},uU={text:"加载配置中..."},pU={saveSuccess:"设置已保存",saveFailed:"保存失败",confirmReset:"确定要重置功能开关为默认值吗?",hasChanges:"您有未保存的更改",updateFailed:"设置失败"},mU={title:oU,tabs:sU,sections:iU,features:aU,model:rU,common:lU,models:cU,builtinAgents:dU,loading:uU,messages:pU},gU="设置模式",hU="手动",fU="AI",yU={title:"AI 设置",loading:"正在准备设置助手…",loadError:"无法打开 AI 设置会话。",retry:"重试",newConversation:"新对话",resetting:"正在新建…",resetBusy:"请先停止当前任务,再开始新对话",resetError:"无法开始新对话,当前会话仍然保留。",resetAttachError:"新对话已开始,但暂时无法加载会话记录。请重新打开设置后重试。",sendErrors:{title:"无法完成设置请求",secureInputRequired:"这项修改需要敏感值,请在手动设置中直接输入。",requestInvalid:"无法校验这次请求,请换一种说法后重试。",revisionConflict:"这些设置已在别处发生变化,请核对最新值后重试。",manualDraftConflict:"手动设置中有尚未保存的修改,请先保存或放弃这些修改。",recoveryReadOnly:"设置当前处于只读恢复模式,请先重建默认配置。",fallback:"暂时无法处理这次设置请求,请重试。"},resetDialog:{title:"开始新对话?",message:"这会清除本次 AI 设置对话和未确认的方案,但不会撤销已经应用的设置。",confirm:"开始新对话",cancel:"保留当前对话"}},wU={title:"确认本次设置变更",description:"本次变更涉及受保护设置。继续前请核对系统生成的权威计划。",confirm:"确认并应用",reject:"保留当前设置"},vU={configured:"已配置",unconfigured:"未配置",placeholder:"输入新的替换值",update:"更新"},bU={notSet:"未设置"},kU={catalog:"无法加载设置。",submit:"无法启动本次请求。",conflict:"这些设置已在别处发生变化,现已加载最新值。",manualConflict:"此设置已在别处发生变化。可保留当前草稿,或按 Esc 使用最新值。",invalidJson:"请先输入有效的 JSON,再保存此设置。"},SU={modeLabel:gU,manualMode:hU,aiMode:fU,session:yU,confirmation:wU,secret:vU,values:bU,errors:kU},xU="模型配置",CU="编辑服务商配置",AU="新建服务商配置",_U="编辑模型配置",TU="新建模型配置",PU="基础服务商参数配置",FU="基础模型参数配置",RU="确定删除此配置?",NU={sectionTitle:"本机已登录账号",rescan:"重新扫描",empty:"未检测到本机已登录的 Codex / Gemini CLI 账号,请先在终端完成登录后重新扫描",import:"导入使用",refresh:"刷新 Token",refreshSuccess:"Token 已刷新",refreshFailed:"刷新失败:{{error}}",expiresAt:"Token 有效期至 {{time}}",tokenValid:"Token 已就绪",accountLine:"账号:{{account}}",label:"认证方式",options:{apiKey:"API Key",codexCli:"Codex CLI 已登录账号",geminiCli:"Gemini CLI 已登录账号"},detected:"将使用本机 {{label}}(账号 {{account}})",notDetected:"本机未检测到 {{kind}} 已登录账号,请先在终端完成登录",unknownAccount:"当前登录账号"},DU={title:"选择模型提供商",or:"或者",orSelectProvider:"或选择预设提供商",customTitle:"自定义配置",customDescription:"手动配置所有参数,适用于私有部署或其他未列出的提供商",getApiKey:"获取 API Key",fetchModels:"获取模型列表",fetchHint:"可从当前供应商拉取模型列表;拉取失败时回退到常用预设模型",fetchingModels:"正在拉取模型列表...",fetchSuccessCount:"已从供应商拉取 {{count}} 个模型",fetchFailedFallback:"拉取模型列表失败,已回退到常用预设模型",fetchEmptyFallback:"供应商未返回可用模型,已回退到常用预设模型",fillApiKeyBeforeFetch:"请先填写 API Key 再获取模型列表",usingPresetModels:"当前显示的是常用预设模型",noPresetModels:"暂无可用模型,请获取模型列表或手动输入模型名",backToSelection:"返回选择提供商",selectModel:"选择模型",multiSelectHint:"支持多选;选中后可分别设置每个模型的上下文窗口、最大输出 Tokens 和推理配置",searchOrInputModel:"搜索或输入模型名称...",inputModelName:"输入自定义模型名称...",useCustomModel:"按 Enter 使用",addCustomModel:"添加自定义模型",modelAlreadyInList:"该模型已在列表中",reusedExistingModel:"已使用当前服务商下已有同名模型配置(未新增重复项)",noModelsSelected:"请先选择模型",removeModel:"移除模型",expandModelSettings:"展开「{{name}}」的详细设置",collapseModelSettings:"收起「{{name}}」的详细设置",urlHint:"已预填官方 API 地址,如使用代理或私有部署可修改",formatHint:"已根据提供商自动选择,通常无需修改"},IU={opensparo:{name:"Sparo 模型平台",description:"Sparo OS 大模型平台"},gemini:{name:"Google Gemini",description:"Google Gemini 系列模型"},anthropic:{name:"Anthropic Claude",description:"Anthropic Claude 系列模型"},minimax:{name:"MiniMax",description:"MiniMax 系列模型"},moonshot:{name:"月之暗面",description:"月之暗面 Kimi 系列模型"},deepseek:{name:"DeepSeek",description:"DeepSeek 系列模型"},zhipu:{name:"智谱AI",description:"智谱AI GLM 系列模型",urlOptions:{default:"OpenAI格式-默认",anthropic:"Anthropic格式",codingPlan:"OpenAI格式-CodingPlan"}},qwen:{name:"通义千问",description:"阿里云百炼大模型平台"},volcengine:{name:"火山引擎",description:"字节跳动火山引擎大模型平台"},siliconflow:{name:"硅基流动",description:"硅基流动大模型平台",urlOptions:{default:"OpenAI格式-默认",anthropic:"Anthropic格式"}},nvidia:{name:"NVIDIA",description:"NVIDIA NIM 大模型平台"},openrouter:{name:"OpenRouter",description:"OpenRouter 大模型平台"}},MU={api:"API配置",proxy:"代理配置"},jU={all:"全部",text:"文本",multimodal:"多模态",other:"辅助"},EU={label:"模型分类",placeholder:"选择模型分类",general_chat:"文本生成",multimodal:"多模态",image_generation:"图像生成",embedding:"向量嵌入",search_enhanced:"搜索",code_specialized:"代码",speech_recognition:"语音识别"},LU={general_chat:"文本",multimodal:"多模态",image_generation:"绘图",embedding:"向量",search_enhanced:"搜索",code_specialized:"代码",speech_recognition:"语音"},$U={general_chat:"文本生成:生成文本回复、代码等,适用于大多数对话场景",multimodal:"多模态:理解图片内容并进行图文混合对话",image_generation:"图像生成:根据文字描述生成图片",embedding:"向量嵌入:将文本转换为向量,用于检索与相似度匹配",search_enhanced:"搜索:提供搜索增强回答或检索支持",code_specialized:"代码:面向代码生成、修改与审查优化",speech_recognition:"语音识别:将语音转换为文字(如智谱 GLM-ASR)"},OU={configName:"服务商名称",configNamePlaceholder:"输入服务商名称",modelName:"模型名称",modelSelection:"选择模型",modelNameHint:"智谱 GLM-ASR 使用 glm-asr,其他语音模型填写对应的模型名称",baseUrl:"API地址",resolvedUrlLabel:"实际请求地址:",forceUrlHint:"以 # 结尾可强制使用输入地址",apiKey:"API密钥",apiKeyPlaceholder:"输入您的 API Key",provider:"请求格式",providerPlaceholder:"选择请求格式",contextWindow:"上下文窗口大小",contextWindowHint:"模型支持的最大上下文窗口大小(用于计算token占用百分比)",maxTokens:"最大输出Tokens",maxTokensHint:"单次请求时限制模型输出的最大token数量(影响响应长度)",description:"描述",descriptionPlaceholder:"配置说明(可选)"},BU={enable:"启用思考",mode:"推理模式",enableHint:"需要模型支持思考模式",summaryOn:"思考开",summaryOff:"思考关",summaryDefault:"API 默认",summaryEnabled:"显式启用",summaryDisabled:"显式禁用",summaryAdaptive:"自适应",budgetTokens:"Claude 思考预算",optionDefault:"API 默认",optionEnabled:"启用",optionDisabled:"禁用",optionAdaptive:"自适应"},WU={label:"推理深度",hint:"控制 provider 支持的推理强度,适用于 Responses API 与支持自适应推理的 Claude 模型",placeholder:"使用 API 默认值",options:{none:"无",minimal:"最小",low:"低",medium:"中",high:"高",xhigh:"超高",max:"最大"}},zU={basicInfo:"基本信息",modelName:"模型名称",provider:"请求格式",apiUrl:"API地址",contextWindow:"上下文窗口",maxOutput:"最大输出",description:"描述",capabilities:"能力",tokens:"tokens"},UU={enable:"启用代理",url:"代理地址",urlPlaceholder:"http://127.0.0.1:7890 或 socks5://127.0.0.1:1080",urlHint:"支持 HTTP/HTTPS/SOCKS5 代理,格式:协议://地址:端口",username:"用户名(可选)",usernamePlaceholder:"代理认证用户名",password:"密码(可选)",passwordPlaceholder:"代理认证密码",save:"保存代理配置",saveSuccess:"代理配置已保存,重启IDE后生效"},HU={title:"流式超时",label:"空闲超时(秒)",placeholder:"留空表示不设超时",invalid:"请输入正整数秒数,或留空。",save:"保存流式超时",saveSuccess:"流式超时已保存"},qU={text_chat:"对话",image_understanding:"多模态",image_generation:"绘图",embedding:"向量",search:"搜索",code_specialized:"代码",function_calling:"工具",speech_recognition:"语音"},VU={openaiCompatible:"OpenAI 兼容",responsesApi:"OpenAI Responses API",claudeApi:"Claude API",geminiApi:"Gemini GenerateContent API",geminiCodeAssist:"Gemini Code Assist"},GU={expandModels:"展开「{{name}}」的模型列表",collapseModels:"收起「{{name}}」的模型列表",modelUnit:"模型",deleteProvider:"删除服务商",deleteTitle:"删除该服务商?",deleteMessage:"将移除「{{name}}」及其下全部 {{count}} 个已保存的模型配置。",deleteWarning:"此操作无法撤销。",deleteConfirm:"删除服务商"},KU={save:"保存",cancel:"取消",edit:"编辑",delete:"删除",test:"测试连接",newConfig:"新建配置",addModel:"添加模型",addProvider:"添加服务商",createFirst:"创建第一个配置"},QU={noModels:"暂无模型配置",noMatchingModels:"没有找到匹配的模型"},JU={placeholder:"搜索模型名称、提供商..."},YU={fillRequired:"请填写必要字段",fillModelName:"请填写模型名称",duplicateModelNameUnderProvider:"该服务商下已有同名模型,请改用其他名称或编辑已有条目",changedExternally:"该模型配置已在其他界面更新,请重新打开后再保存",saveFailed:"保存失败",deleteFailed:"删除配置失败",loadFailed:"加载AI配置失败",testSuccess:"测试成功",testFailed:"测试失败",errorDetails:"详细错误",connectionTestMessages:{toolCallsNotDetected:"本次测试未检测到工具调用,因此暂时无法验证工具调用能力。",imageInputCheckFailed:"连接已成功,但图片输入测试未通过。"},autoSetPrimary:"已自动设为主力模型",defaultDescription:"{{name}} 模型配置",cloneName:"{{name}} - 副本",templateName:"{{provider}} - {{modelName}}",templateDescription:"{{description}} - {{modelName}}"},ZU={title:"高级设置",inlineThinkInText:{label:"解析文本中的 标签",hint:"将文本流中的 ... 实时拆分为思考内容"},skipSslVerify:{label:"跳过SSL证书验证",warning:"跳过SSL证书验证存在安全风险,请仅在测试环境或内网环境使用!"},customHeaders:{label:"自定义请求头",hint:"添加或修改HTTP请求头",modeLabel:"应用模式",modeReplace:"替换",modeMerge:"合并",modeReplaceHint:"自定义请求头将完全替换默认请求头(需要自行添加Content-Type、Authorization等)",modeMergeHint:"先应用默认请求头,再应用自定义请求头(可覆盖已有值,添加新值)",addHeader:"添加字段",keyPlaceholder:"key",valuePlaceholder:"value"},customRequestBody:{label:"自定义请求体",hint:"输入JSON格式的请求体字段,用于覆盖默认请求参数",modeMerge:"合并",modeTrim:"精简",modeMergeHint:"在默认请求体基础上合并自定义字段,可覆盖已有字段。",trimHintOpenAI:"发送前仅保留 model、messages、max_tokens,以及 stream / tools 等运行必需字段,再应用自定义请求体。",trimHintResponses:"发送前仅保留 model、input、instructions、max_output_tokens,以及 stream / tools 等运行必需字段,再应用自定义请求体。",trimHintAnthropic:"发送前仅保留 model、messages、system、max_tokens,以及 stream / tools 等运行必需字段,再应用自定义请求体。",trimHintGemini:"发送前仅保留 contents、systemInstruction、generationConfig.maxOutputTokens,以及 tools / toolConfig;Gemini 的 model 由请求 URL 决定。",placeholder:`例如: +{ + "temperature": 0.8, + "top_p": 0.9 +}`,invalidJson:"JSON格式错误,请检查语法",validJson:"JSON格式有效",mergeHint:"自定义字段将覆盖默认请求体中的对应字段"}},XU={title:xU,editProvider:CU,newProvider:AU,editModel:_U,newModel:TU,editProviderSubtitle:PU,editSubtitle:FU,confirmDelete:RU,cliAuth:NU,providerSelection:DU,providers:IU,tabs:MU,categories:jU,category:EU,categoryIcons:LU,categoryHints:$U,form:OU,thinking:BU,reasoningEffort:WU,details:zU,proxy:UU,streamIdleTimeout:HU,capabilities:qU,formats:VU,providerGroup:GU,actions:KU,empty:QU,search:JU,messages:YU,advancedSettings:ZU},eH="AI 用量",tH={refresh:"刷新",reset:"重置"},nH="正在加载用量历史...",oH={loadFailed:"加载 AI 用量历史失败。",resetFailed:"重置 AI 用量历史失败。"},sH={title:"重置 AI 用量历史?",message:"这会重置此设备上保存的所有 AI 用量记录,操作不可撤销。",confirm:"重置记录",cancel:"取消"},iH={filters:"查看方式",overview:"总览",trend:"历史走势",recent:"最近请求",by:{agent:"按智能体查看",model:"按模型查看",time:"按时间查看"}},aH={timeRange:{label:"时间范围",today:"今天",thisWeek:"本周",thisMonth:"本月",all:"全部"},groupBy:{label:"分组",agent:"智能体",model:"模型",time:"时间"},includeSubagent:{label:"包含子智能体",description:"将委派给子智能体的模型调用计入同一视图。"}},rH={total:"总 tokens",input:"输入",output:"输出",requests:"请求数"},lH={unknown:"未知",requests:"{{count}} 次请求",inOut:"输入 {{input}} / 输出 {{output}}"},cH={time:"时间",agent:"智能体",model:"模型",tokens:"Token 数"},dH="这个视图下暂时没有 AI 用量记录。",uH={title:eH,actions:tH,loading:nH,messages:oH,resetDialog:sH,sections:iH,filters:aH,metrics:rH,labels:lH,table:cH,empty:dH},pH="外观",mH="选择语言、主题和字体,不影响工作区行为。",gH={title:"外观",language:"语言",themes:"主题",builtIn:"内置",custom:"自定义",export:"导出",delete:"删除",confirmDelete:'确定要删除主题 "{{name}}" 吗?',languageRowHint:"选择一个语言包作为当前界面语言。",themeRowHint:"选择界面配色主题。",themeLoading:"正在加载主题设置...",themeLoadFailed:"主题设置加载失败。",systemTheme:"跟随系统",systemThemeDescription:"根据系统浅色或深色外观自动切换主题,并随系统设置更新。",presets:{dark:{name:"暗色",description:"Sparo OS 默认暗色主题,采用克制的印红强调色"},light:{name:"亮色",description:"亮色主题,柔和底板、墨色文字与克制强调色"}},fontSize:{title:"字体大小",loading:"正在加载字体设置...",loadFailed:"字体设置加载失败。",uiSizeLabel:"界面字体",uiSizeHint:"控制导航、面板、设置与其他界面元素的字体大小。",levels:{compact:"紧凑",small:"小",default:"默认",medium:"中等",large:"大",custom:"自定义"},customPxLabel:"自定义大小(12-20 px)",resetButton:"恢复默认",previewText:"Sparo OS 是一个由 AI 驱动的编程环境。The quick brown fox jumps over the lazy dog.",flowChatLabel:"对话区域",flowChatHint:"关闭时,对话区域跟随界面字体大小。开启后,可设置 12-20 px 的独立字号。",flowChatCustomToggle:"自定义对话字体大小",markdownEditorLabel:"Markdown 编辑器",markdownEditorHint:"关闭时,Markdown 编辑与预览跟随界面字体大小。开启后,可选择 12-20 px 的阅读与编辑字号。",markdownEditorCustomToggle:"自定义 Markdown 编辑器字体大小"}},hH={title:pH,subtitle:mH,appearance:gH},fH="常规",yH="设置启动行为、日志、终端默认值、托盘行为和通知。",wH={sections:{title:"登录时启动"},toggleLabel:"开机自动启动",toggleDescription:"登录系统后自动启动 Sparo OS;具体表现因操作系统而异。",messages:{loading:"加载中…",loadFailed:"无法读取开机启动设置",saveFailed:"无法更新开机启动设置"}},vH={sections:{logging:"日志",loggingHint:"日志级别与本次启动日志目录",level:"日志级别",path:"本次启动日志路径"},level:{description:"实时控制日志输出级别,修改后立即生效。"},path:{description:"本次启动写入日志文件所在的目录。"},levels:{trace:"Trace",debug:"Debug",info:"Info",warn:"Warn",error:"Error",off:"Off"},actions:{openFolder:"打开文件夹",openFolderTooltip:"在文件管理器中打开日志文件夹"},messages:{loading:"加载中...",loadFailed:"加载日志配置失败",saveFailed:"保存日志级别失败",levelUpdated:"日志级别已更新",openedFolder:"日志文件夹已打开",openFailed:"打开日志文件夹失败",pathUnavailable:"日志文件夹路径不可用"}},bH={sections:{terminal:"终端",defaultTerminal:"默认终端"},controls:{autoDetect:"自动检测 (推荐)",description:"新建终端时使用的默认 Shell 类型",placeholder:"选择默认终端",noShells:"未检测到可用的终端"},warnings:{cmd:"CMD 不支持 Shell 集成,AI 命令将通过 PowerShell 执行。",gitBash:"Git Bash 安装 oh-my-zsh 后可能导致 Shell 集成失效,如遇异常建议切换至 PowerShell。"},messages:{loading:"加载中...",loadFailed:"加载配置失败",updated:"默认终端已更新",saveFailed:"保存配置失败"}},kH={sections:{title:"系统托盘"},closeAction:{label:"关闭按钮行为",description:"点击窗口关闭按钮时执行的动作。",options:{tray:"最小化到托盘",quit:"退出应用"}},messages:{saveSuccess:"托盘设置已保存",saveFailed:"托盘设置保存失败"}},SH={title:"通知",dialogCompletion:{label:"任务完成通知",description:"当 AI 任务完成且窗口不在焦点时,弹出 Toast 通知"},startupTips:{label:"启动时显示使用技巧",description:"每次启动时随机展示一条使用技巧卡片,帮助发现更多功能"},messages:{saveSuccess:"通知设置已保存",saveFailed:"保存通知设置失败"}},xH={title:fH,subtitle:yH,launchAtLogin:wH,logging:vH,terminal:bH,tray:kH,notifications:SH},CH="设置",AH="选择配置项",_H="搜索配置…",TH="没有匹配的配置",PH="清除搜索",FH="Beta",RH={title:"设置暂时只读",message:"已保存的配置无法安全加载,Sparo OS 已使用安全默认值继续启动。",description:"准备好后可重建当前默认配置。此操作会删除不可用配置及其保存的密钥,但不会影响会话、工作区、应用和其他数据。",promptTitle:"已保存的配置不可用",promptMessage:"Sparo OS 正在使用安全默认值运行。是否立即重建当前默认配置?不可用配置及其保存的密钥将被删除,其他应用数据保持不变。",action:"重建默认配置",rebuilding:"正在重建…",later:"稍后处理",failed:"默认配置重建失败。Sparo OS 仍在只读安全模式下正常运行;可稍后在设置中重试。"},NH={appearance:"语言、主题与界面字体大小。",basics:"日志、终端 Shell、开机启动与通知。",models:"AI 模型、API 密钥、供应商与代理。",personalization:"标题生成、Agent 伙伴与思考过程。",voiceInput:"本地语音输入、模型下载与麦克风默认项。",bitfunCoder:"BitFun Coder 调试日志、Ingest 端口与语言模板。",permissions:"工具执行确认、超时与桌面自动化授权。",memory:"自动记忆开关与提炼频率。",editor:"代码编辑器字体、显示与格式化。",lsp:"语言服务与代码智能。",keyboard:"快捷键与键位。",aiUsage:"按智能体、模型和时间查看历史 AI 用量。",dataStorage:"应用数据、存储用量与重置控制。"},DH={general:"基础",data:"数据",smartCapabilities:"智慧化配置",productApps:"产品应用",advanced:"高级"},IH={ai:"AI",appearance:"外观",basics:"常规",models:"模型",personalization:"个性化",voiceInput:"语音输入",bitfunCoder:"BitFun Coder","bitfun-coder":"BitFun Coder",permissions:"权限",memory:"记忆",skills:"技能",agents:"智能体",editor:"代码编辑器",lsp:"语言服务",keyboard:"快捷键",aiUsage:"AI 用量",dataStorage:"数据与存储",terminal:"终端","product-apps":"产品应用",themes:"主题",font:"字体",version:"版本","last-modified":"最后修改时间"},MH={advanced:"高级","agent-companion":"Agent 伙伴",appearance:"外观",behavior:"行为",composer:"消息输入","computer-use":"桌面自动化","daily-letter":"每日来信",debug:"调试","default-model":"默认模型",display:"显示","font-size":"字体大小","global-auto-memory":"全局自动记忆","goal-mode":"目标模式","host-scan":"主机扫描",language:"语言",logging:"日志",models:"模型",notifications:"通知",providers:"模型供应商",proxy:"代理",runtime:"运行时","session-title":"会话标题",shell:"Shell",shortcuts:"快捷键",theme:"主题","thinking-process":"思考过程","tool-execution":"工具执行",tray:"系统托盘","workspace-auto-memory":"工作区自动记忆"},jH={"enable-visual-mode":"视觉模式",version:"版本","last-modified":"最后修改时间"},EH={title:CH,selectConfig:AH,searchPlaceholder:_H,searchNoResults:TH,searchClear:PH,beta:FH,recovery:RH,tabDescriptions:NH,categories:DH,tabs:IH,sections:MH,fields:jH},LH="数据与存储",$H="查看本地存储占用,并执行有范围的清理或重置操作。",OH="正在加载存储用量...",BH={reset:"执行重置",resetting:"正在重置...",openFolderTooltip:"在文件管理器中打开"},WH={usage:"本机存储用量",reset:"重置与清理"},zH={total:"托管合计"},UH={config:"设置与偏好",data:"通用应用数据",state:"界面与任务状态",sessions:"会话",works:"工作",runs:"运行记录",app_data:"智能应用数据",services:"系统服务",workspaces:"工作区运行时",agentic_os:"全局 Agentic OS 运行时",apps:"已安装和生成的应用",components:"组件",agents:"智能体",skills:"技能",skill_suites:"技能套件",runtimes:"托管运行时",browser_profiles:"托管浏览器资料",secrets:"凭据与授权",cache:"缓存",logs:"日志",temp:"临时文件",backups:"备份"},HH={mode:{soft:"清理缓存",appData:"重置本机数据",factory:"恢复出厂"},summary:{soft:"清理缓存、临时文件和界面布局状态,保留设置与数据。",appData:"删除本机设置、状态、会话、应用、缓存和运行时数据。",factory:"清除 Sparo OS 管理的全部本地数据,包括凭据与浏览器配置。"},details:{soft:"通过清理缓存、临时文件和界面布局状态释放空间。设置、凭据和工作区数据均会保留。",appData:"将应用恢复到干净的本机状态。设置、会话、Work、Run、智能应用数据、系统服务状态、Agentic OS 运行时、已安装应用、缓存和临时文件都会被删除。",factory:"清除 Sparo OS 管理的所有内容,包括凭据、浏览器配置、自定义智能体、技能和托管运行时。"},dialog:{confirm:"继续",cancel:"取消"},confirm:{included:"包含",excluded:"跳过",soft:{title:"确定清理缓存吗?",message:"将清理缓存、临时文件和界面布局状态。设置、凭据和工作区数据不会被删除。"},appData:{title:"确定重置本机数据吗?",message:"此操作将永久删除所选的 Sparo OS 本机数据,且无法撤销。你的项目源文件不会被改动,重置完成后应用会自动重启。"},factory:{title:"确定恢复出厂设置吗?",message:"此操作将永久删除 Sparo OS 在本机管理的全部数据,且无法撤销。重置完成后应用会自动重启。"}},options:{forced:"此模式下始终删除",backup:{label:"创建重置备份",description:"删除前将配置和状态复制到备份文件夹。"},logs:{label:"包含日志",description:"同时删除运行日志。"},secrets:{label:"包含密钥",description:"同时删除已保存的凭据和授权数据。"},browser:{label:"包含浏览器配置",description:"同时删除 Sparo 托管浏览器的登录状态和配置。"}}},qH={confirm:"重置并重启",cancel:"取消"},VH={loadFailed:"加载存储用量失败。",resetFailed:"重置本机数据失败。",resetComplete:"重置 {{resetId}} 已完成,释放 {{size}}。继续使用前请重启 Sparo OS。",openFolderFailed:"无法在文件管理器中打开该目录。"},GH="暂无已跟踪的存储用量。",KH={title:LH,subtitle:$H,loading:OH,actions:BH,sections:WH,metrics:zH,categoryLabels:UH,reset:HH,resetDialog:qH,messages:VH,empty:GH},QH="调试配置",JH="日志和语言调试模板配置",YH={combined:"调试模式设置",settings:"调试设置",templates:"语言调试模板"},ZH={javascript:"JavaScript / TypeScript",python:"Python",rust:"Rust",go:"Go",java:"Java"},XH={logPath:{label:"日志文件路径",description:"Debug日志保存路径(相对于工作区根目录),默认为 .sparo_os/debug.log",placeholder:".sparo_os/debug.log",browse:"浏览"},ingestPort:{label:"Ingest服务器端口",description:"用于接收Web应用日志的HTTP服务器端口"}},e7={description:"启用模板后,将使用自定义模板覆盖内置逻辑。关闭则使用系统内置的默认模板。",enableTooltip:"点击启用自定义模板",disableTooltip:"点击禁用自定义模板",instrumentation:{label:"插桩代码模板",placeholder:"输入插桩代码模板...",placeholders:"可用占位符"},region:{label:"Region标记",startPlaceholder:"开始标记",endPlaceholder:"结束标记"},notes:"注意事项",configure:"配置模板",reset:"重置为默认模板",noteItems:{javascript:{postToIngest:"通过 HTTP POST 发送日志到 ingest 服务器",replaceData:"{DATA} 需替换为 JavaScript 对象表达式"},python:{appendNdjson:"直接追加 NDJSON 日志到工作区的 LOG_PATH",ensureAscii:"使用 ensure_ascii=False 支持中文等非ASCII字符",replaceData:'{DATA} 需替换为 Python 表达式(如 {"var": var} 或 locals())',importOnce:"导入语句只需在文件顶部写一次"},rust:{appendNdjson:"直接追加 NDJSON 日志到 LOG_PATH",requireSerdeJson:"需要 serde_json 依赖: cargo add serde_json",replaceData:'{DATA} 需替换为 Rust 表达式(如 {"var": var})',syncOnly:"在同步代码中使用;异步代码需改用 tokio::fs"},go:{iife:"使用立即执行匿名函数,可在任意位置插入",appendNdjson:"直接追加 NDJSON 日志到 LOG_PATH",imports:'需要导入 "os", "encoding/json", "time"',replaceData:'{DATA} 需替换为 Go 表达式(如 map[string]interface{}{"var": var})'},java:{appendNdjson:"直接追加 NDJSON 日志到 LOG_PATH",requireGson:"需要 Gson 依赖(或可用 Jackson 替代)",replaceData:'{DATA} 需替换为 Java 对象(如 Map.of("var", var))',writeString:"Java 11+ 可用 Files.writeString;旧版需用 Files.write + getBytes()"}}},t7={save:"保存配置",saving:"保存中...",cancel:"取消"},n7={logFile:"日志文件"},o7={loading:"加载中...",loadFailed:"加载配置失败",saveSuccess:"配置已保存",saveFailed:"保存配置失败",resetSuccess:"已恢复默认配置",resetFailed:"重置配置失败",logPathUpdated:"日志文件路径已更新",selectFileFailed:"选择文件失败",templateEnabled:"已启用 {{name}} 模板",templateDisabled:"已禁用 {{name}} 模板"},s7={title:QH,subtitle:JH,sections:YH,languageLabels:ZH,settings:XH,templates:e7,actions:t7,fileDialog:n7,messages:o7},i7="默认模型配置",a7="加载中...",r7={default:"默认配置",models:"模型列表",proxy:"网络代理"},l7={title:"核心配置",required:"必填",optional:"可选",primary:{label:"主力模型",description:"用于复杂推理、代码生成、多步骤任务",placeholder:"请选择主力模型"},fast:{label:"快速模型",description:"用于简单问答、快速响应场景,节省成本",hint:"未配置时,所有任务都使用主力模型",placeholder:"请选择快速模型",notSet:"不设置(使用主力模型)"}},c7={title:"扩展能力模型配置",capabilities:{image_understanding:{label:"图片理解模型",description:"当主模型不支持图片输入时,用于分析图片和截图内容"},image_generation:{label:"图像生成",description:"根据文字描述生成图片"},speech_recognition:{label:"语音识别",description:"将语音转换为文字,支持语音输入"}},notConfigured:"未配置",notSet:"不设置",selectModel:"选择模型",autoSelect:"自动选择"},d7={title:"高级配置",modeOverrides:{title:"模式模型覆盖",description:"为特定模式指定不同的模型(默认使用主力模型)"},subAgentOverrides:{title:"SubAgent 模型覆盖",description:"为特定助手指定不同的模型(默认使用主力模型)"},subAgents:{"git-func-agent":{displayName:"Git 功能",description:"提交信息、代码审查"},"session-title-func-agent":{displayName:"会话标题",description:"自动生成对话标题"},"arc-func-agent":{displayName:"架构分析",description:"依赖图、Mermaid 图表"},compression:{displayName:"上下文压缩",description:"智能压缩长对话上下文"}}},u7={primary:"主力模型",primaryShort:"旗舰",fast:"快速模型",fastShort:"快速",custom:"其他",customShort:"其他",modelChoice:"模型选择",selectModel:"选择模型",notConfigured:"未配置,将使用主力模型"},p7={noModels:"暂无可用模型,请先在「模型列表」中添加模型"},m7={loadFailed:"加载配置失败",updateFailed:"更新失败",modelUpdated:"{{slot}}已设置为 {{name}}",capabilityUpdated:"能力模型已更新"},g7={title:i7,loading:a7,tabs:r7,core:l7,optional:c7,advanced:d7,selection:u7,empty:p7,messages:m7},h7="代码编辑器",f7="代码编辑器设置会自动保存,并同步到已打开的编辑器。",y7={appearance:{title:"外观设置"},behavior:{title:"编辑行为"},display:{title:"显示设置"},advanced:{title:"高级功能"},reset:{title:"重置"}},w7={font:"字体",fontSize:"字体大小",lineHeight:"行高"},v7={tabSize:"Tab 大小",insertSpaces:"使用空格缩进",insertSpacesDesc:"Tab 键插入空格而非制表符",wordWrap:"自动换行",wordWrapOptions:{off:"禁用",on:"启用",wordWrapColumn:"在列数处换行",bounded:"在视口和列数处换行"},lineNumbers:"行号显示",lineNumberOptions:{on:"显示",off:"隐藏",relative:"相对行号",interval:"间隔显示"}},b7={minimap:"显示缩略图",minimapDesc:"在编辑器侧边显示代码缩略图",minimapPosition:"缩略图位置",minimapPositionLeft:"左侧",minimapPositionRight:"右侧",minimapSize:"缩略图大小",minimapSizeAuto:"自动",minimapSizeFill:"填充",minimapSizeFit:"适应"},k7={formatOnSave:"保存时格式化",formatOnSaveDesc:"保存文件时自动格式化代码",formatOnPaste:"粘贴时格式化",formatOnPasteDesc:"粘贴代码时自动格式化",trimAutoWhitespace:"自动删除行尾空格",trimAutoWhitespaceDesc:"保存时移除行尾多余的空格"},S7={reset:"重置为默认",save:"保存设置"},x7={loading:"加载中...",loadFailed:"加载配置失败",saving:"保存中...",saveSuccess:"配置已保存,已打开的编辑器会自动更新",saveFailed:"保存配置失败",resetFailed:"重置配置失败",confirmReset:"确定要重置编辑器配置为默认值吗?",resetDone:"已重置为默认值"},C7={title:"重置代码编辑器设置?",message:"代码编辑器字体、行为、显示和高级选项都会恢复为默认值。",confirm:"重置代码编辑器",cancel:"取消"},A7={title:h7,subtitle:f7,sections:y7,appearance:w7,behavior:v7,display:b7,advanced:k7,actions:S7,messages:x7,resetDialog:C7},_7="快捷键",T7="查看快捷键,录制修改后再统一应用。",P7="搜索快捷键或键位…",F7="应用",R7="保存中…",N7="重置为默认",D7="点击录制新的快捷键",I7="按下新键位…",M7="撤销此更改",j7="系统固定快捷键,无法自定义",E7="未找到匹配的快捷键",L7="冲突",$7="保存失败,请重试",O7="重置失败,请重试",B7="键位不一致,可重新录制为一组",W7={title:"重置快捷键?",message:"所有自定义快捷键都会被移除,并恢复为默认键位。",confirm:"重置快捷键",cancel:"取消"},z7={space:"空格"},U7={app:"全局",canvas:"编辑器画布",chat:"Agent 会话",filetree:"文件树"},H7={nav:{toggleSearch:"打开导航搜索"},scene:{openSettings:"打开设置",openTerminal:"打开终端",escapeToAgenticBase:"返回 Agentic OS 桌面"},canvas:{splitHorizontal:"水平分屏",splitVertical:"垂直分屏",anchorZone:"切换锚点区",maximize:"最大化编辑器",closePreview:"关闭预览"},tab:{close:"关闭当前标签页",reopenClosed:"重新打开已关闭标签页",switchMerged:"切换编辑器标签",switchMergedHint:"录制一次修饰键 + 任意数字 1–9;同一组修饰键会应用到各标签位。"},chat:{btwFill:"开启侧问会话",stopGeneration:"停止生成",activateInput:"激活输入框",newSession:"新建会话"},filetree:{rename:"重命名",delete:"删除",refresh:"刷新",newFile:"新建文件",newFolder:"新建文件夹",collapseAll:"折叠所有目录"}},q7={title:_7,subtitle:T7,search:P7,apply:F7,saving:R7,reset:N7,clickToRecord:D7,recording:I7,revertChange:M7,fixedBinding:j7,noResults:E7,conflict:L7,saveError:$7,resetError:O7,mergedNonUniform:B7,resetDialog:W7,keyLabels:z7,scopes:U7,shortcuts:H7},V7="MCP",G7="管理 MCP 服务器连接",K7={serverList:{title:"MCP 服务列表",description:"统一管理 MCP 服务状态与 JSON 配置。"}},Q7={servers:"服务器",add:"添加服务器"},J7={id:"服务器ID",idPlaceholder:"github-mcp",idHint:"服务器ID是唯一标识符,不可重复",name:"服务器名称",namePlaceholder:"GitHub MCP Server",type:"服务器类型",typeLocal:"本地进程",typeRemote:"远程服务",typeContainer:"容器服务",command:"启动命令",commandPlaceholder:"node",commandHint:"例如: node, python, npx 等",args:"命令参数(每行一个)",argsPlaceholder:`server.js +--port +3000`,argsHint:"每行一个参数",env:"环境变量",envPlaceholder:'JSON 格式,例如: {"KEY": "value"}',url:"服务器URL",urlPlaceholder:"http://localhost:3000",enabled:"启用此服务器",autoStart:"应用启动时自动运行",transport:"传输方式",statusDetail:"状态详情",remoteUrl:"远程地址",remoteAuth:"认证状态",remoteAuthConfigured:"已配置",remoteAuthConfiguredWithSource:"已通过 {{source}} 配置",remoteAuthMissing:"未配置",remoteOAuthReady:"已配置 OAuth,等待授权",remoteAuthMethod:"认证方式",remoteAuthMethodOAuthXaa:"已配置 OAuth,预留 XAA",remoteAuthMethodOAuth:"OAuth",remoteAuthMethodXaa:"XAA",remoteOAuthIdle:"尚未开始",remoteOAuthAwaitingBrowser:"等待打开浏览器",remoteOAuthAwaitingCallback:"等待提供方回调",remoteOAuthExchangingToken:"正在交换授权码",remoteOAuthAuthorized:"已授权",remoteOAuthFailed:"失败",remoteOAuthCancelled:"已取消",runtime:{source:"来源",path:"解析路径",available:"命令可用",unavailable:"命令不可用",managed:"托管运行时",system:"系统环境",unknown:"未知",unsupportedReason:"不可用原因",unsupportedRemoteSse:"暂不支持远程 MCP SSE 传输"},authSource:{headers:"请求头",env:"环境变量",oauth:"OAuth"}},Y7={uninitialized:"未初始化",starting:"启动中",connected:"已连接",healthy:"健康",needsAuth:"需要认证",reconnecting:"重连中",failed:"失败",stopping:"停止中",stopped:"已停止",disconnected:"已断开",connecting:"连接中",error:"错误"},Z7={add:"添加服务器",addFirst:"添加第一个服务器",edit:"编辑",editServer:"编辑服务器",addServer:"添加服务器",delete:"删除",start:"启动",stop:"停止",restart:"重启",refresh:"刷新",save:"保存",saveConfig:"保存配置",cancel:"取消",cancelAdd:"取消添加",close:"关闭",backToList:"返回列表",jsonConfig:"JSON 配置",remoteAuth:"远程认证",startRemoteOAuth:"通过 OAuth 连接",restartRemoteOAuth:"重新发起 OAuth",reconnectRemoteOAuth:"重新通过 OAuth 连接",cancelRemoteOAuth:"取消 OAuth",saveRemoteAuth:"保存并重连"},X7={placeholder:"搜索服务器..."},e9={noServers:"暂无配置的 MCP 服务器",noServersHint:"添加 MCP 服务器以扩展功能",noMatchingServers:"没有找到匹配的服务器"},t9="加载中...",n9={type:"类型",enabled:"启用",autoStart:"自动启动",status:"状态",yes:"是",no:"否"},o9={remoteAuthTitle:"远程认证:{{serverName}}",remoteOAuthHint:"使用 OAuth 连接这个远程 MCP 服务器。Sparo OS 会监听一个本地回调地址,并在授权完成后重新连接该服务器。",remoteOAuthCurrentStatus:"OAuth 状态:{{status}}",remoteOAuthRedirectUri:"回调地址:{{redirectUri}}",remoteOAuthStatus:"OAuth 详情:{{status}} - {{message}}",remoteAuthHint:"粘贴 Bearer token 或完整的 Authorization 请求头值。保存后会重启远程 MCP 服务器。",remoteAuthServerUrl:"服务器地址:{{url}}",remoteAuthPlaceholder:"Bearer eyJ... 或 eyJ..."},s9={title:"MCP JSON 配置",hint1:"使用标准 Cursor 格式的 MCP 配置。配置将自动保存到用户目录下的 app.json 文件中。",hint2:'格式说明:可以省略 type 字段。提供 "command" 时按 stdio(本地进程)解析;提供 "url" 时按 sse(远程服务)解析。也可显式设置 type="stdio"/"sse" 以保持兼容。',lintLocation:"(第 {{line}} 行,第 {{column}} 列)",lintError:"JSON 有语法错误{{location}}:{{message}}",exampleTitle:"配置示例:",localProcess:"本地进程(stdio):",remoteService:"远程服务(sse):"},i9={title:"MCP 资源",actions:{refresh:"刷新",close:"关闭"},search:{placeholder:"搜索资源..."},loading:{resources:"正在加载资源...",content:"正在加载内容..."},empty:{noMatch:"未找到资源",noResources:"暂无资源",selectToView:"选择资源以查看内容"},errors:{loadContentFailed:"加载资源内容失败",binaryContent:"二进制资源内容无法在此预览"},mockContent:`# {{name}} + +这是 {{uri}} 的内容 + +Lorem ipsum dolor sit amet...`},a9={addSuccess:"服务器添加成功",addFailed:"添加服务器失败",deleteSuccess:"服务器已删除",deleteFailed:"删除服务器失败",deleteConfirm:`确定要删除这个 MCP 服务器吗? + +注意:删除后配置无法恢复。`,startSuccess:'服务器 "{{serverId}}" 已启动',startFailed:'启动服务器 "{{serverId}}" 失败',stopSuccess:'服务器 "{{serverId}}" 已停止',stopFailed:'停止服务器 "{{serverId}}" 失败',restartSuccess:'服务器 "{{serverId}}" 已重启',restartFailed:'重启服务器 "{{serverId}}" 失败',saveSuccess:"MCP 配置已保存并生效",saveFailed:"配置保存失败",partialStartFailed:"配置已保存,但部分服务器启动失败。请检查服务器配置是否正确。",serverSaved:'服务器 "{{name}}" 已保存',jsonError:"JSON 格式错误",nameRequired:"请输入服务器名称",idRequired:"请输入服务器 ID",commandRequired:"本地进程类型的服务器必须提供启动命令",urlRequired:"远程服务类型的服务器必须提供服务器地址",validationFailed:"校验失败",commandUnavailable:'服务器 "{{serverId}}" 的命令不可用,请检查运行时安装或命令配置。',remoteOAuthAuthorized:'服务器 "{{serverId}}" 的 OAuth 已连接。',remoteOAuthFailed:'服务器 "{{serverId}}" 的 OAuth 连接失败。',remoteAuthRequired:"请提供 Bearer token 或完整的 Authorization 请求头值。",remoteAuthUpdated:'已更新服务器 "{{serverId}}" 的远程认证。',remoteOAuthStarted:'已为服务器 "{{serverId}}" 打开 OAuth 登录。'},r9={unknownError:"未知错误",jsonFormatError:"JSON 格式错误",configStructureError:"配置结构错误",serverConfigError:"服务器配置错误",permissionError:"文件权限错误",fileOperationError:"文件操作失败",resourceNotFound:"资源不存在",serverStartError:"服务器启动失败",operationFailed:"{{context}}失败",suggestions:{jsonFormat:["使用在线 JSON 验证工具检查格式","确保所有字符串使用双引号","检查是否有多余的逗号","确认所有括号正确闭合"],configStructure:['检查配置是否包含 "mcpServers" 字段','确保 "mcpServers" 是一个对象类型',"参考界面中的配置示例"],serverConfig:["提供 command(stdio)或 url(sse)字段","args 必须是数组格式","env 必须是对象格式"],permission:["以管理员身份运行应用","检查配置文件的访问权限","确认杀毒软件没有阻止文件写入"],fileOperation:["检查磁盘空间是否充足","确认配置目录存在且可访问","尝试重启应用"],serverStart:["检查命令路径是否正确","确认所需的运行环境已安装(如 Node.js)","查看环境变量配置是否正确","检查端口是否被占用"],default:["检查网络连接","尝试重新操作","查看日志获取更多信息","如果问题持续,请联系技术支持"]},jsonParseError:`JSON 格式错误:{{message}} + +请检查: +• 所有键名和字符串值都用双引号包围 +• 没有多余的逗号 +• 所有括号正确闭合`,mcpServersRequired:`配置必须包含 "mcpServers" 字段 + +正确格式: +{ + "mcpServers": { + "server-name": { ... } + } +}`,mcpServersMustBeObject:`"mcpServers" 必须是一个对象(不能是数组或其他类型) + +正确格式: +"mcpServers": { + "server-id": {...} +}`,deleteServerFailed:'删除服务器 "{{serverId}}" 失败:{{message}}'},l9={startSuccess:"启动成功",startFailed:"启动失败",stopSuccess:"停止成功",stopFailed:"停止失败",restartSuccess:"重启成功",restartFailed:"重启失败",saveSuccess:"保存成功",saveFailed:"保存失败",deleteSuccess:"删除成功",deleteFailed:"删除失败",operationFailed:"操作失败",partialStartFailed:"部分服务器启动失败",suggestionPrefix:"建议:"},c9={title:V7,subtitle:G7,section:K7,tabs:Q7,server:J7,status:Y7,actions:Z7,search:X7,empty:e9,loading:t9,labels:n9,modal:o9,jsonEditor:s9,resourceBrowser:i9,messages:a9,errors:r9,notifications:l9},d9="记忆",u9="控制后台记忆提炼与主机扫描的启用状态和频率。",p9={global:{sectionTitle:"全局记忆",enabled:"启用全局自动记忆",enabledDesc:"自动提取可长期复用的知识并写入全局 agentic_os 记忆。",extractEveryEligibleTurns:"全局记忆更新频率",extractEveryEligibleTurnsDesc:"每完成 N 轮符合条件的对话,更新一次 agentic_os 记忆。",minExtractIntervalMinutes:"最小更新时间间隔",minExtractIntervalMinutesDesc:"0 表示关闭冷却间隔。",forceExtractAfterPendingEligibleTurns:"冷却期间强制更新阈值",forceExtractAfterPendingEligibleTurnsDesc:"0 表示关闭该覆盖规则。否则当待处理的符合条件轮次达到该阈值时,即使冷却时间未到也会立即执行自动记忆。"},workspace:{sectionTitle:"工作区记忆",enabled:"启用工作区自动记忆",enabledDesc:"自动提取可长期复用的知识并写入当前工作区记忆。",extractEveryEligibleTurns:"工作区记忆更新频率",extractEveryEligibleTurnsDesc:"每完成 N 轮符合条件的对话,更新一次工作区记忆。",minExtractIntervalMinutes:"最小更新时间间隔",minExtractIntervalMinutesDesc:"0 表示关闭冷却间隔。",forceExtractAfterPendingEligibleTurns:"冷却期间强制更新阈值",forceExtractAfterPendingEligibleTurnsDesc:"0 表示关闭该覆盖规则。否则当待处理的符合条件轮次达到该阈值时,即使冷却时间未到也会立即执行自动记忆。"},units:{minutes:"分钟",turns:"轮"}},m9={text:"加载配置中..."},g9={disableAll:"禁用",enableAll:"启用",resetAll:"重置",retry:"重试"},h9={title:"重置记忆设置?",message:"全局记忆、工作区记忆和主机扫描设置都会恢复为默认值。",confirm:"重置设置",cancel:"取消"},f9={title:"主机扫描",enable:{label:"启用后台自动扫描",description:"在后台使用临时 Agentic OS 会话定期更新 host overview;首次缺失或为空时会延后 10 分钟再尝试"},interval:{label:"常规扫描间隔",description:"当 host overview 已存在且非空时,按这个间隔检查并刷新概览"},intervals:{daily:"每天",every3Days:"每 3 天",weekly:"每 7 天",every2Weeks:"每 14 天",monthly:"每 30 天"},messages:{loadFailed:"加载主机扫描设置失败",saveFailed:"保存主机扫描设置失败",enabledUpdated:"主机扫描开关已更新",intervalUpdated:"主机扫描间隔已更新"}},y9={loadFailed:"加载配置失败",saveSuccess:"设置已保存",saveFailed:"保存失败",disableAllSuccess:"已禁用自动记忆和主机扫描",disableAllFailed:"禁用失败",enableAllSuccess:"已启用自动记忆和主机扫描",enableAllFailed:"启用失败",resetAllSuccess:"已恢复记忆页默认设置",resetAllFailed:"重置失败"},w9={title:d9,subtitle:u9,autoMemory:p9,loading:m9,actions:g9,resetDialog:h9,hostScan:f9,messages:y9},v9="权限",b9="控制工具确认、执行限制和桌面自动化访问权限。",k9={sectionTitle:"工具执行行为"},S9={maxContinuationTurns:"Goal 自动推进预算",maxContinuationTurnsDesc:"每个新目标最多可由 Goal 模式自动排队推进的轮数。",turns:"轮"},x9={sectionTitle:"Computer use(桌面自动化)",enable:"启用 Computer use",enableDesc:"关闭时,任何会话模式都不会启用 ComputerUse 工具。",accessibility:"辅助功能",accessibilityDesc:"",screenCapture:"屏幕录制",screenCaptureDesc:"",granted:"已授权",notGranted:"未授权",openSettings:"系统设置",platformNote:"说明"},C9={sectionTitle:"浏览器控制(CDP)",status:"浏览器状态",statusDesc:"Sparo OS 使用 9222 端口通过 CDP 直接控制浏览器标签页。",connected:"已连接",notConnected:"未连接",tabs:"个标签页",connect:"连接",connectSuccess:"已连接 {{browser}}",connectFailed:"连接浏览器失败",restartSuccess:"已重启 {{browser}} 并启用调试",restartFailed:"重启浏览器并启用调试失败",createLauncher:"创建启动器",createLauncherDesc:"创建一个 macOS 启动器,用于以 CDP 调试端口启动浏览器。",createLauncherSuccess:"启动器已创建:{{path}}",createLauncherFailed:"创建启动器失败",restartModal:{title:"重启浏览器?",description:"检测到 {{browser}} 已在运行,但未启用调试端口。Sparo OS 需要先以调试模式重启浏览器,才能控制标签页。",warning:"这会关闭当前浏览器窗口,并重新打开浏览器。",cancel:"取消",confirm:"重启并启用调试",restarting:"正在重启..."}},A9={text:"加载配置中..."},_9={saveSuccess:"设置已保存",saveFailed:"保存失败"},T9={title:v9,subtitle:b9,toolExecution:k9,goalMode:S9,computerUse:x9,browserControl:C9,loading:A9,messages:_9},P9="个性化",F9="调整助手呈现、伙伴外观和会话中的显示行为。",R9={sessionTitle:{title:"自动会话标题",warning:"会话标题将使用用户消息的前 20 个字符"},dailyLetter:{title:"每日来信",enable:"开启每日来信",subtitle:"选择写每日来信的模型。未单独指定时使用主模型。"},agentCompanion:{title:"智能体伙伴",enable:"显示智能体伙伴",petLabel:"外观",petDescription:"选择内置外观,或导入 Petdex zip 包。",petPlaceholder:"选择外观",defaultPet:"默认 Sparky",defaultPetDescription:"使用内置 Sparky 伙伴。",groups:{presets:"内置",imported:"已导入"},import:"导入",importing:"导入中...",delete:"删除",deleteDialog:{title:"删除导入的外观?",message:"“{{name}}”会从此设备移除,并自动切回默认伙伴。",confirm:"删除外观",cancel:"取消"}},thinkingProcess:{title:"思考过程",showProcess:"显示思考过程",showProcessDescription:"关闭后,FlowChat 不再显示模型思考输出。",keepCompletedItem:"完成后保留可展开项",keepCompletedItemDescription:"思考输出结束并自动折叠后,在 FlowChat 中保留一个可展开的思考项。"}},N9={label:"模型",primary:"主模型",fast:"快速模型",notConfigured:"未配置",fastUsesPrimary:"使用旗舰"},D9={enable:"启用"},I9={empty:"没有可用模型。请先在“模型”中添加模型。",updateSuccess:"{{agentName}} 将使用 {{modelName}}"},M9={text:"正在加载配置..."},j9={saveSuccess:"设置已保存",saveFailed:"保存失败",updateFailed:"更新失败"},E9={title:P9,subtitle:F9,features:R9,model:N9,common:D9,models:I9,loading:M9,messages:j9},L9="语音输入",$9="管理本地语音输入与 SenseVoice Small INT8 模型。",O9="正在加载语音输入设置...",B9={composer:"消息输入",model:"本地模型"},W9={auto:"自动检测",zh:"普通话",yue:"粤语",en:"英语",ja:"日语",ko:"韩语"},z9={enabled:{label:"显示语音输入",description:"在消息输入框中显示麦克风操作。"},language:{label:"识别语言",description:"本地转写默认使用的语言。"},maxRecording:{label:"录音上限",description:"单次语音输入允许的最长秒数。"}},U9={not_installed:"未安装",downloading:"下载中",installed:"已安装",verifying:"校验中",corrupt:"需要修复",deleting:"删除中",error:"错误"},H9={refresh:"刷新",version:"版本 {{version}}",size:"{{size}}",progress:"{{percent}}% · {{downloaded}} / {{total}}",download:"下载",downloading:"下载中",downloaded:"已下载",cancel:"取消",cancelling:"取消中",openFolder:"打开位置",verify:"校验",verifying:"校验中",delete:"删除",deleting:"删除中",keep:"保留",deleteConfirmTitle:"删除本地语音模型?",deleteConfirmMessage:"{{name}} 将从本地存储中移除。",empty:"没有可用的语音模型。"},q9={loadFailed:"加载语音输入设置失败",saveSuccess:"语音输入设置已保存",saveFailed:"保存语音输入设置失败",downloadSuccess:"语音模型已下载",downloadFailed:"下载语音模型失败",downloadCancelled:"语音模型下载已取消",cancelFailed:"取消下载失败",openFolderFailed:"打开语音模型位置失败",verifySuccess:"语音模型校验通过",verifyFailed:"校验语音模型失败",deleteSuccess:"语音模型已删除",deleteFailed:"删除语音模型失败"},V9={title:L9,subtitle:$9,loading:O9,sections:B9,languages:W9,composer:z9,states:U9,model:H9,messages:q9},G9="打开工作区",K9="新建工作区",Q9="返回首页",J9="返回主桌面",Y9="返回上一场景",Z9="最近场景",X9="场景导航",eq="全局",tq="关于",nq="打开菜单",oq="打开任务列表",sq="任务管理",iq="关闭菜单",aq="选择要打开的工作区目录",rq="配置中心",lq="展开左侧面板",cq="收起左侧面板",dq="展开右侧面板",uq="收起右侧面板",pq="聊天",mq="显示聊天面板",gq="隐藏聊天面板",hq="外观",fq="语言",yq="语言",wq="主题",vq="跟随系统",bq="多端协同",kq="请先打开一个工作区,再使用设备网络。",Sq="多端协同 · 已连接",xq="多端协同 · 等待连接",Cq="设置连接",Aq="查看详情",_q="断开 Bot",Tq="断开中...",Pq="通过",Fq="视图模式切换",Rq="办公助理",Nq="BitFun Coder",Dq="切换到办公助理",Iq="切换到 Coder 模式",Mq="隐藏 Agentic",jq="激活 Agentic",Eq="切换工作区",Lq="最近工作区",$q="暂无最近工作区",Oq="选择工作区",Bq={openProject:G9,newProject:K9,goHome:Q9,returnToMainDesktop:J9,backToPreviousScene:Y9,recentScenes:Z9,sceneNavigation:X9,globalScope:eq,about:tq,openMenu:nq,openSessionsList:oq,openTaskManagement:sq,closeMenu:iq,selectProjectDirectory:aq,configCenter:rq,expandLeftPanel:lq,collapseLeftPanel:cq,expandRightPanel:dq,collapseRightPanel:uq,chatPanel:pq,showChatPanel:mq,hideChatPanel:gq,appearance:hq,language:fq,languageList:yq,appearanceThemeList:wq,followSystemTheme:vq,remoteConnect:bq,remoteConnectRequiresWorkspace:kq,remoteControlConnected:Sq,remoteControlWaiting:xq,remoteControlSetup:Cq,remoteControlViewDetails:Aq,remoteControlDisconnectBot:_q,remoteControlDisconnecting:Tq,remoteControlVia:Pq,modeSwitchAriaLabel:Fq,modeCowork:Rq,modeCoder:Nq,switchToCowork:Dq,switchToCoder:Iq,hideAgentic:Mq,activateAgentic:jq,switchWorkspace:Eq,recentWorkspaces:Lq,noRecentWorkspaces:$q,noWorkspaceOpen:Oq},Wq={navControl:"导航控制",mainNav:"主导航",sceneHeader:"场景标题栏"},zq="后退",Uq="前进",Hq="后退 (Alt+←)",qq="前进 (Alt+→)",Vq={sessions:"任务",project:"目录",memory:"记忆",agents:"AI 应用",skills:"技能",tools:"工具",capabilities:"能力",terminal:"Shell",git:"Git",subAgent:"子代理"},Gq={agents:"它能调用哪些 Agent",skills:"它懂什么专项知识 — 技能知识文件",tools:"它能用什么工具 — 内置工具与 MCP 服务",addWorkspace:"添加工作区",newAgenticOsSession:"重启 Agentic OS"},Kq={workspace:"工作区",sessions:"任务",apps:"应用中心",devKit:"开发套件",shell:"Shell"},Qq="收起任务列表",Jq={entry:{title:"应用构建器",description:"创建带有明确目标、工作对象、主界面和组件图的 Product App。"},panel:{title:"应用构建器",reload:"刷新预览",openInApps:"打开 Product App",emptyTitle:"Builder 正在为你打草稿",emptyDescription:"生成第一个可运行版本后,预览会自动出现在这里。",loading:"正在加载预览",loadFailed:"加载预览失败",retry:"重试"},diagnostics:{title:"Diagnostics",ok:"运行正常",empty:"暂无运行时错误",fatalCount:"{{count}} 个错误",warningCount:"{{count}} 个警告"}},Yq={comingSoon:"即将上线"},Zq={triggerPlaceholder:"搜索",headerSearchHint:"Alt + F 搜索",headerShortcut:"Alt F",triggerTooltip:"搜索 (Alt+F)",inputPlaceholder:"搜索工作、工作区、产品应用和组件...",groupWorks:"工作",groupRecentWork:"最近工作",groupWorkspaces:"已打开工作区",groupApps:"产品应用",groupWorkObjects:"工作对象",groupComponents:"组件",groupArtifacts:"产物",groupSessions:"任务会话",groupRecentTasks:"最近会话",empty:"未找到相关结果",noRecentTasks:"暂无最近工作,输入关键词可搜索工作区、产品应用、组件等",workHint:"{{status}}",workWorkspaceHint:"{{workspace}} / {{status}}",workObjectHint:"{{app}} / {{scope}}",artifactHint:"来自 {{work}}",sessionWorkspaceHint:"会话位于 {{workspace}}"},Xq={title:"扩展",categories:{agents:"智能体",extensions:"扩展",analytics:"分析"}},eV={title:"Shell",filters:{label:"显示"},views:{all:"全部",manual:"我的",agent:"Agent"},actions:{newTerminal:"新建终端",refresh:"刷新"},context:{start:"启动",stop:"停止",editConfig:"编辑配置",saveConfig:"保存配置",deleteSavedTerminal:"删除已保存终端",delete:"删除",close:"关闭"},badges:{startupCommand:"cmd",saved:"已保存",default:"默认"},empty:{all:"还没有终端",manual:"还没有用户终端",agent:"还没有 Agent 终端",quickNew:"快速新建"}},tV={newSession:"新建任务",newBitfunCoderSession:"BitFun Coder",newCoworkSession:"写文档、整理事项",newDesignSession:"做设计、出原型",newBitfunCoderSessionShort:"BitFun Coder",newBitfunCoderSessionDomain:"编码 Product App",newCoworkSessionShort:"办公助理",newCoworkSessionDomain:"写作、整理与规划",newDesignSessionShort:"设计师",newDesignSessionDomain:"设计与原型",newDeepResearchSession:"查资料、做研究",newDeepResearchSessionShort:"深度研究",newDeepResearchSessionDomain:"资料研究与综合",newAppBuilderSession:"创建 Product App",newAppBuilderSessionShort:"应用构建器",newAppBuilderSessionDomain:"产品应用设计",systemBadge:"系统",systemGroup:"系统",extensionGroup:"扩展",modeAppBuilder:"应用构建器",agenticOs:"打开 Agentic OS",agenticOsShort:"Agentic OS",modeBitfunCoder:"BitFun Coder",modeCowork:"办公助理",modeDesign:"设计师",bitfunCoderSessionMode:"BitFun Coder 任务",coworkSessionMode:"办公助理任务",designSessionMode:"设计师任务",noSessions:"暂无任务",rename:"重命名",delete:"删除",confirmEdit:"确认",cancelEdit:"取消",showMore:"还有 {{count}} 个任务",showAll:"还有 {{count}} 个(展开全部)",showLess:"收起",workspaceOwner:"所属工作区:{{name}}",sessionContext:"所属:{{name}}"},nV={title:"定时任务",open:"打开定时任务",shortLabel:"定时任务",listTitle:"任务列表",loading:"正在加载定时任务...",never:"未安排",nextRunLabel:"下次执行",fields:{workspacePath:"工作区路径",session:"会话",name:"任务名称",enabled:"启用状态",enabledHint:"启用该任务",scheduleKind:"调度方式",at:"执行时间",everyMs:"间隔(分钟)",anchorMs:"锚点时间(可选)",cronExpr:"Cron 表达式",timezone:"时区(可选)",prompt:"任务内容"},placeholders:{workspacePath:"请输入工作区路径",session:"请选择或输入会话 ID",name:"例如:每日全球新闻简报",anchorMs:"留空则使用创建时刻",timezone:"例如:Asia/Shanghai",prompt:"请输入定时触发时发送的内容"},scheduleKinds:{at:"单次执行",every:"固定间隔",cron:"Cron"},scheduleSummary:{every:"每 {{everyMinutes}} 分钟",cron:"Cron: {{expr}}",cronWithTz:"Cron: {{expr}} · {{tz}}"},status:{idle:"待命",disabled:"已停用",queued:"已入队",running:"执行中",ok:"成功",error:"失败",cancelled:"已取消"},actions:{refresh:"刷新任务列表",newJob:"新增任务",toggleEnabled:"切换启用状态",edit:"编辑任务",delete:"删除任务",save:"保存修改",create:"创建任务",cancel:"取消"},editor:{editTitle:"编辑任务",createTitle:"新建任务"},empty:{title:"还没有定时任务",description:"点击右上角的加号创建第一条定时任务。"},deleteDialog:{title:"删除任务“{{name}}”?"},messages:{loadFailed:"加载定时任务失败:{{error}}",saveFailed:"保存定时任务失败:{{error}}",updateFailed:"更新定时任务失败:{{error}}",deleteFailed:"删除定时任务失败:{{error}}",deleteSuccess:"定时任务已删除",createSuccess:"定时任务已创建",updateSuccess:"定时任务已更新"},validation:{nameRequired:"请输入任务名称",promptRequired:"请输入任务内容",workspaceRequired:"请输入工作区路径",sessionRequired:"请选择会话"}},oV={empty:"暂无已打开工作区",emptyProjects:"暂无普通工作区",closeFailed:"关闭工作区失败",resetWorkspaceFailed:"重置工作区失败",workspaceReset:"已重置工作区",reorderFailed:"调整工作区顺序失败",dropBefore:"松开后插入到此项前",dropAfter:"松开后插入到此项后",revealFailed:"打开工作区目录失败",copyPathFailed:"复制路径失败",createSessionFailed:"新建任务失败",initSessionFailed:"初始化 AGENTS.md 任务失败",worktreeCreated:"已创建 worktree",worktreeCreatedAndOpened:"已创建并打开 worktree",worktreeCreateFailed:"创建 worktree 失败:{{error}}",worktreeCreateOrOpenFailed:"worktree 已创建,但作为工作区打开失败:{{error}}",worktreeDeleted:"已删除 worktree",deleteWorktreeFailed:"删除 worktree 失败",expandSessions:"展开任务列表",collapseSessions:"收起任务列表",groups:{projects:"普通工作区"},actions:{more:"更多操作",newSession:"新建任务",resetWorkspace:"重置工作区",initAgents:"初始化 AGENTS.md",newWorktree:"新建 worktree",deleteWorktree:"删除 worktree",copyPath:"复制路径",reveal:"在资源管理器中打开",close:"关闭工作区"},resetWorkspaceDialog:{title:"重置 {{name}}?",message:"此操作会清空该工作区目录下的所有内容,但不会删除工作区目录本身。",pathLabel:"工作区路径"},deleteWorktreeDialog:{title:"删除 {{name}}?",message:"此操作会关闭该工作区,并删除对应的 worktree 目录。",pathLabel:"Worktree 路径"}},sV={allAgents:"全部子智能体",newAgent:"新建子智能体",agentsOverview:"Agent 总览"},iV={allSkills:"全部技能",addSkill:"添加技能"},aV={builtinTools:"内置工具",mcpServices:"MCP 服务"},rV={openMyAgent:"我的智能体",customize:"自定义"},lV="更多选项",cV="多模态工具",dV="通知",uV=JSON.parse('{"subtitle":"今天想做些什么?","agenticOSDesc":"统筹并推进 AI 工作","sectionExtensions":"扩展","sectionSystem":"系统","welcomeHint":"从左侧进入 Agentic OS,或浏览扩展与系统工具","hub":{"ariaLabel":"Sparo Hub","sections":{"frequent":"常用","more":"更多","preview":"浏览预览","direct":"直接前往"},"aria":{"frequent":"常用入口","more":"更多入口","preview":"可切换预览的入口","direct":"直接打开场景的入口"},"controls":{"group":"环境与偏好","settings":"打开设置","about":"关于","settingsShort":"设置","theme":"主题","language":"语言","systemTheme":"跟随系统","systemThemeShort":"系统","lightTheme":"亮色","darkTheme":"暗色","currentTheme":"主题:{{value}}","currentLanguage":"语言:{{value}}","exitTheme":"退出主题选择","exitLanguage":"退出语言选择"},"trigger":{"open":"打开 Sparo Hub","close":"关闭 Sparo Hub"},"capsule":{"default":"Sparo Hub","running":"工作 · {{count}} 运行中","attention":"工作 · {{count}} 待处理","dailyLetter":"今日来信 · 未读"},"states":{"current":"当前","ready":"可打开","unread":"未读","running":"{{count}} 运行中"},"actions":{"openItem":"打开{{item}}","newAgenticOsSession":"新建会话"},"work":{"summary":"{{running}} 运行中 · {{attention}} 待处理","empty":"目前没有需要关注的工作","open":"打开工作中心","new":"新建工作"},"stage":{"agentic-os":{"status":"随时可用","lede":"从一个目标开始,Sparo 会连接合适的能力并保持工作连续。","points":{"first":{"title":"开始对话","meta":"说出下一件事"},"second":{"title":"继续协作","meta":"回到最近上下文"},"third":{"title":"运行轨迹","meta":"查看执行脉络"}}},"apps":{"status":"操作入口","lede":"应用既能独立使用,也能成为一项工作的专属执行界面。","points":{"first":{"title":"发现","meta":"找到合适能力"},"second":{"title":"打开","meta":"进入应用空间"},"third":{"title":"承接工作","meta":"连接当前任务"}}},"files":{"status":"全局范围","lede":"从本机文件系统出发,在全局位置与项目工作区之间自然切换。","points":{"first":{"title":"本机","meta":"磁盘与固定目录"},"second":{"title":"工作区","meta":"项目范围浏览"},"third":{"title":"打开位置","meta":"继续处理文件"}}},"shell":{"status":"环境就绪","lede":"在系统与项目范围间选择正确的执行环境,同时保留上下文。","points":{"first":{"title":"系统范围","meta":"全局命令环境"},"second":{"title":"项目范围","meta":"跟随工作区"},"third":{"title":"权限边界","meta":"明确执行范围"}}},"daily-letter":{"status":"后台整理中","lede":"系统在后台收集进展、提炼重点,并在合适的时机交付给你。","points":{"first":{"title":"收集","meta":"汇总今日轨迹"},"second":{"title":"整理","meta":"提炼重点与待办"},"third":{"title":"交付","meta":"形成今日来信"}}},"memory":{"status":"仅你可见","lede":"记忆不是档案柜,而是一条由长期协作逐渐形成的个人轨迹。","points":{"first":{"title":"偏好","meta":"理解你的选择"},"second":{"title":"协作反馈","meta":"调整配合方式"},"third":{"title":"项目背景","meta":"延续工作上下文"}}},"skills":{"status":"自动匹配","lede":"把专项知识与工作方法连接起来,在合适的任务里自动生效。","points":{"first":{"title":"知识","meta":"沉淀专业经验"},"second":{"title":"方法","meta":"组织可靠流程"},"third":{"title":"调用","meta":"任务中自动匹配"}}},"tools":{"status":"按需调用","lede":"内置工具和连接服务共同扩展 Agent 能够安全执行的边界。","points":{"first":{"title":"内置工具","meta":"系统执行能力"},"second":{"title":"MCP 服务","meta":"连接外部系统"},"third":{"title":"权限边界","meta":"保持调用可控"}}},"subagents":{"status":"协同待命","lede":"主 Agent 负责方向,专门协作者并行承接边界清晰的任务。","points":{"first":{"title":"主 Agent","meta":"保持整体方向"},"second":{"title":"专门协作者","meta":"匹配具体能力"},"third":{"title":"并行执行","meta":"汇回统一结果"}}},"settings":{"status":"全局生效","lede":"用少量关键设置,控制 Sparo OS 的能力、边界与表达方式。","points":{"first":{"title":"模型","meta":"默认智能能力"},"second":{"title":"权限","meta":"系统执行边界"},"third":{"title":"外观与行为","meta":"个性化使用体验"}}}},"preview":{"common":{"loading":"正在加载","statusUnavailable":"状态暂不可用","partialData":"部分数据","enabled":"已开启","disabled":"已关闭","count":"{{count}} 项","retry":"重试"},"agenticOs":{"category":"协作中枢","status":{"processing":"正在处理","current":"当前会话","available":"随时可用"},"summary":"{{sessions}} 个会话 · {{turns}} 轮协作","sections":{"continue":"继续协作","recent":"最近会话","sessionCount":"显示 {{count}} 个"},"session":{"turns":"{{count}} 轮","loading":"加载中…"},"empty":{"title":"开始一次新协作","description":"说出你想让什么发生。","noRecent":"暂无其他最近会话"},"actions":{"newSession":"新建会话","openTimeline":"查看全部轨迹"},"aria":{"openSession":"打开会话:{{title}}"}},"workCenter":{"category":"工作操作面","status":{"loading":"加载中","unavailable":"暂不可用","attention":"{{count}} 个等待你","running":"{{count}} 个运行中","idle":"当前已就绪"},"metrics":{"running":"运行中","attention":"等待你","recent":"最近"},"sections":{"running":"正在工作","recent":"最近工作","workCount":"共 {{count}} 个"},"empty":{"noWork":"暂无工作","noRunning":"当前没有正在执行的工作","noRecent":"暂无最近工作"},"error":{"loadFailed":"加载工作失败"},"actions":{"newWork":"新建工作","openAll":"全部工作","retry":"重试","handle":"处理","viewProgress":"查看进度","resume":"恢复","continue":"继续","viewResult":"查看结果","open":"打开"},"aria":{"openWork":"打开工作:{{title}}"},"workStatus":{"draft":"草稿","active":"可开始","running":"运行中","waiting_user":"等待你","blocked":"已阻塞","paused":"已暂停","completed":"已完成","failed":"失败","cancelled":"已取消","interrupted":"已中断","archived":"已归档"}},"apps":{"category":"智能应用","status":"{{count}} 项可继续","metrics":{"active":"继续使用","installed":"已安装","discover":"可发现"},"sections":{"apps":"应用","continue":"继续运行","running":"运行中","pinned":"固定","recommended":"推荐应用","recent":"最近打开","installed":"我的应用","discover":"发现应用"},"workStatus":{"running":"运行中","attention":"等待处理","active":"可继续"},"appState":{"running":"正在运行","installed":"已安装","discover":"查看"},"actions":{"open":"打开应用中心","create":"创建应用","manage":"管理"},"empty":{"appsTitle":"暂无应用","continueTitle":"暂无可继续应用","runningTitle":"暂无运行应用","catalogTitle":"暂无推荐应用"},"aria":{"apps":"应用","runningApps":"运行中的应用","recommendedApps":"推荐应用","continueApp":"继续 {{name}}","openRunningApp":"打开运行中的应用 {{name}}","openApp":"打开应用 {{name}}"},"errors":{"works":"暂时无法读取应用工作","catalog":"暂时无法读取应用目录"}},"files":{"category":"全局文件系统","search":{"placeholder":"搜索位置或输入路径","ariaLabel":"搜索已知位置或输入完整路径","clear":"清除位置搜索"},"sections":{"continue":"继续浏览","common":"常用位置","results":"位置结果"},"actions":{"open":"打开文件管理器","search":"搜索位置"},"types":{"folder":"文件夹","file":"文件"},"empty":{"continueTitle":"暂无可继续位置","commonTitle":"暂无常用位置","searchTitle":"无匹配位置","contentsTitle":"此位置暂无内容"},"aria":{"openLocation":"打开位置 {{name}}","openEntry":"打开 {{name}}"},"errors":{"contents":"暂时无法读取此位置"}},"shell":{"category":"执行环境","status":"{{count}} 个运行中","metrics":{"running":"运行中","manual":"手动终端","agent":"Agent 终端"},"sections":{"running":"运行中","saved":"保存的终端"},"actions":{"open":"打开 Shell","new":"新建终端"},"newSessionName":"终端 {{count}}","empty":{"runningTitle":"暂无终端","savedTitle":"还没有保存的终端","savedDescription":"可在 Shell 中保存名称、目录和启动命令。","workspaceDescription":"打开一个工作区后即可使用保存的终端。"},"errors":{"sessions":"暂时无法读取终端状态"}},"dailyLetter":{"category":"系统简报","status":{"notGenerated":"今日尚未生成","writing":"正在书写今日来信","unread":"未读","ready":"已读"},"actions":{"generate":"生成今日来信","generating":"生成中…","open":"打开今日来信","openUnread":"拆开来信","continue":"继续阅读","expandReading":"展开阅读","reviewReceipts":"处理 {{count}} 条回执"},"receiptPrompt":"{{count}} 条想请你确认","metrics":{"pendingReceipts":"待处理回执","appIdeas":"应用灵感","history":"历史来信"},"sections":{"today":"今天","recent":"最近来信"},"scope":{"agentic_os":"全局","workspace":"工作区"},"empty":{"todayTitle":"今日暂无来信","writingTitle":"正在生成来信","history":"暂无历史来信"},"errors":{"load":"今日来信暂不可用","history":"暂时无法读取最近来信","generate":"暂时无法生成来信"}},"memory":{"category":"用户轨迹","status":{"ready":"自动记忆开启","partial":"部分范围已开启","paused":"自动记忆已暂停"},"actions":{"open":"打开记忆"},"growth":{"title":"今天的成长","unit":"点","caption":"今天留下的记忆","recent":"最近记录","empty":"今天还没有留下新记忆","persistence":"已沉淀 {{count}} 个来源","persistencePending":"等待首次沉淀"},"sections":{"current":"当前记忆"},"items":{"user":{"title":"关于你","meta":"偏好与协作方式"},"longTerm":{"title":"长期记忆","meta":"持续协作中形成"},"workspace":{"title":"当前工作区","meta":"项目上下文"}},"updated":{"today":"今天","hoursAgo":"{{count}} 小时前","unavailable":"尚未形成","noWorkspace":"未打开"},"consolidation":{"ariaLabel":"记忆整理状态","state":{"ready":"已整理","running":"正在整理","failed":"需要处理","disabled":"暂不可用","notRun":"尚未整理"},"summary":"{{count}} 个来源 · {{time}}","lastRun":"上次整理 {{time}}","runningMeta":"正在沉淀最近的记忆记录","notRunMeta":"形成记录后即可整理","statusUnavailable":"状态暂不可用","actions":{"run":"立即整理","running":"整理中"},"messages":{"started":"已开始整理记忆","notNeeded":"当前记忆已是最新状态","failed":"记忆整理失败"}},"errors":{"load":"记忆暂不可用","records":"暂时无法读取记忆记录"}},"skills":{"category":"能力扩展","status":{"available":"能力可用","empty":"尚未安装技能"},"metrics":{"installed":"已安装","project":"项目技能","suites":"技能套件"},"sections":{"available":"当前可用","popular":"热门发现"},"scope":{"builtin":"内置","user":"用户","project":"项目"},"meta":{"installed":"已安装 {{count}} 个","installs":"{{count}} 次安装"},"actions":{"open":"打开技能"},"empty":{"installedTitle":"暂无已安装技能","marketTitle":"暂无新技能"},"errors":{"load":"技能暂不可用","installed":"暂时无法读取已安装技能","market":"暂时无法读取可发现技能"}},"capabilities":{"category":"执行与协作","status":{"ready":"能力可用","attention":"连接需要处理","partial":"部分状态不可用","idle":"等待调用"},"metrics":{"builtin":"内置","connected":"连接","specialists":"专家"},"sections":{"execution":"执行能力","specialists":"协作专家"},"meta":{"servers":"{{count}} 个服务","specialists":"{{count}} 个可调用","connectedOf":"{{connected}} / {{count}} 已连接","tools":"{{count}} 个工具"},"execution":{"builtin":"内置工具","builtinDescription":"文件、Shell、Web 与工作流能力","mcpServices":"MCP 服务","mcpServicesDescription":"连接外部系统与数据源","mcpTools":"MCP 工具","mcpToolsDescription":"由已连接服务提供的扩展工具"},"actions":{"tools":"打开工具中心","subagents":"管理子代理"},"empty":{"noneTitle":"还没有子代理","noneDescription":"可创建一位专家承接明确的委派工作。","noneEnabledTitle":"没有已启用的专家","noneEnabledDescription":"前往子代理场景选择可调用的专家。"},"errors":{"execution":"执行能力状态暂不可用","servers":"MCP 状态暂不可用","tools":"工具目录暂不可用","subagents":"子代理暂不可用"}},"tools":{"category":"连接能力","status":{"ready":"连接状态良好","attention":"需要处理","noServers":"尚未配置 MCP","idle":"服务当前空闲"},"metrics":{"builtin":"内置工具","mcpTools":"MCP 工具","connected":"已连接"},"sections":{"servers":"MCP 连接","capabilities":"能力分布"},"meta":{"servers":"{{count}} 个服务"},"serverStatus":{"connected":"已连接","needsAuth":"需要授权","failed":"连接失败","starting":"启动中","reconnecting":"重连中","stopping":"停止中","stopped":"已停止","idle":"空闲"},"capabilities":{"files":"文件与导航","filesDescription":"读取、编辑、搜索并定位文件","workflow":"规划与会话","workflowDescription":"规划工作、交互并管理会话","extensions":"扩展能力","extensionsDescription":"委派能力与 MCP 扩展"},"actions":{"open":"打开工具"},"empty":{"serversTitle":"还没有 MCP 服务","serversDescription":"前往工具中心添加连接能力。"},"errors":{"load":"工具暂不可用","servers":"暂时无法读取 MCP 状态"}},"subagents":{"category":"协作专家","status":{"ready":"可随时调用","empty":"尚无子代理","noneEnabled":"没有已启用的子代理"},"metrics":{"ready":"可调用","all":"全部","project":"项目级"},"sections":{"ready":"已就绪专家","sources":"来源分布"},"meta":{"ready":"{{count}} 个可调用","tools":"{{count}} 个工具"},"sources":{"project":"项目","projectDescription":"当前工作区可用","user":"用户","userDescription":"跨工作区可用","builtin":"内置","builtinDescription":"由 Sparo 提供"},"actions":{"open":"打开子代理"},"empty":{"noneTitle":"还没有子代理","noneDescription":"可创建一位专家处理专门的委派工作。","noneEnabledTitle":"没有已启用的专家","noneEnabledDescription":"前往子代理场景选择可调用的专家。"},"errors":{"load":"子代理暂不可用"}}},"items":{"agentic-os":{"category":"协作中枢","description":"统筹任务、调用能力,并推进跨应用与跨项目的工作。","hint":"从这里继续全局协作,或新建一个独立会话。"},"workCenter":{"category":"用户操作面","description":"查看正在运行、等待处理和已经安排的工作。","hint":"工作状态会直接反馈到左下角入口。"},"apps":{"category":"用户操作面","description":"打开智能应用,或为当前工作选择合适的应用。","hint":"应用既可以独立打开,也可以成为某项工作的执行界面。"},"files":{"category":"全局环境","description":"浏览本机文件、磁盘和固定目录,也可将目录作为工作区打开。","hint":"这是全局文件系统入口,不局限于当前项目。"},"shell":{"category":"全局环境","description":"在系统或项目范围内打开 Shell。","hint":"进入后可在系统会话与项目会话之间切换。"},"daily-letter":{"category":"系统后台","description":"查看系统在后台整理的今日进展与待确认事项。","hint":"新的来信会同步显示在图标与左下角入口。"},"memory":{"category":"用户轨迹","description":"查看 Agentic OS 记住的偏好、协作反馈和项目背景。","hint":"记忆反映长期协作轨迹,而不是一次性的操作入口。"},"skills":{"category":"扩展能力","description":"管理可复用的专项知识和工作方法。","hint":"技能会在合适的任务中被 Agent 自动调用。"},"capabilities":{"category":"执行与协作","description":"统一查看可执行工具、连接服务与可委派专家。","hint":"工具负责执行,子代理负责并行承接明确任务。"},"tools":{"category":"扩展能力","description":"查看内置工具与已经连接的 MCP 服务。","hint":"工具扩展执行边界,通常不需要频繁进入管理。"},"subagents":{"category":"扩展能力","description":"管理可由主 Agent 调用的专门协作者。","hint":"子代理会在复杂工作中并行承接明确的子任务。"},"settings":{"category":"系统设置","description":"管理模型、权限、外观与系统行为。","hint":"这里的变化会影响 Sparo OS 的全局运行方式。"}}}}'),pV={label:"工作栏",title:"工作",subtitle:"{{count}} 个焦点",searchPlaceholder:"搜索工作...",filterNoMatch:"没有匹配的工作",empty:"暂无工作",loadFailed:"加载工作失败",retry:"重试",pinKeepOpen:"保持展开",unpinKeepOpen:"取消保持",openWorkList:"打开工作快览",openWorkCenter:"打开工作中心",openWorkCenterShort:"中心",openWork:"打开工作",openWorkDetails:"工作详情",rowActions:"工作操作",workShort:"工作",activeWorksGroupLabel:"焦点工作",runningWorksGroupLabel:"焦点工作",recentWorksGroupLabel:"最近",newWorkButton:"启动新工作",createTitle:"创建 Work",modeAriaLabel:"Work 启动方式",modeManual:"我来指定",modeAgenticOs:"交给 OS",sentencePrefix:"让",sentenceInfix:"在",sentenceSuffix:"工作。",delegatePrefix:"让 Sparo",delegateSuffix:"。",objectivePlaceholder:"处理什么",objectiveRequired:"先写要处理的事情",agentSearchPlaceholder:"搜索产品应用",workspacePlaceholder:"选择这个工作属于哪里",globalScopeLabel:"全局工作",globalScopeDescription:"不绑定到项目文件夹",workspaceRequired:"请先选择项目目录",workspaceRequiredHint:"这个产品应用需要项目目录才能启动。",noOpenWorkspace:"没有匹配的文件夹",browseWorkspace:"选择文件夹",confirmCreate:"开始",confirmDispatch:"交给 OS",createFailed:"创建工作失败",dispatchFailed:"发送给 Agentic OS 失败",browseWorkspaceFailed:"选择文件夹失败",workspaceMissing:"请先选择工作区",openFailed:"打开工作失败",cancelFailed:"取消运行失败",cancelRunningWork:"取消运行",removeFailed:"移除工作失败",removeWork:"归档工作",resultCount:"{{count}} 个结果",executor:{systemGroup:"内置执行者",intelligentAppGroup:"智能应用",releaseUnavailable:"此应用在所选范围内没有已激活且兼容的 Release。",systemBadge:"内置",bitfunCoder:"BitFun Coder",bitfunCoderDescription:"编码、调试、验证与交付",cowork:"办公助理",coworkDescription:"写作、整理与规划",design:"设计师",designDescription:"设计与原型",research:"深度研究",researchDescription:"资料研究与综合"},group:{all:"全部",running:"焦点",active:"可继续",done:"已完成"},status:{draft:"草稿",active:"可继续",running:"运行中",waiting_user:"等待你",blocked:"受阻",paused:"已暂停",completed:"已完成",failed:"失败",archived:"已归档"},kind:{"one-shot":"一次性","multi-step":"多步骤","long-running-session":"长期运行",recurring:"周期性",tracking:"追踪",topic:"主题","app-workflow":"应用流程","delegated-work":"委派工作"}},mV={aria:Wq,back:zq,forward:Uq,backShortcut:Hq,forwardShortcut:qq,items:Vq,tooltips:Gq,sections:Kq,collapseSessions:Qq,appBuilder:Jq,badges:Yq,search:Zq,myAgent:Xq,shell:eV,sessions:tV,scheduledJobs:nV,workspaces:oV,agents:sV,skills:iV,tools:aV,actions:rV,moreOptions:lV,multimodalTools:cV,notifications:dV,menuPanel:uV,workDock:pV},gV="远程控制",hV="设备网络",fV="连接设置",yV="连接设置",wV="返回设备网络",vV="控制端",bV="移动端",kV="桌面端",SV="电脑控制",xV="手机控制",CV="IM 控制",AV="这台电脑",_V="当前设备",TV="我的手机",PV="可查看 · 可控制",FV="在线 · 可控制",RV="等待手机连接",NV="辅助交互",DV="由手机连接",IV="手表",MV="耳机",jV="眼镜",EV="微信、飞书等 IM 是消息与指令入口",LV="安全连接",$V="端到端加密",OV="连接承载",BV="选择连接基础设施,建立安全通道",WV="让手机与这台电脑处于同一局域网,然后扫描二维码连接。",zV="使用已授权的 ngrok 隧道连接这台设备。",UV="通过 Sparo 中继建立端到端加密连接。",HV="连接到你自行部署和维护的中继服务。",qV="通过 Telegram Bot 接收消息和指令。",VV="通过飞书机器人接收消息和指令。",GV="通过微信扫码登录并连接消息入口。",KV="执行节点",QV="数据中心",JV="执行节点",YV="同一设备可兼任控制",ZV="本机在线 · 数据与执行已启用",XV="添加 Windows 节点",eG="添加 Linux 节点",tG="Windows 节点",nG="Linux 节点",oG="可添加",sG="添加",iG="多个 Windows、macOS、Linux 节点可同时执行任务",aG="1 个主节点在线 · 端到端加密",rG="2 个主节点在线 · 端到端加密",lG="扫描二维码",cG="连接新设备",dG="分布式执行",uG="分布式执行功能暂未上线。",pG="辅助设备",mG="辅助设备功能暂未上线。",gG="知道了",hG="局域网",fG="Sparo 中继",yG="内网穿透",wG="自建服务器",vG="IM 控制",bG="连接承载",kG="IM 控制",SG="连接",xG="连接中...",CG="断开连接",AG="取消",_G="使用手机扫描二维码进行连接",TG="将配对码发送给机器人完成配对",PG="移动设备已连接,可以关闭此对话框。",FG="用户 ID",RG="查看 ngrok 隧道用量与状态。",NG="服务器地址",DG="当前 IP",IG="网关 IP",MG="飞书",jG="打开机器人",EG="就绪",LG="等待连接...",$G="已拷贝 URL",OG="等待机器人确认...",BG="握手中...",WG="验证中...",zG="已连接",UG="已断开",HG="通过局域网连接,两台设备需在同一LAN/WiFi下。若连接失败,请检查路由器安全设置(如AP隔离/客户端隔离)是否限制局域网互访,并确认两台设备的代理服务设置未影响局域网流量(允许直连局域网)。",qG="通过Sparo OS中继服务器连接。当前该服务器由Sparo OS团队自建,主要用于便捷试用与功能体验。尽管业务消息采用端到端加密,中继服务及其相关基础设施仍可能感知必要元数据,且任何公网服务都可能因配置缺陷、日志暴露、运营失误或遭受攻击而带来信息安全与数据泄露风险。若用于长期使用、正式环境或更高安全要求场景,建议优先使用自建服务器,并自行控制部署与运维策略。",VG="通过ngrok隧道连接,首次使用需安装ngrok并完成授权,无需手动启动ngrok服务。",GG="通过ngrok隧道连接,首次使用需",KG="安装ngrok",QG="并完成授权,无需手动启动ngrok服务。",JG="通过自建中继服务器连接。",YG="通过",ZG="自建中继服务器连接",XG="。",eK="通过飞书、Telegram 或微信机器人连接,请先完成对应配置。",tK="打开Telegram,搜索 @BotFather",nK="发送 /newbot,按提示创建机器人",oK="复制Bot Token,粘贴到下方",sK="查看",iK="飞书机器人完整配置指南",aK="",rK="前往",lK="飞书开放平台",cK=",创建企业自建应用",dK="启用机器人能力,配置权限管理和事件与回调",uK="将App ID和App Secret填入下方",pK="微信",mK="使用腾讯微信 iLink 通道连接。需先用微信扫码登录,再与飞书/Telegram 一样发送 6 位配对码。",gK="点击下方按钮显示二维码,用微信扫码并在手机上确认登录。",hK="在手机微信中确认登录后,桌面端会自动显示 6 位配对码;在微信中打开与机器人的对话并发送该配对码。",fK="获取微信登录二维码",yK="取消扫码",wK="已扫码,请在微信中确认登录;确认后将自动显示配对码。",vK="微信已登录。若未自动进入配对步骤,请点击「连接」重试。",bK="等待扫码确认…",kK="详细模式",SK="简洁模式",xK="打开 ngrok 安装与配置页面",CK="远程连接免责声明",AK="启用远程连接前,请确认你已理解并接受以下事项:",_K="远程连接可能存在未发现的安全漏洞、功能缺陷或不兼容变更,请在充分了解风险后使用。",TK="远程连接会开启与网络通信相关的能力(包括但不限于局域网、第三方中继、自建服务、机器人通道等),请仅在可信网络和可信设备上使用。",PK="远程连接采用端到端加密(X25519 ECDH + AES-256-GCM,每次会话生成临时密钥对)传输业务消息,中继服务器无法解密消息内容;但设备名称、连接状态、服务地址等必要元数据及其他连接上下文信息不属于业务消息密文范畴,仍可能被网络路径、服务节点或其他基础设施感知。",FK="Sparo OS 远程连接的加密实现完全开源,你可以自行审计源码以验证安全性。",RK="请勿在不受信任环境中传输敏感信息;机器人消息平台、第三方网络、系统日志策略等可能影响你的数据暴露面,其他外部服务策略变化亦可能带来额外风险。",NK="Sparo OS 不会将你的远程连接业务内容用于训练或商业化使用;但你选择接入的第三方服务(如 ngrok、Telegram、飞书、自建服务器运维组件等)可能按其条款处理数据,其他关联服务亦可能产生数据处理行为。",DK="使用 ngrok、自建中继、Telegram/飞书机器人等方式时,相关地址、Token、App Secret、密钥及其他访问凭证由你自行保管,泄露可能导致未授权访问或其他安全事件。",IK="二维码中包含中继地址、房间标识、公钥等连接信息及其他会话标识,请避免将其截图、录屏或展示给无关人员。",MK="使用 ngrok 或其他第三方隧道服务时,流量会经过外部服务链路。请自行评估账号安全、地域合规、配额限制、服务可用性与潜在中间链路风险等因素。",jK="使用自建中继服务时,你需自行负责主机与容器安全(包括但不限于系统补丁、访问控制、TLS 证书、端口暴露、防火墙、DDoS/爆破防护、日志审计、备份恢复等)。服务器被攻击、配置错误、密钥泄露或其他运维失误可能导致连接中断、数据泄露或被篡改风险。",EK="网络环境、防火墙、路由器隔离策略(如 AP/客户端隔离)、代理/隧道服务设置等以及其他网络策略都可能影响连接结果与稳定性。",LK="机器人模式下发送的配对码仅用于当前会话绑定,请勿向无关人员泄露;其他机器人平台机制或策略变更也可能影响安全性与可用性。",$K="机器人配对信息会保存在本地磁盘以便重启后自动恢复连接;如果本机被未授权人员访问、恶意软件入侵或发生其他系统安全事件,该信息可能被利用。",OK="移动端通过浏览器加载 Web 应用进行连接,浏览器缓存、本地存储、页面截图、系统剪贴板等都可能带来额外的信息暴露风险,其他浏览器插件或系统功能亦可能扩大风险面。",BK="部分国家或地区对加密通信、隧道服务、跨境数据传输等有法规限制,请自行评估当地法律合规性;其他监管政策变化也可能影响功能可用性与合规义务。",WK="使用远程连接功能过程中产生的风险、损失、纠纷或其他不利后果(包括但不限于数据泄露、连接中断、账号异常、服务不可用等)由你自行承担;Sparo OS 不对由此造成的问题负责。",zK="查看免责声明",UK="已同意",HK="未同意",qK="不同意",VK="同意并继续",GK={title:gV,networkTitle:hV,setupTitle:fV,connectionSettings:yV,backToNetwork:wV,controlLayer:vV,mobileEndpoint:bV,desktopEndpoint:kV,desktopControl:SV,mobileControl:xV,imControl:CV,thisComputer:AV,currentDevice:_V,myPhone:TV,canViewControl:PV,onlineControl:FV,waitingForPhone:RV,auxiliaryInteraction:NV,throughPhone:DV,watch:IV,headphones:MV,glasses:jV,messageCommandEntry:EV,secureConnection:LV,endToEndEncrypted:$V,transportMethod:OV,transportHint:BV,setupSummaryLan:WV,setupSummaryNgrok:zV,setupSummarySparoServer:UV,setupSummaryCustomServer:HV,setupSummaryTelegram:qV,setupSummaryFeishu:VV,setupSummaryWeixin:GV,executionDataNodes:KV,dataCenter:QV,executionNode:JV,sameDeviceCanControl:YV,localNodeRunning:ZV,windowsNodePlaceholder:XV,linuxNodePlaceholder:eG,windowsNode:tG,linuxNode:nG,readyToAdd:oG,add:sG,concurrentExecutionHint:iG,nodeSummary:aG,nodeSummaryConnected:rG,scanQr:lG,connectNewDevice:cG,distributedExecutionTitle:dG,distributedExecutionUnavailable:uG,auxiliaryDevicesTitle:pG,auxiliaryDevicesUnavailable:mG,gotIt:gG,tabLan:hG,tabSparoServer:fG,tabNgrok:yG,tabCustomServer:wG,tabBot:vG,groupNetwork:bG,groupBot:kG,connect:SG,connecting:xG,disconnect:CG,cancel:AG,scanHint:_G,botHint:TG,connectedHint:PG,connectedUserId:FG,ngrokUsageLink:RG,serverUrl:NG,currentIp:DG,gatewayIp:IG,feishu:MG,openBot:jG,stateIdle:EG,stateWaiting:LG,urlCopied:$G,stateWaitingBot:OG,stateHandshaking:BG,stateVerifying:WG,stateConnected:zG,stateDisconnected:UG,desc_lan:HG,desc_sparo_server:qG,desc_ngrok:VG,desc_ngrok_prefix:GG,desc_ngrok_link:KG,desc_ngrok_suffix:QG,desc_custom_server:JG,desc_custom_server_prefix:YG,desc_custom_server_link:ZG,desc_custom_server_suffix:XG,desc_bot:eK,botTgStep1:tK,botTgStep2:nK,botTgStep3:oK,botFeishuDocPrefix:sK,botFeishuDocLink:iK,botFeishuDocSuffix:aK,botFeishuStep1Prefix:rK,botFeishuOpenPlatform:lK,botFeishuStep1Suffix:cK,botFeishuStep2:dK,botFeishuStep3:uK,weixin:pK,botWeixinIntro:mK,botWeixinStep1:gK,botWeixinStep2:hK,botWeixinQrButton:fK,botWeixinQrCancel:yK,botWeixinAwaitingPhoneConfirm:wK,botWeixinLinked:vK,botWeixinPolling:bK,botVerboseMode:kK,botConciseMode:SK,openNgrokSetup:xK,disclaimerTitle:CK,disclaimerIntro:AK,disclaimerItemGeneralRisk:_K,disclaimerItemSecurity:TK,disclaimerItemEncryption:PK,disclaimerItemOpenSource:FK,disclaimerItemPrivacy:RK,disclaimerItemDataUsage:NK,disclaimerItemCredentials:DK,disclaimerItemQrCode:IK,disclaimerItemNgrok:MK,disclaimerItemSelfHosted:jK,disclaimerItemNetwork:EK,disclaimerItemBot:LK,disclaimerItemBotPersistence:$K,disclaimerItemMobileBrowser:OK,disclaimerItemCompliance:BK,disclaimerItemLiability:WK,disclaimerReview:zK,disclaimerStatusAgreed:UK,disclaimerStatusPending:HK,disclaimerDecline:qK,disclaimerAgree:VK},KK={title:"编辑器",openFile:"打开文件",saveFile:"保存文件",saveAs:"另存为",closeFile:"关闭文件",closeAll:"关闭所有",undo:"撤销",redo:"重做",find:"查找",replace:"替换",findInFiles:"在文件中查找",goToLine:"跳转到行",goToSymbol:"跳转到符号",format:"格式化",formatSelection:"格式化选中内容",comment:"切换注释",fold:"折叠",unfold:"展开",foldAll:"折叠全部",unfoldAll:"展开全部",wordWrap:"自动换行",minimap:"缩略图",breadcrumbs:"面包屑导航",lineNumbers:"行号",whitespace:"空白字符",encoding:"编码",lineEnding:"行尾",language:"语言模式",common:{retry:"重试",loading:"加载中...",loadFailed:"加载失败",fileNotFound:"文件不存在",permissionDenied:"权限不足",networkError:"网络错误",saveFailedWithMessage:"保存文件失败: {{message}}",save:"保存",cancel:"取消",edit:"编辑",add:"新增",delete:"删除"},codeEditor:{loadingFile:"正在加载文件...",saving:"正在保存...",initFailedWithMessage:"编辑器初始化失败: {{message}}",externalModifiedConfirm:`该文件已被外部程序修改。 + +您当前有未保存的修改,是否要放弃修改并重新加载文件?`,externalModifiedTitle:"磁盘上的文件已变更",externalModifiedDetail:"检测到该文件在磁盘上的版本(修改时间/大小)与当前编辑器所依据的版本不一致。您有未保存的本地修改。若重新加载,本地未保存内容将丢失。",discardAndReload:"放弃修改并重新加载",keepLocalEdits:"保留本地编辑",saveConflictTitle:"保存冲突",saveConflictDetail:"保存前检测到磁盘上的文件已被其他程序修改。您可以选择用当前编辑覆盖磁盘,或放弃本地修改并从磁盘重新加载。",overwriteSave:"覆盖保存",reloadFromDisk:"从磁盘重新加载",unsupportedBinaryTitle:"不支持的文件类型",unsupportedBinaryMessage:"该文件类型无法在编辑器中打开,Sparo OS 未加载其内容。请使用外部应用查看。",unsupportedBinaryMessageWithSize:"该 {{size}} 文件类型无法在编辑器中打开,Sparo OS 未加载其内容。请使用外部应用查看。"},diffEditor:{loading:"正在加载差异编辑器...",openFailed:"打开失败",initFailedWithMessage:"差异编辑器初始化失败: {{message}}",changesCount:"({{count}} 处差异)",prevChange:"上一个差异 (Alt+↑ / Shift+F7)",nextChange:"下一个差异 (Alt+↓ / F7)",switchToInline:"切换到内联视图",switchToSideBySide:"切换到并排视图"},imageViewer:{filePathEmpty:"文件路径为空",loadImageFailedWithMessage:"加载图片失败: {{message}}",decodeFailed:"图片加载失败,浏览器无法解析图片数据",zoomOut:"缩小 (Ctrl + -)",zoomReset:"重置缩放 (Ctrl + 0)",zoomIn:"放大 (Ctrl + +)",rotate90:"旋转 90°",download:"下载图片",enterFullscreen:"全屏显示",exitFullscreen:"退出全屏",imageUrlEmpty:"图片URL为空"},statusBar:{readOnly:"只读",goToLine:"跳转到行",indentSettings:"缩进设置",fileEncoding:"文件编码",selectLanguageMode:"选择语言模式",lspConnected:"LSP 已连接",lspConnecting:"LSP 连接中...",lspDisconnected:"LSP 未连接",selectionLinesChars:"{{lines}} 行, {{chars}} 字符",selectionChars:"{{count}} 已选",ln:"Ln",col:"Col",indentSpaces:"空格: {{n}}",indentTab:"Tab: {{n}}",goToLineHint:"行 或 行:列(Enter 跳转,Esc 关闭)",goToLinePlaceholder:"例如 10 或 10:5",selectIndent:"选择缩进",selectEncoding:"选择编码",selectLanguageModeHint:"选择语言模式(点击即切换)",indentOptionSpaces:"空格: {{n}}",indentOptionTab:"Tab: {{n}}"}},QK={title:"终端",new:"新建终端",split:"拆分终端",kill:"终止",clear:"清空",scrollToBottom:"滚动到底部",copySelection:"复制选中内容",paste:"粘贴",selectAll:"全选",find:"查找",shell:"Shell",workingDirectory:"工作目录",runCommand:"运行命令",commandHistory:"命令历史"},JK={title:"Git",repository:"仓库",branch:"分支",branches:"分支列表",checkout:"切换分支",newBranch:"新建分支",deleteBranch:"删除分支",merge:"合并",rebase:"变基",commit:"提交",commitMessage:"提交信息",stage:"暂存",unstage:"取消暂存",stageAll:"暂存全部",unstageAll:"取消全部暂存",discard:"放弃更改",discardAll:"放弃所有更改",push:"推送",pull:"拉取",fetch:"获取",remote:"远程仓库",remotes:"远程仓库列表",stash:"贮藏",stashList:"贮藏列表",stashApply:"应用贮藏",stashPop:"弹出贮藏",stashDrop:"删除贮藏",log:"提交历史",diff:"差异",blame:"追溯",tags:"标签",status:{modified:"已修改",added:"已添加",deleted:"已删除",renamed:"已重命名",untracked:"未跟踪",staged:"已暂存",conflict:"冲突",unknown:"未知"},statusDescription:{untracked:"新文件,尚未添加到 Git",modified:"文件已修改但未暂存",added:"新文件已暂存",deleted:"文件已删除",renamed:"文件已重命名",conflicted:"文件存在合并冲突",staged:"修改已暂存,等待提交",unknown:"未知状态"},actions:{sync:"同步",refresh:"刷新",viewHistory:"查看历史",viewChanges:"查看更改",resolveConflict:"解决冲突"}},YK={referencesPanel:{previewFallback:"(无预览)",emptyTitle:"未找到引用",emptyWithSymbol:'符号 "{{symbol}}" 没有引用',emptyDescription:"没有找到引用",titleWithSymbol:'"{{symbol}}" 的引用',title:"引用列表",emptyLine:"(空行)"},errors:{loadPluginsFailed:"Failed to load plugins",installPluginFailed:"Failed to install plugin",uninstallPluginFailed:"Failed to uninstall plugin",initializeFailed:"Failed to initialize LSP"}},ZK={title:"文件浏览器",empty:"暂无文件",emptyFiltered:"未找到匹配的文件",draggingFile:"文件:{{name}}",newFile:"新建文件",newFolder:"新建文件夹",rename:"重命名",delete:"删除",refresh:"刷新",collapse:"折叠全部",expand:"展开全部",filter:"筛选文件",showHidden:"显示隐藏文件",sortBy:"排序方式",sortByName:"按名称",sortByModified:"按修改时间",sortBySize:"按大小",sortByType:"按类型",compressionTooltip:`压缩路径: {{compressed}} +完整路径: {{full}}`,errors:{loadTreeFailed:"加载文件树失败",loadTreeFailedWithMessage:"加载文件树失败: {{message}}"}},XK={title:"搜索",placeholder:"搜索...",searchFiles:"搜索文件",searchContent:"搜索内容",searchSymbols:"搜索符号",matchCase:"区分大小写",matchWholeWord:"全词匹配",useRegex:"使用正则表达式",includeFiles:"包含文件",excludeFiles:"排除文件",results:"搜索结果",noResults:"无搜索结果",noResultsHint:"尝试修改搜索词或检查拼写",expand:"展开",collapse:"收起",resultsSummary:"找到 {{files}} 个文件,共 {{matches}} 处匹配",resultsShowing:"(显示前 {{count}} 个)",loadMore:"加载更多 ({{count}})",replace:"替换",replaceAll:"全部替换",global:{placeholder:"搜索文件和内容...",placeholderDisabled:"请先打开工作区",phaseFilename:"搜索文件名...",phaseContent:"搜索内容...",resultsFound:"找到 {{count}} 个结果",resultsShowing:" (显示 {{count}} 个)",loadMore:"加载更多 ({{count}} 个结果)",resultsTruncatedFiles:"当前仅显示前 {{count}} 个文件匹配结果。",resultsTruncatedContent:"当前仅显示前 {{count}} 个内容匹配结果。",lineNumberPrefix:"第 {{line}} 行: "}},eQ={title:"快照",create:"创建快照",restore:"恢复快照",delete:"删除快照",compare:"比较快照",list:"快照列表",name:"快照名称",description:"快照描述",createdAt:"创建时间",auto:"自动快照",manual:"手动快照"},tQ={title:"可视化",mermaid:"Mermaid 图表",zoom:"缩放",zoomIn:"放大",zoomOut:"缩小",fitView:"适应视图",center:"居中",export:"导出图片",layout:"布局"},nQ={editor:{loadingFile:"正在加载文件...",placeholder:"开始编写 Markdown 内容...",emptyPreview:"当前文件暂时没有任何内容,按空格开启AI协作",source:"源码",markdown:"Markdown",livePreview:"实时预览",preview:"预览",moreMenu:"更多",centeredLayout:"居中显示",documentSections:"章节列表",viewModeLabel:"Markdown 编辑器模式",exportHtml:"导出 HTML",exportPdf:"导出 PDF",exportSaveTitleHtml:"将 Markdown 导出为 HTML",exportSaveTitlePdf:"将 Markdown 导出为 PDF",exportedHtml:"HTML 已导出到 {{path}}",exportedPdf:"PDF 已导出到 {{path}}",exportFailed:"导出失败:{{message}}",revealExport:"在文件夹中显示",exportNeedsDesktop:"Markdown 导出功能需要在桌面应用中使用。",notice:{sourcePreviewFallback:"该文档包含无法在可视化模式中安全表示的内容。请在源码模式中编辑,或切换到预览查看效果。"}},planViewer:{loadingPlan:"正在加载计划...",unsaved:"未保存",build:"构建",built:"已构建",building:"构建中...",remainingTodos:"剩余 {{count}} 个待办",toggleYamlEditOn:"编辑 YAML",toggleYamlEditOff:"关闭编辑",yamlPlaceholder:"YAML frontmatter...",contentPlaceholder:"计划内容...",buildPlanTitle:"构建计划:{{name}}"},tiptap:{placeholder:"请输入 Markdown 内容...",toolbarPlaceholder:"工具栏",mermaidRendering:"正在渲染 Mermaid 图表...",mermaidRenderFailed:"Mermaid 渲染失败",mermaidRenderFailedWithMessage:"渲染失败: {{message}}",unknownError:"未知错误",localImageAltLoadFailedWithSrc:"图片加载失败: {{src}}",localImageTitleUnableToLoadWithPath:"无法加载: {{path}}",localImageLoading:"图片加载中...",localImageFailed:"图片加载失败",outline:{label:"文档章节",title:"章节"},rawHtml:{inlineLabel:"HTML",preview:"预览",sandbox:"沙箱",source:"源码",editSource:"编辑源码",html:"HTML",details:"详情",frontmatter:"Frontmatter",footnote:"脚注",markdown:"Markdown"},details:{summaryPlaceholder:"摘要"},tableQuickInsert:{insertColumn:"插入列",insertRow:"插入行"},insertLinkTextPlaceholder:"链接文本",inlineAi:{triggerHint:"按空格以启用 AI",askMode:"问 AI",continueMode:"继续编写",askPlaceholder:"万事问 AI ...",continuePlaceholder:"补充一下你希望续写的方向...",currentPage:"当前页面",suggestionSection:"建议",summaryAction:"添加摘要",todoAction:"添加待办事项",summaryDirection:"在当前位置插入一段简短摘要,概括上文的关键内容,并保持当前文档语言和风格。",todoDirection:"在当前位置插入一个简洁的 Markdown 待办事项列表,提炼出接下来的行动项,并保持当前文档语言和风格。",thinkSection:"思考、询问、对话",cancel:"取消",working:"处理中...",askSubmit:"发送给 AI",continueSubmit:"继续编写",accept:"接受写入",reject:"丢弃",previewTitle:"AI 预览",previewStreaming:"生成中",previewReady:"待确认",workspaceRequired:"请先打开工作区,再使用 AI 辅助。",askEmpty:"请输入要问 AI 的内容。",askSent:"问题已发送到当前工作区的 AI 会话。",askFailed:"发送问题失败。",continueInserted:"AI 续写内容已插入。",continueEmptyResult:"AI 没有返回可插入内容,或者插入位置已失效。",continueFailed:"AI 续写失败。",continueStartFailed:"启动 AI 续写失败。",tempSessionName:"Markdown 内联续写"},coauthor:{barLabel:"AI 协作",actionPlaceholder:"选择动作",promptPlaceholder:"可选要求",apply:"改写",review:"审阅",run:"生成提案",acceptAll:"全部接受",rejectAll:"全部拒绝",retry:"重试",stale:"内容已变化",selectionUnresolved:"无法安全定位选中的 Markdown。",comments:"评论",profileOn:"已启用文档画像",profileOff:"已禁用文档画像",failed:"协作请求失败。",applied:"协作提案已应用。",polishSelection:"润色",reviewSelection:"审阅",selectionAnchor:"让 Sparo 改写这段选中内容",selectionPromptPlaceholder:"告诉 Sparo 如何改写这段",selectionSubmit:"改写选中内容",selectionClose:"关闭选区改写",acceptOp:"接受此项",rejectOp:"拒绝此项",acceptShort:"接受",rejectShort:"取消",acceptHunk:"接受此段",rejectHunk:"拒绝此段",proposed:"建议改动",streamingRewrite:"正在原文位置改写...",commentPin:"协作评论"},shortcuts:{undo:"撤销",redo:"重做",save:"保存",escape:"退出编辑",indent:"缩进",outdent:"取消缩进",bold:"加粗",italic:"斜体",link:"插入链接",newBlock:"新建块"}}},oQ={editor:KK,terminal:QK,git:JK,lsp:YK,fileTree:ZK,search:XK,snapshot:eQ,visualization:tQ,markdown:nQ},sQ="显示窗口",iQ="隐藏窗口",aQ="新建会话",rQ="最近会话",lQ="暂无会话",cQ="退出",dQ="Sparo OS v{{version}}",uQ="Sparo OS 已最小化到托盘,右键点击托盘图标打开菜单。",pQ="确认退出",mQ="当前有 {{count}} 个 Agent 任务正在运行,确定要退出吗?",gQ={showWindow:sQ,hideWindow:iQ,newSession:aQ,recentSessions:rQ,noSessions:lQ,quit:cQ,version:dQ,trayHint:uQ,quitConfirmTitle:pQ,quitConfirmMessage:mQ},hQ=["zh-CN","en-US"],fQ=["common","components","design-system/preview","errors","flow-chat","flow-chat/chat-input","flow-chat/design-canvas","flow-chat/session","flow-chat/tool-cards","flow-chat/welcome","notifications","panels/files","panels/git","panels/terminal","scenes/app-builder","scenes/files","scenes/memory","scenes/apps","scenes/capabilities","scenes/skills","scenes/subagents","scenes/daily-letter","scenes/work-center","scenes/tools","scenes/welcome","settings/config-center","settings/keyboard","settings","settings/agentic-tools","settings/agents","settings/ai-features","settings/ai-model","settings/ai-mode","settings/ai-usage","settings/appearance","settings/basics","settings/debug","settings/data-storage","settings/default-model","settings/editor","settings/mcp","settings/memory","settings/permissions","settings/personalization","settings/voice-input","shell/header","shell/navigation","shell/remote-connect","tools","tray"],Xa="zh-CN",Ug="en-US",fs=[{id:"zh-CN",name:"简体中文",englishName:"Simplified Chinese",nativeName:"简体中文",rtl:!1,dateFormat:"YYYY年M月D日",numberFormat:{decimal:".",thousands:","},builtin:!0},{id:"en-US",name:"English",englishName:"English (US)",nativeName:"English",rtl:!1,dateFormat:"MM/DD/YYYY",numberFormat:{decimal:".",thousands:","},builtin:!0}];function er(i){return hQ.includes(i)}const yQ="common",Hg=fQ,Wm=i=>{let e;const n=new Set,s=(f,y)=>{const v=typeof f=="function"?f(e):f;if(!Object.is(v,e)){const b=e;e=y??(typeof v!="object"||v===null)?v:Object.assign({},e,v),n.forEach(S=>S(e,b))}},r=()=>e,m={setState:s,getState:r,getInitialState:()=>h,subscribe:f=>(n.add(f),()=>n.delete(f))},h=e=i(s,r,m);return m},wQ=(i=>i?Wm(i):Wm),vQ=i=>i;function bQ(i,e=vQ){const n=De.useSyncExternalStore(i.subscribe,De.useCallback(()=>e(i.getState()),[i,e]),De.useCallback(()=>e(i.getInitialState()),[i,e]));return De.useDebugValue(n),n}const kQ=i=>{const e=wQ(i),n=s=>bQ(e,s);return Object.assign(n,e),n},SQ=(i=>kQ);function xQ(i,e){let n;try{n=i()}catch{return}return{getItem:r=>{var c;const u=h=>h===null?null:JSON.parse(h,void 0),m=(c=n.getItem(r))!=null?c:null;return m instanceof Promise?m.then(u):u(m)},setItem:(r,c)=>n.setItem(r,JSON.stringify(c,void 0)),removeItem:r=>n.removeItem(r)}}const Bc=i=>e=>{try{const n=i(e);return n instanceof Promise?n:{then(s){return Bc(s)(n)},catch(s){return this}}}catch(n){return{then(s){return this},catch(s){return Bc(s)(n)}}}},CQ=(i,e)=>(n,s,r)=>{let c={storage:xQ(()=>window.localStorage),partialize:_=>_,version:0,merge:(_,E)=>({...E,..._}),...e},u=!1,m=0;const h=new Set,f=new Set;let y=c.storage;if(!y)return i((..._)=>{console.warn(`[zustand persist middleware] Unable to update item '${c.name}', the given storage is currently unavailable.`),n(..._)},s,r);const v=()=>{const _=c.partialize({...s()});return y.setItem(c.name,{state:_,version:c.version})},b=r.setState;r.setState=(_,E)=>(b(_,E),v());const S=i((..._)=>(n(..._),v()),s,r);r.getInitialState=()=>S;let A;const F=()=>{var _,E;if(!y)return;const j=++m;u=!1,h.forEach(B=>{var W;return B((W=s())!=null?W:S)});const z=((E=c.onRehydrateStorage)==null?void 0:E.call(c,(_=s())!=null?_:S))||void 0;return Bc(y.getItem.bind(y))(c.name).then(B=>{if(B)if(typeof B.version=="number"&&B.version!==c.version){if(c.migrate){const W=c.migrate(B.state,B.version);return W instanceof Promise?W.then(I=>[!0,I]):[!0,W]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,B.state];return[!1,void 0]}).then(B=>{var W;if(j!==m)return;const[I,ee]=B;if(A=c.merge(ee,(W=s())!=null?W:S),n(A,!0),I)return v()}).then(()=>{j===m&&(z?.(A,void 0),A=s(),u=!0,f.forEach(B=>B(A)))}).catch(B=>{j===m&&z?.(void 0,B)})};return r.persist={setOptions:_=>{c={...c,..._},_.storage&&(y=_.storage)},clearStorage:()=>{y?.removeItem(c.name)},getOptions:()=>c,rehydrate:()=>F(),hasHydrated:()=>u,onHydrate:_=>(h.add(_),()=>{h.delete(_)}),onFinishHydration:_=>(f.add(_),()=>{f.delete(_)})},c.skipHydration||F(),A||S},AQ=CQ,zm={currentLanguage:Xa,fallbackLanguage:Ug,loadedNamespaces:[],isInitialized:!1,isChanging:!1,autoDetect:!1},di=SQ()(AQ(i=>({...zm,setCurrentLanguage:e=>{i({currentLanguage:e})},setFallbackLanguage:e=>{i({fallbackLanguage:e})},addLoadedNamespace:e=>{i(n=>({loadedNamespaces:n.loadedNamespaces.includes(e)?n.loadedNamespaces:[...n.loadedNamespaces,e]}))},setInitialized:e=>{i({isInitialized:e})},setChanging:e=>{i({isChanging:e})},setAutoDetect:e=>{i({autoDetect:e})},reset:()=>{i(zm)}}),{name:"sparo-i18n-state",partialize:i=>({currentLanguage:i.currentLanguage,fallbackLanguage:i.fallbackLanguage,autoDetect:i.autoDetect})}));async function Ss(i,e={},n){return window.__TAURI_INTERNALS__.invoke(i,e,n)}var Um;(function(i){i.WINDOW_RESIZED="tauri://resize",i.WINDOW_MOVED="tauri://move",i.WINDOW_CLOSE_REQUESTED="tauri://close-requested",i.WINDOW_DESTROYED="tauri://destroyed",i.WINDOW_FOCUS="tauri://focus",i.WINDOW_BLUR="tauri://blur",i.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",i.WINDOW_THEME_CHANGED="tauri://theme-changed",i.WINDOW_CREATED="tauri://window-created",i.WINDOW_SUSPENDED="tauri://suspended",i.WINDOW_RESUMED="tauri://resumed",i.WEBVIEW_CREATED="tauri://webview-created",i.DRAG_ENTER="tauri://drag-enter",i.DRAG_OVER="tauri://drag-over",i.DRAG_DROP="tauri://drag-drop",i.DRAG_LEAVE="tauri://drag-leave"})(Um||(Um={}));var No;(function(i){i[i.Trace=1]="Trace",i[i.Debug=2]="Debug",i[i.Info=3]="Info",i[i.Warn=4]="Warn",i[i.Error=5]="Error"})(No||(No={}));function _Q(i){if(i)if(i.startsWith("Error")){const n=i.split(` +`)[3]?.trim();if(!n)return;const s=/at\s+(?.*?)\s+\((?.*?):(?\d+):(?\d+)\)/,r=n.match(s);if(r){const{functionName:c,fileName:u,lineNumber:m,columnNumber:h}=r.groups;return`${c}@${u}:${m}:${h}`}else{const c=/at\s+(?.*?):(?\d+):(?\d+)/,u=n.match(c);if(u){const{fileName:m,lineNumber:h,columnNumber:f}=u.groups;return`@${m}:${h}:${f}`}}}else return i.split(` +`).map(s=>s.split("@")).filter(([s,r])=>s.length>0&&r!=="[native code]")[2]?.filter(s=>s.length>0).join("@")}async function Ii(i,e,n){const s=_Q(new Error().stack),{file:r,line:c,keyValues:u}={};await Ss("plugin:log|log",{level:i,message:e,location:s,file:r,line:c,keyValues:u})}async function TQ(i,e){await Ii(No.Error,i)}async function PQ(i,e){await Ii(No.Warn,i)}async function FQ(i,e){await Ii(No.Info,i)}async function RQ(i,e){await Ii(No.Debug,i)}async function NQ(i,e){await Ii(No.Trace,i)}const DQ=typeof window<"u"&&("__TAURI_INTERNALS__"in window||"__TAURI__"in window);function IQ(i){if(i==null)return"";if(i instanceof Error)return i.stack||i.message;if(typeof i=="object")try{const e={},n=[];for(const r in i){const c=i[r];c instanceof Error?n.push(c.stack||`${c.name}: ${c.message}`):e[r]=c}const s=[];return Object.keys(e).length>0&&s.push(JSON.stringify(e)),n.length>0&&s.push(n.join(` +`)),s.join(", ")}catch{return String(i)}return String(i)}class ps{static instance;currentLevel;constructor(){this.currentLevel=3}static getInstance(){return ps.instance||(ps.instance=new ps),ps.instance}setLevel(e){this.currentLevel=e}getLevel(){return this.currentLevel}trace(e,n,s){this.log(0,e,n,s)}debug(e,n,s){this.log(1,e,n,s)}info(e,n,s){this.log(2,e,n,s)}warn(e,n,s){this.log(3,e,n,s)}error(e,n,s){this.log(4,e,n,s)}log(e,n,s,r){if(e{});break;case 1:RQ(n).catch(()=>{});break;case 2:FQ(n).catch(()=>{});break;case 3:PQ(n).catch(()=>{});break;case 4:TQ(n).catch(()=>{});break}}outputConsole(e,n,s){const r=s!==void 0?[n,s]:[n];switch(e){case 0:case 1:console.debug(...r);break;case 2:console.info(...r);break;case 3:console.warn(...r);break;case 4:console.error(...r);break}}createContextLogger(e){return{trace:(n,s)=>this.trace(n,e,s),debug:(n,s)=>this.debug(n,e,s),info:(n,s)=>this.info(n,e,s),warn:(n,s)=>this.warn(n,e,s),error:(n,s)=>this.error(n,e,s)}}}const MQ=ps.getInstance(),ft=i=>MQ.createContextLogger(i),jQ="modulepreload",EQ=function(i){return"/"+i},Hm={},Xt=function(e,n,s){let r=Promise.resolve();if(n&&n.length>0){let h=function(f){return Promise.all(f.map(y=>Promise.resolve(y).then(v=>({status:"fulfilled",value:v}),v=>({status:"rejected",reason:v}))))};document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),m=u?.nonce||u?.getAttribute("nonce");r=h(n.map(f=>{if(f=EQ(f),f in Hm)return;Hm[f]=!0;const y=f.endsWith(".css"),v=y?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${f}"]${v}`))return;const b=document.createElement("link");if(b.rel=y?"stylesheet":jQ,y||(b.as="script"),b.crossOrigin="",b.href=f,m&&b.setAttribute("nonce",m),document.head.appendChild(b),y)return new Promise((S,A)=>{b.addEventListener("load",S),b.addEventListener("error",()=>A(new Error(`Unable to preload CSS for ${f}`)))})}))}function c(u){const m=new Event("vite:preloadError",{cancelable:!0});if(m.payload=u,window.dispatchEvent(m),!m.defaultPrevented)throw u}return r.then(u=>{for(const m of u||[])m.status==="rejected"&&c(m.reason);return e().catch(c)})};function ct(i,e,n,s){if(typeof e=="function"?i!==e||!s:!e.has(i))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?s:n==="a"?s.call(i):s?s.value:e.get(i)}function ds(i,e,n,s,r){if(typeof e=="function"?i!==e||!0:!e.has(i))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(i,n),n}var ko,Wt,cs,Ha,tr;const Wc="__TAURI_TO_IPC_KEY__";function ld(i,e=!1){return window.__TAURI_INTERNALS__.transformCallback(i,e)}class qg{constructor(e){ko.set(this,void 0),Wt.set(this,0),cs.set(this,[]),Ha.set(this,void 0),ds(this,ko,e||(()=>{})),this.id=ld(n=>{const s=n.index;if("end"in n){s==ct(this,Wt,"f")?this.cleanupCallback():ds(this,Ha,s);return}const r=n.message;if(s==ct(this,Wt,"f")){for(ct(this,ko,"f").call(this,r),ds(this,Wt,ct(this,Wt,"f")+1);ct(this,Wt,"f")in ct(this,cs,"f");){const c=ct(this,cs,"f")[ct(this,Wt,"f")];ct(this,ko,"f").call(this,c),delete ct(this,cs,"f")[ct(this,Wt,"f")],ds(this,Wt,ct(this,Wt,"f")+1)}ct(this,Wt,"f")===ct(this,Ha,"f")&&this.cleanupCallback()}else ct(this,cs,"f")[s]=r})}cleanupCallback(){window.__TAURI_INTERNALS__.unregisterCallback(this.id)}set onmessage(e){ds(this,ko,e)}get onmessage(){return ct(this,ko,"f")}[(ko=new WeakMap,Wt=new WeakMap,cs=new WeakMap,Ha=new WeakMap,Wc)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[Wc]()}}class zc{constructor(e,n,s){this.plugin=e,this.event=n,this.channelId=s}async unregister(){return Pn(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function LQ(i,e,n){const s=new qg(n);try{return await Pn(`plugin:${i}|register_listener`,{event:e,handler:s}),new zc(i,e,s.id)}catch{return await Pn(`plugin:${i}|registerListener`,{event:e,handler:s}),new zc(i,e,s.id)}}async function $Q(i){return Pn(`plugin:${i}|check_permissions`)}async function OQ(i){return Pn(`plugin:${i}|request_permissions`)}async function Pn(i,e={},n){return window.__TAURI_INTERNALS__.invoke(i,e,n)}function BQ(i,e="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(i,e)}class WQ{get rid(){return ct(this,tr,"f")}constructor(e){tr.set(this,void 0),ds(this,tr,e)}async close(){return Pn("plugin:resources|close",{rid:this.rid})}}tr=new WeakMap;function zQ(){return!!(globalThis||window).isTauri}const UQ=Object.freeze(Object.defineProperty({__proto__:null,Channel:qg,PluginListener:zc,Resource:WQ,SERIALIZE_TO_IPC_FN:Wc,addPluginListener:LQ,checkPermissions:$Q,convertFileSrc:BQ,invoke:Pn,isTauri:zQ,requestPermissions:OQ,transformCallback:ld},Symbol.toStringTag,{value:"Module"}));var Uc;(function(i){i.WINDOW_RESIZED="tauri://resize",i.WINDOW_MOVED="tauri://move",i.WINDOW_CLOSE_REQUESTED="tauri://close-requested",i.WINDOW_DESTROYED="tauri://destroyed",i.WINDOW_FOCUS="tauri://focus",i.WINDOW_BLUR="tauri://blur",i.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",i.WINDOW_THEME_CHANGED="tauri://theme-changed",i.WINDOW_CREATED="tauri://window-created",i.WEBVIEW_CREATED="tauri://webview-created",i.DRAG_ENTER="tauri://drag-enter",i.DRAG_OVER="tauri://drag-over",i.DRAG_DROP="tauri://drag-drop",i.DRAG_LEAVE="tauri://drag-leave"})(Uc||(Uc={}));async function HQ(i,e){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(i,e),await Pn("plugin:event|unlisten",{event:i,eventId:e})}async function Hc(i,e,n){var s;const r=typeof n?.target=="string"?{kind:"AnyLabel",label:n.target}:(s=n?.target)!==null&&s!==void 0?s:{kind:"Any"};return Pn("plugin:event|listen",{event:i,target:r,handler:ld(e)}).then(c=>async()=>HQ(i,c))}const qQ=Object.freeze(Object.defineProperty({__proto__:null,get TauriEvent(){return Uc},listen:Hc},Symbol.toStringTag,{value:"Module"})),Yn=ft("TauriAdapter");class VQ{unlistenFunctions=[];connected=!1;invokeFn=null;initPromise=null;async ensureInitialized(){if(!this.invokeFn){if(this.initPromise){await this.initPromise;return}this.initPromise=this.doInitialize(),await this.initPromise}}async doInitialize(){try{if(!(typeof window<"u"&&("__TAURI_INTERNALS__"in window||"__TAURI__"in window))){Yn.warn("Tauri API not available, running in non-Tauri environment"),this.invokeFn=async()=>{throw new Error("Tauri API is not available. Make sure you are running in a Tauri environment.")};return}const n=await Xt(()=>Promise.resolve().then(()=>UQ),void 0);this.invokeFn=n.invoke,Yn.debug("Tauri API initialized successfully")}catch(e){Yn.error("Failed to load Tauri API",e),this.invokeFn=async()=>{throw new Error("Failed to load Tauri API: "+(e instanceof Error?e.message:"Unknown error"))}}}async connect(){this.connected=!0}async request(e,n){this.connected||await this.connect(),await this.ensureInitialized();try{if(!this.invokeFn)throw new Error("Tauri invoke function not initialized");return n!==void 0?await this.invokeFn(e,n):await this.invokeFn(e)}catch(s){throw Yn.error("Request failed",{action:e,error:s}),s}}listen(e,n){let s=null,r=!1;return Hc(e,c=>{if(!r)try{n(c.payload)}catch(u){Yn.error("Error in event listener callback",{event:e,error:u})}}).then(c=>{r?c():(s=c,this.unlistenFunctions.push(c))}).catch(c=>{Yn.error("Failed to listen event",{event:e,error:c})}),()=>{if(r=!0,s){s();const c=this.unlistenFunctions.indexOf(s);c>-1&&this.unlistenFunctions.splice(c,1)}}}async listenReady(e,n){let s=!1;const r=await Hc(e,c=>{if(!s)try{n(c.payload)}catch(u){Yn.error("Error in event listener callback",{event:e,error:u})}});return s?(r(),()=>{}):(this.unlistenFunctions.push(r),()=>{s=!0,r();const c=this.unlistenFunctions.indexOf(r);c>-1&&this.unlistenFunctions.splice(c,1)})}async disconnect(){this.unlistenFunctions.forEach(e=>{try{e()}catch(n){Yn.error("Error while unlistening",n)}}),this.unlistenFunctions=[],this.connected=!1}isConnected(){return this.connected}}function GQ(i){return new VQ}let bc=null;function KQ(){return bc||(bc=GQ()),bc}const QQ=100,JQ=100,YQ=60;function kc(i,e,n){i.push(e),i.length>n&&i.splice(0,i.length-n)}class ZQ{recentTasks=[];recentApiCalls=[];eventLoopLag=[];contextGetter=null;lastHeartbeatAt;recordTask(e){kc(this.recentTasks,e,QQ)}recordApiCall(e){kc(this.recentApiCalls,e,JQ)}recordEventLoopLag(e){kc(this.eventLoopLag,e,YQ)}recordHeartbeat(e=Date.now()){this.lastHeartbeatAt=e}registerContext(e){return this.contextGetter=e,()=>{this.contextGetter===e&&(this.contextGetter=null)}}snapshot(e){return{...e,recentTasks:this.recentTasks.map(n=>({...n})),recentApiCalls:this.recentApiCalls.map(n=>({...n})),eventLoopLag:this.eventLoopLag.map(n=>({...n})),lastHeartbeatAt:this.lastHeartbeatAt,capturedAt:Date.now(),context:this.contextGetter?.()}}}function XQ(){return typeof window<"u"&&("__TAURI_INTERNALS__"in window||"__TAURI__"in window)}const eJ=ft("RuntimeHeartbeat"),tJ=1500;class nJ{constructor(e,n){this.snapshot=e,this.onSent=n}timer=null;sender=null;inFlight=!1;configure(e){this.sender=e}start(){if(this.timer!==null||!this.sender||!XQ())return;const e=()=>{this.sendHeartbeat(),this.timer=window.setTimeout(e,tJ)};e()}stop(){this.timer!==null&&(window.clearTimeout(this.timer),this.timer=null)}async sendHeartbeat(){if(!this.sender||this.inFlight)return;const e=this.snapshot();this.inFlight=!0;try{await this.sender.send(e),this.onSent()}catch(n){eJ.debug("Runtime heartbeat send failed",{error:n})}finally{this.inFlight=!1}}}const ui=ft("AppRuntime"),qm={"user-visible":0,background:1,idle:2},oJ=750,sJ=3e3,Sc=2e3,Vm=250,iJ=750,aJ=2,Gm=500;class rJ{diagnostics=new ZQ;heartbeat;nextTaskId=1;queue=[];activeCount=0;concurrency=2;gateOpen=!1;eventLoopPressure=!1;runtimeSafeMode=!1;recoveredLagTicks=0;monitorTimer=null;userInputHoldTimer=null;lastMonitorTick=0;lastUserInputAt=0;monitorsStarted=!1;constructor(){this.heartbeat=new nJ(()=>this.snapshot(),()=>this.diagnostics.recordHeartbeat())}activate(){this.gateOpen||(this.gateOpen=!0,this.pump())}startMonitors(){this.monitorsStarted||(this.monitorsStarted=!0,this.startEventLoopMonitor(),this.installVisibilityAndInputListeners())}setConcurrency(e){this.concurrency=Math.max(1,Math.floor(e)),this.pump()}setSafeMode(e){this.runtimeSafeMode!==e&&(this.runtimeSafeMode=e,e?ui.warn("Runtime safe mode enabled"):this.pump())}scheduleTask(e,n,s={}){const r=this.nextTaskId++,c=s.priority??"idle",u={id:r,name:e,priority:c,status:"queued",queuedAt:Date.now(),reason:s.reason};this.diagnostics.recordTask(u);const m={id:r,name:e,priority:c,run:n,slowMs:s.slowMs??oJ,cancelled:!1,record:u};let h=null,f=null;const y=()=>{if(m.cancelled){this.markCancelled(m);return}this.queue.push(m),this.queue.sort((b,S)=>qm[b.priority]-qm[S.priority]),this.pump()},v=()=>{if(m.cancelled){this.markCancelled(m);return}if(c==="user-visible"){y();return}const b=s.idleTimeoutMs??sJ,S=window.requestIdleCallback;if(typeof S=="function"){f=S(y,{timeout:b});return}h=window.setTimeout(y,Math.min(b,50))};return h=window.setTimeout(v,s.delayMs??0),{cancel:()=>{m.cancelled=!0,h!==null&&(window.clearTimeout(h),h=null),f!==null&&typeof window.cancelIdleCallback=="function"&&(window.cancelIdleCallback(f),f=null),this.markCancelled(m)}}}schedulePeriodicTask(e,n,s){let r=!1,c=null,u=null,m=!1;const h=()=>{c!==null&&(window.clearTimeout(c),c=null)};let f=()=>{};const y=()=>{if(r)return;const v=s.priority??"background";if(s.pauseWhenHidden&&document.visibilityState!=="visible"){this.recordSkipped(e,v,"document-hidden"),f(s.intervalMs);return}if(this.eventLoopPressure&&v!=="user-visible"){this.recordSkipped(e,v,"event-loop-pressure"),f(s.intervalMs);return}if(this.runtimeSafeMode&&v!=="user-visible"){this.recordSkipped(e,v,"runtime-safe-mode"),f(s.intervalMs);return}if(m){this.recordSkipped(e,v,"previous-run-active"),f(Math.max(1e3,Math.floor(s.intervalMs/2)));return}m=!0,u=this.scheduleTask(e,async()=>{try{await n()}finally{m=!1,u=null,r||f(s.intervalMs)}},s)};return f=v=>{h(),c=window.setTimeout(y,Math.max(0,v))},s.runImmediately?y():f(s.initialDelayMs??s.intervalMs),{cancel:()=>{r=!0,h(),u?.cancel(),u=null}}}snapshot(){return this.diagnostics.snapshot({gateOpen:this.gateOpen,pressure:this.eventLoopPressure,safeMode:this.runtimeSafeMode,visibility:document.visibilityState})}pump(){for(;this.activeCountthis.canDispatch(s.priority));if(e===-1)return;const[n]=this.queue.splice(e,1);if(!n||n.cancelled){n&&this.markCancelled(n);continue}this.runTask(n)}}canDispatch(e){return e==="user-visible"?!0:!(!this.gateOpen||this.eventLoopPressure||this.runtimeSafeMode||e==="idle"&&Date.now()-this.lastUserInputAte.run()).then(()=>{const n=Date.now(),s=n-(e.record.startedAt??n);e.record.status=e.cancelled?"cancelled":"completed",e.record.finishedAt=n,e.record.durationMs=s,s>e.slowMs&&ui.warn("Runtime task was slow",{name:e.name,durationMs:s,priority:e.priority})}).catch(n=>{const s=Date.now();e.record.status="failed",e.record.finishedAt=s,e.record.durationMs=s-(e.record.startedAt??s),e.record.error=n instanceof Error?n.message:String(n),ui.error("Runtime task failed",{name:e.name,priority:e.priority,error:n})}).finally(()=>{this.activeCount-=1,this.pump()})}markCancelled(e){e.record.status==="queued"&&(e.record.status="cancelled",e.record.finishedAt=Date.now())}recordSkipped(e,n,s){this.diagnostics.recordTask({id:this.nextTaskId++,name:e,priority:n,status:"skipped",queuedAt:Date.now(),finishedAt:Date.now(),reason:s})}startEventLoopMonitor(){if(this.monitorTimer!==null)return;this.lastMonitorTick=Date.now();const e=()=>{const n=Date.now(),s=Math.max(0,n-this.lastMonitorTick-Sc);this.lastMonitorTick=n,s>Vm&&(this.diagnostics.recordEventLoopLag({observedAt:n,lagMs:s}),ui.warn("Event loop lag observed",{lagMs:s})),s>iJ?(this.recoveredLagTicks=0,this.eventLoopPressure||(this.eventLoopPressure=!0,ui.warn("Runtime entered event-loop pressure",{lagMs:s}))):this.eventLoopPressure&&s=aJ&&(this.eventLoopPressure=!1,this.recoveredLagTicks=0,this.pump())),this.monitorTimer=window.setTimeout(e,Sc)};this.monitorTimer=window.setTimeout(e,Sc)}installVisibilityAndInputListeners(){const e=()=>{document.visibilityState==="visible"&&this.pump()},n=()=>{this.lastUserInputAt=Date.now(),this.userInputHoldTimer!==null&&window.clearTimeout(this.userInputHoldTimer),this.userInputHoldTimer=window.setTimeout(()=>{this.userInputHoldTimer=null,this.pump()},Gm)};document.addEventListener("visibilitychange",e),window.addEventListener("focus",e),window.addEventListener("pointerdown",n,{passive:!0}),window.addEventListener("keydown",n,{passive:!0})}}const Km=new rJ,lJ=["api_key","apikey","token","secret","password","authorization","credential","private_key","privatekey"],cJ=["pcm16base64","pcm16_base64"],dJ=new Set(["env","headers","customheaders","extraheaders"]),uJ=new Set(["content","error","message","prompt","text","userMessage","userPrompt"].map(cd));function cd(i){return i.toLowerCase().replace(/[^a-z0-9]/g,"")}function Qm(i){const e=i.toLowerCase();return lJ.some(n=>e.includes(n))}function Jm(i){const e=i.toLowerCase();return cJ.some(n=>e.includes(n))}function pJ(i){return dJ.has(cd(i))}function mJ(i){return uJ.has(cd(i))}function Ym(i){return"***"}function qc(i){return i==null?i:Array.isArray(i)?i.map(qc):typeof i!="object"?"***":Object.fromEntries(Object.entries(i).map(([e,n])=>[e,qc(n)]))}function Zm(i){return typeof i!="string"?"[redacted payload]":`[redacted payload: ${i.length} chars]`}function ys(i,e){if(i==null)return i;if(Array.isArray(i))return i.map(s=>ys(s,e));if(typeof i!="object")return e&&Qm(e)?Ym():e&&Jm(e)?Zm(i):i;const n={};for(const[s,r]of Object.entries(i)){if(Qm(s)||mJ(s)){n[s]=Ym();continue}if(Jm(s)){n[s]=Zm(r);continue}if(pJ(s)){n[s]=qc(r);continue}n[s]=ys(r,s)}return n}const So=ft("ApiClient");function gJ(i){if(i instanceof Error)return i.message;if(typeof i=="string")return i;if(i&&typeof i=="object"){const e=i;if(typeof e.code=="string")return e.code;if(typeof e.message=="string")return e.message}return"Unknown error"}function _o(i,e="client.operation_failed"){if(i&&typeof i=="object"){const n=i.code;if(typeof n=="string"&&n.trim())return n}return e}class hJ{config;activeRequests=new Map;stats={totalRequests:0,successfulRequests:0,failedRequests:0,averageResponseTime:0,activeRequests:0};responseTimes=[];adapter;constructor(e={}){this.config={timeout:3e4,retries:0,retryDelay:1e3,enableLogging:!1,middleware:[],...e},this.adapter=KQ()}async invoke(e,n,s){const r={command:e,args:n,...this.config,...s},c=this.createRequest("tauri",r);return this.executeRequest(c)}async request(e){const n={...this.config,...e},s=this.createRequest("http",n);return this.executeRequest(s)}cancelAll(){this.activeRequests.forEach(e=>{e.abort()}),this.activeRequests.clear()}listen(e,n){try{return this.adapter.listen(e,n)}catch(s){return So.error("Failed to listen to event",{event:e,code:_o(s)}),()=>{}}}async listenReady(e,n){try{return this.adapter.listenReady?await this.adapter.listenReady(e,n):this.adapter.listen(e,n)}catch(s){return So.error("Failed to listen to event",{event:e,code:_o(s)}),()=>{}}}async healthCheck(){try{return this.adapter.isConnected()||await this.adapter.connect(),await this.invoke("ping",{},{timeout:5e3,retries:1}),!0}catch{return!1}}getStats(){return{...this.stats}}getAdapter(){return this.adapter}createRequest(e,n){return{id:`${e}-${Date.now()}-${Math.random()}`,type:e,config:n,timestamp:new Date,retryCount:0}}async executeRequest(e){const n=Date.now();this.updateStats({totalRequests:this.stats.totalRequests+1});try{const s=new AbortController;this.activeRequests.set(e.id,s);const r=setTimeout(()=>{s.abort()},e.config.timeout||this.config.timeout);try{const c=await this.applyMiddleware(e,async m=>m.type==="tauri"?this.executeTauriCommand(m.config):this.executeHttpRequest(m.config,s.signal));clearTimeout(r),this.activeRequests.delete(e.id);const u=Date.now()-n;return this.recordResponseTime(u),Km.diagnostics.recordApiCall({command:this.describeRequest(e),durationMs:u,status:"completed",timestamp:Date.now()}),this.updateStats({successfulRequests:this.stats.successfulRequests+1}),this.config.enableLogging&&So.debug("Request completed",{type:e.type,responseTime:u,config:ys(e.config)}),c.data}finally{clearTimeout(r),this.activeRequests.delete(e.id)}}catch(s){if(Km.diagnostics.recordApiCall({command:this.describeRequest(e),durationMs:Date.now()-n,status:"failed",timestamp:Date.now()}),this.updateStats({failedRequests:this.stats.failedRequests+1}),e.retryCount<(e.config.retries||this.config.retries)){const r=(e.config.retryDelay||this.config.retryDelay)*Math.pow(2,e.retryCount);return this.config.enableLogging&&So.warn("Retrying request",{requestId:e.id,attempt:e.retryCount+1,maxRetries:e.config.retries||this.config.retries,delay:r}),await new Promise(c=>setTimeout(c,r)),e.retryCount++,this.executeRequest(e)}throw this.config.enableLogging&&So.error("Request failed after retries",{requestId:e.id,retryCount:e.retryCount,config:ys(e.config),code:_o(s)}),this.normalizeError(s)}}async executeTauriCommand(e){try{return{success:!0,data:await this.adapter.request(e.command,e.args||{}),timestamp:new Date}}catch(n){const s=gJ(n);throw(s.includes("not found")||s.includes("Config path")||s.includes("Configuration error"))&&this.config.enableLogging?So.debug("Command returned expected result",{command:e.command,code:_o(n,"command.expected_failure")}):So.error("Command failed",{command:e.command,args:ys(e.args),code:_o(n,"command.failed")}),this.createApiError("COMMAND_FAILED",s,n)}}describeRequest(e){return e.type==="tauri"?`api:${e.config.command}`:`api:${e.config.method} ${e.config.url}`}async executeHttpRequest(e,n){try{const s=new URL(e.url,this.config.baseUrl);e.params&&Object.entries(e.params).forEach(([m,h])=>{s.searchParams.append(m,String(h))});const r={method:e.method,headers:{"Content-Type":"application/json",...e.headers},signal:n};e.data&&e.method!=="GET"&&(r.body=JSON.stringify(e.data));const c=await fetch(s.toString(),r);if(!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`);return{success:!0,data:await c.json(),timestamp:new Date}}catch(s){throw s.name==="AbortError"?this.createApiError("REQUEST_TIMEOUT","Request timeout",s):this.createApiError("HTTP_REQUEST_FAILED",s.message,s)}}async applyMiddleware(e,n){if(this.config.middleware.length===0)return n(e);let s=0;const r=async c=>{if(s>=this.config.middleware.length)return n(c);const u=this.config.middleware[s++];return u(c,r)};return r(e)}normalizeError(e){return this.isApiError(e)?e:this.createApiError("UNKNOWN_ERROR",e.message,e)}createApiError(e,n,s){const r=new Error(n);return r.code=e,r.message=n,s&&(r.details={originalErrorCode:_o(s,e)}),r}isApiError(e){return e&&typeof e.code=="string"}recordResponseTime(e){this.responseTimes.push(e),this.responseTimes.length>100&&(this.responseTimes=this.responseTimes.slice(-100));const n=this.responseTimes.reduce((s,r)=>s+r,0)/this.responseTimes.length;this.updateStats({averageResponseTime:Math.round(n)})}updateStats(e){this.stats={...this.stats,...e}}}const zt=new hJ,V={invoke:(i,e,n)=>zt.invoke(i,e,n),listen:(i,e)=>zt.listen(i,e),listenReady:(i,e)=>zt.listenReady(i,e),get:(i,e)=>zt.request({method:"GET",url:i,...e}),post:(i,e,n)=>zt.request({method:"POST",url:i,data:e,...n}),put:(i,e,n)=>zt.request({method:"PUT",url:i,data:e,...n}),delete:(i,e)=>zt.request({method:"DELETE",url:i,...e}),patch:(i,e,n)=>zt.request({method:"PATCH",url:i,data:e,...n}),cancelAll:()=>zt.cancelAll(),healthCheck:()=>zt.healthCheck(),getStats:()=>zt.getStats(),getAdapter:()=>zt.getAdapter()};function $ne(){const i=ft("ApiMiddleware");return async(e,n)=>{const s=Date.now();try{const r=await n(e),c=Date.now()-s;return i.debug("Request completed",{type:e.type,duration:c,config:ys(e.config)}),r}catch(r){const c=Date.now()-s;throw i.error("Request failed",{type:e.type,duration:c,code:_o(r)}),r}}}function One(i=3,e=1e3){const n=ft("ApiRetryMiddleware");return async(s,r)=>{let c;for(let u=0;u<=i;u++)try{return await r(s)}catch(m){if(c=m,usetTimeout(f,h))}}throw c}}class dd extends Error{context;isTauriCommandError=!0;constructor(e,n){super(e),this.name="TauriCommandError",this.context={...n,timestamp:new Date().toISOString()},Error.captureStackTrace&&Error.captureStackTrace(this,dd)}getFormattedMessage(){const{command:e,request:n,originalError:s,timestamp:r}=this.context;let c=`[${r}] Tauri command failed: ${e} +`;return c+=`Error message: ${this.message} +`,n&&(c+=`Request payload: ${JSON.stringify(n,null,2)} +`),s&&(c+=`Original error: ${s.message||s} +`),c}isNetworkError(){const e=this.message.toLowerCase();return e.includes("network")||e.includes("connection")||e.includes("timeout")||e.includes("fetch")}isPermissionError(){const e=this.message.toLowerCase();return e.includes("permission")||e.includes("access")||e.includes("unauthorized")||e.includes("forbidden")}isParameterError(){const e=this.message.toLowerCase();return e.includes("parameter")||e.includes("argument")||e.includes("invalid")||e.includes("missing")}}function J(i,e,n){let s="Unknown error";return e?.message?s=e.message:typeof e=="string"&&(s=e),new dd(s,{command:i,request:n,originalError:e})}const qa=ft("WorkspaceAPI"),fJ="file-search://progress",yJ="file-search://complete",wJ="file-search://error";function Xm(i){const e=new Map;for(const n of i){const s=e.get(n.path);if(s){n.matchType==="fileName"?s.fileNameMatch=n:s.contentMatches.push(n);continue}e.set(n.path,{path:n.path,name:n.name,isDirectory:n.isDirectory,fileNameMatch:n.matchType==="fileName"?n:void 0,contentMatches:n.matchType==="content"?[n]:[]})}return Array.from(e.values())}class vJ{async openWorkspace(e){try{return await V.invoke("open_workspace",{request:{path:e}})}catch(n){throw J("open_workspace",n,{path:e})}}async closeWorkspace(){try{await V.invoke("close_workspace",{request:{}})}catch(e){throw J("close_workspace",e)}}async getWorkspaceInfo(){try{return await V.invoke("get_workspace_info",{request:{}})}catch(e){throw J("get_workspace_info",e)}}async listFiles(e){try{return await V.invoke("list_files",{request:{path:e}})}catch(n){throw J("list_files",n,{path:e})}}async readFile(e){try{return await V.invoke("read_file",{request:{path:e}})}catch(n){throw J("read_file",n,{path:e})}}async writeFile(e,n){try{await V.invoke("write_file",{request:{path:e,content:n}})}catch(s){throw J("write_file",s,{path:e,content:n})}}async writeFileContent(e,n,s){try{await V.invoke("write_file_content",{request:{workspacePath:e,filePath:n,content:s}})}catch(r){throw J("write_file_content",r,{workspacePath:e,filePath:n,content:s})}}async createFile(e){try{await V.invoke("create_file",{request:{path:e}})}catch(n){throw J("create_file",n,{path:e})}}async deleteFile(e){try{await V.invoke("delete_file",{request:{path:e}})}catch(n){throw J("delete_file",n,{path:e})}}async createDirectory(e){try{await V.invoke("create_directory",{request:{path:e}})}catch(n){throw J("create_directory",n,{path:e})}}async deleteDirectory(e,n=!0){try{await V.invoke("delete_directory",{request:{path:e,recursive:n}})}catch(s){throw J("delete_directory",s,{path:e,recursive:n})}}async getFileTree(e,n){try{return await V.invoke("get_file_tree",{request:{path:e,maxDepth:n}})}catch(s){throw J("get_file_tree",s,{path:e,maxDepth:n})}}async getDirectoryChildren(e){try{return await V.invoke("get_directory_children",{request:{path:e}})}catch(n){throw J("get_directory_children",n,{path:e})}}async getDirectoryChildrenPaginated(e,n=0,s=100){try{return await V.invoke("get_directory_children_paginated",{request:{path:e,offset:n,limit:s}})}catch(r){throw J("get_directory_children_paginated",r,{path:e,offset:n,limit:s})}}async explorerGetChildren(e){try{return await V.invoke("explorer_get_children",{request:{path:e}})}catch(n){throw J("explorer_get_children",n,{path:e})}}async readFileContent(e,n){try{return await V.invoke("read_file_content",{request:{filePath:e,encoding:n}})}catch(s){throw J("read_file_content",s,{filePath:e,encoding:n})}}async getFileMetadata(e){try{const n=await V.invoke("get_file_metadata",{request:{path:e}});return{path:String(n.path??e),resolvedPath:typeof n.resolvedPath=="string"?n.resolvedPath:void 0,modified:Number(n.modified??0),size:Number(n.size??0),isFile:n.isFile===!0,isDir:n.isDir===!0,isRuntimeArtifact:typeof n.isRuntimeArtifact=="boolean"?n.isRuntimeArtifact:void 0}}catch(n){throw J("get_file_metadata",n,{path:e})}}createSearchId(e){return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}async cancelSearch(e){if(e)try{await V.invoke("cancel_search",{request:{searchId:e}})}catch(n){qa.warn("Failed to cancel search",{searchId:e,error:n})}}async raceCancelable(e,n,s,r){if(!r)return n;if(r.aborted)throw await this.cancelSearch(s),new DOMException("Search aborted","AbortError");return await Promise.race([n,new Promise((c,u)=>{const m=()=>{this.cancelSearch(s),u(new DOMException(`${e} aborted`,"AbortError"))};r.addEventListener("abort",m,{once:!0})})])}supportsSearchStreamEvents(){return typeof window<"u"&&("__TAURI_INTERNALS__"in window||"__TAURI__"in window)}async runSearchStream(e,n,s,r={},c){if(!this.supportsSearchStreamEvents())throw new Error(`Search streaming is unavailable for ${n} searches outside Tauri`);if(c?.aborted)throw await this.cancelSearch(s.searchId),new DOMException(`${e} aborted`,"AbortError");const{listen:u}=await Xt(async()=>{const{listen:m}=await Promise.resolve().then(()=>qQ);return{listen:m}},void 0);return await new Promise((m,h)=>{let f=!1;const y=[],v=()=>{for(;y.length>0;){const F=y.pop();try{F?.()}catch(_){qa.warn("Failed to cleanup search stream listener",{searchId:s.searchId,searchKind:n,error:_})}}},b=F=>{f||(f=!0,v(),m(F))},S=F=>{f||(f=!0,v(),h(F))},A=()=>{this.cancelSearch(s.searchId),S(new DOMException(`${e} aborted`,"AbortError"))};c&&(c.addEventListener("abort",A,{once:!0}),y.push(()=>{c.removeEventListener("abort",A)})),(async()=>{y.push(await u(fJ,F=>{const _=F.payload;_.searchId!==s.searchId||_.searchKind!==n||r.onProgress?.(_)})),y.push(await u(yJ,F=>{const _=F.payload;_.searchId!==s.searchId||_.searchKind!==n||b(_)})),y.push(await u(wJ,F=>{const _=F.payload;_.searchId!==s.searchId||_.searchKind!==n||S(new Error(_.error))})),await V.invoke(e,{request:s})})().catch(F=>{S(J(e,F,{rootPath:s.rootPath,pattern:s.pattern,searchId:s.searchId,searchKind:n}))})})}async searchFiles(e,n,s=!0,r=!1,c=!1,u=!1,m,h,f,y){const v=m??this.createSearchId(s?"legacy-content":"legacy-filenames");try{const b=V.invoke("search_files",{request:{rootPath:e,pattern:n,searchContent:s,searchId:v,caseSensitive:r,useRegex:c,wholeWord:u,maxResults:h,includeDirectories:f}});return await this.raceCancelable("search_files",b,v,y)}catch(b){throw b instanceof DOMException&&b.name==="AbortError"?b:J("search_files",b,{rootPath:e,pattern:n,searchContent:s,searchId:v,caseSensitive:r,useRegex:c,wholeWord:u,maxResults:h,includeDirectories:f})}}async searchFilenamesOnly(e,n,s=!1,r=!1,c=!1,u,m,h=!0,f){return(await this.searchFilenamesOnlyDetailed(e,n,s,r,c,u,m,h,f)).results}async searchFilenamesOnlyDetailed(e,n,s=!1,r=!1,c=!1,u,m,h=!0,f){const y=u instanceof AbortSignal?u:f,v=typeof u=="string"?u:this.createSearchId("filenames");try{const b=V.invoke("search_filenames",{request:{rootPath:e,pattern:n,searchId:v,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m,includeDirectories:h}});return await this.raceCancelable("search_filenames",b,v,y)}catch(b){throw b instanceof DOMException&&b.name==="AbortError"?b:J("search_filenames",b,{rootPath:e,pattern:n,searchId:v,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m,includeDirectories:h})}}async searchFilenamesOnlyStreamDetailed(e,n,s=!1,r=!1,c=!1,u,m,h=!0,f={},y){const v=u instanceof AbortSignal?u:y,b=typeof u=="string"?u:this.createSearchId("filenames");if(!this.supportsSearchStreamEvents()){const S=await this.searchFilenamesOnlyDetailed(e,n,s,r,c,b,m,h,v),A=Xm(S.results),F={searchId:b,searchKind:"filenames",limit:S.limit,truncated:S.truncated,totalResults:A.length};return A.length>0&&f.onProgress?.({searchId:b,searchKind:"filenames",results:A}),F}return await this.runSearchStream("start_search_filenames_stream","filenames",{rootPath:e,pattern:n,searchId:b,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m,includeDirectories:h},f,v)}async searchContentOnly(e,n,s=!1,r=!1,c=!1,u,m,h){return(await this.searchContentOnlyDetailed(e,n,s,r,c,u,m,h)).results}async searchContentOnlyDetailed(e,n,s=!1,r=!1,c=!1,u,m,h){const f=u instanceof AbortSignal?u:h,y=typeof u=="string"?u:this.createSearchId("content");try{const v=V.invoke("search_file_contents",{request:{rootPath:e,pattern:n,searchId:y,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m}});return await this.raceCancelable("search_file_contents",v,y,f)}catch(v){throw v instanceof DOMException&&v.name==="AbortError"?v:J("search_file_contents",v,{rootPath:e,pattern:n,searchId:y,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m})}}async searchContentOnlyStreamDetailed(e,n,s=!1,r=!1,c=!1,u,m,h={},f){const y=u instanceof AbortSignal?u:f,v=typeof u=="string"?u:this.createSearchId("content");if(!this.supportsSearchStreamEvents()){const b=await this.searchContentOnlyDetailed(e,n,s,r,c,v,m,y),S=Xm(b.results),A={searchId:v,searchKind:"content",limit:b.limit,truncated:b.truncated,totalResults:S.length};return S.length>0&&h.onProgress?.({searchId:v,searchKind:"content",results:S}),A}return await this.runSearchStream("start_search_file_contents_stream","content",{rootPath:e,pattern:n,searchId:v,caseSensitive:s,useRegex:r,wholeWord:c,maxResults:m},h,y)}async renameFile(e,n){try{await V.invoke("rename_file",{request:{oldPath:e,newPath:n}})}catch(s){throw J("rename_file",s,{oldPath:e,newPath:n})}}async exportLocalFileToPath(e,n){try{await V.invoke("export_local_file_to_path",{request:{sourcePath:e,destinationPath:n}})}catch(s){throw J("export_local_file_to_path",s,{sourcePath:e,destinationPath:n})}}async revealInExplorer(e){try{await V.invoke("reveal_in_explorer",{request:{path:e}})}catch(n){throw J("reveal_in_explorer",n,{path:e})}}async startFileWatch(e,n){try{await V.invoke("start_file_watch",{path:e,recursive:n})}catch(s){throw qa.error("Failed to start file watch",{path:e,recursive:n,error:s}),J("start_file_watch",s,{path:e,recursive:n})}}async stopFileWatch(e){try{await V.invoke("stop_file_watch",{path:e})}catch(n){throw qa.error("Failed to stop file watch",{path:e,error:n}),J("stop_file_watch",n,{path:e})}}async getWatchedPaths(){try{return await V.invoke("get_watched_paths",{})}catch(e){throw J("get_watched_paths",e)}}async getClipboardFiles(){try{return await V.invoke("get_clipboard_files")}catch(e){throw J("get_clipboard_files",e)}}async pasteFiles(e,n,s=!1){try{return await V.invoke("paste_files",{request:{sourcePaths:e,targetDirectory:n,isCut:s}})}catch(r){throw J("paste_files",r,{sourcePaths:e,targetDirectory:n,isCut:s})}}}const Bne=new vJ;class bJ{async getConfigStartupStatus(){try{return await V.invoke("get_config_startup_status",{request:{}})}catch(e){throw J("get_config_startup_status",e)}}async rebuildDefaultConfig(){try{return await V.invoke("rebuild_default_config",{request:{}})}catch(e){throw J("rebuild_default_config",e)}}async describeConfigCatalog(e){try{return await V.invoke("describe_config_catalog",{request:e})}catch(n){throw J("describe_config_catalog",n,{scope:e.scope,query:e.query})}}async getConfigSnapshot(e){try{return await V.invoke("get_config_snapshot",{request:e})}catch(n){throw J("get_config_snapshot",n,{scope:e.scope})}}async planConfigPatch(e){try{return await V.invoke("plan_config_patch",{request:e})}catch(n){throw J("plan_config_patch",n,{requestId:e.requestId,expectedRevision:e.expectedRevision,settingIds:e.operations.map(s=>s.settingId)})}}async commitConfigPatch(e){try{return await V.invoke("commit_config_patch",{request:e})}catch(n){throw J("commit_config_patch",n,{planId:e.planId,expectedRevision:e.expectedRevision,confirmed:e.confirmed})}}async undoConfigCommit(e){try{return await V.invoke("undo_config_commit",{request:e})}catch(n){throw J("undo_config_commit",n,{commitId:e.commitId,expectedRevision:e.expectedRevision,confirmed:e.confirmed})}}async getConfigCommit(e){try{return await V.invoke("get_config_commit",{request:{commitId:e}})}catch(n){throw J("get_config_commit",n,{commitId:e})}}async retryConfigApply(e){try{return await V.invoke("retry_config_apply",{request:e})}catch(n){throw J("retry_config_apply",n,{commitId:e.commitId,consumer:e.consumer,expectedAttempt:e.expectedAttempt})}}onConfigCommitted(e){return V.listen("config://committed",e)}onConfigSnapshotRefreshed(e){return V.listen("config://snapshot-refreshed",e)}onConfigRolledBack(e){return V.listen("config://rolled-back",e)}onConfigApplyStatus(e){return V.listen("config://apply-status",e)}async getRuntimeLoggingInfo(){try{return await V.invoke("get_runtime_logging_info",{request:{}})}catch(e){throw J("get_runtime_logging_info",e)}}async getSkillConfigs({forceRefresh:e,workspacePath:n}={}){try{return await V.invoke("get_skill_configs",{forceRefresh:e,workspacePath:n})}catch(s){throw J("get_skill_configs",s,{forceRefresh:e,workspacePath:n})}}async getAgentSkillConfigs({agentId:e,forceRefresh:n,workspacePath:s}){try{return await V.invoke("get_agent_skill_configs",{agentId:e,forceRefresh:n,workspacePath:s})}catch(r){throw J("get_agent_skill_configs",r,{agentId:e,forceRefresh:n,workspacePath:s})}}async setAgentSkillDisabled({agentId:e,skillKey:n,disabled:s,workspacePath:r}){try{return await V.invoke("set_agent_skill_disabled",{agentId:e,skillKey:n,disabled:s,workspacePath:r})}catch(c){throw J("set_agent_skill_disabled",c,{agentId:e,skillKey:n,disabled:s,workspacePath:r})}}async setAgentSkillSuiteDisabled({agentId:e,suiteKey:n,disabled:s,workspacePath:r}){try{return await V.invoke("set_agent_skill_suite_disabled",{request:{agentId:e,suiteKey:n,disabled:s,workspacePath:r}})}catch(c){throw J("set_agent_skill_suite_disabled",c,{agentId:e,suiteKey:n,disabled:s,workspacePath:r})}}async replaceAgentSkillSelection({agentId:e,enabledSkillKeys:n,enabledSuiteKeys:s,workspacePath:r}){try{return await V.invoke("replace_agent_skill_selection",{request:{agentId:e,enabledSkillKeys:n,enabledSuiteKeys:s,workspacePath:r}})}catch(c){throw J("replace_agent_skill_selection",c,{agentId:e,enabledSkillKeys:n,enabledSuiteKeys:s,workspacePath:r})}}async validateSkillPackagePath(e){try{return await V.invoke("validate_skill_package_path",{path:e})}catch(n){throw J("validate_skill_package_path",n,{path:e})}}async addSkillPackage({sourcePath:e,level:n,workspacePath:s}){try{return await V.invoke("add_skill_package",{request:{sourcePath:e,level:n,workspacePath:s}})}catch(r){throw J("add_skill_package",r,{sourcePath:e,level:n,workspacePath:s})}}async deleteSkillPackage({kind:e,key:n,workspacePath:s}){try{return await V.invoke("delete_skill_package",{request:{kind:e,key:n,workspacePath:s}})}catch(r){throw J("delete_skill_package",r,{kind:e,key:n,workspacePath:s})}}async listSkillMarket(e,n){try{return await V.invoke("list_skill_market",{request:{query:e,limit:n}})}catch(s){throw J("list_skill_market",s,{query:e,limit:n})}}async searchSkillMarket(e,n){try{return await V.invoke("search_skill_market",{request:{query:e,limit:n}})}catch(s){throw J("search_skill_market",s,{query:e,limit:n})}}async downloadSkillMarket({packageId:e,level:n="project",workspacePath:s}){try{return await V.invoke("download_skill_market",{request:{package:e,level:n,workspacePath:s}})}catch(r){throw J("download_skill_market",r,{package:e,level:n,workspacePath:s})}}}const _i=new bJ,eg=ft("ToolAPI");class kJ{async getAllToolsInfo(){try{return await V.invoke("get_all_tools_info")}catch(e){throw J("get_all_tools_info",e)}}async getToolInfo(e){try{return await V.invoke("get_tool_info",{request:{toolName:e}})}catch(n){throw J("get_tool_info",n,{toolName:e})}}async validateToolInput(e){try{return await V.invoke("validate_tool_input",{request:e})}catch(n){throw J("validate_tool_input",n,e)}}async executeTool(e){try{return await V.invoke("execute_tool",{request:{toolName:e.toolName,input:e.parameters,workspacePath:e.workspacePath,sessionId:e.sessionId,dialogTurnId:e.dialogTurnId,agentType:e.agentType,context:e.context}})}catch(n){throw J("execute_tool",n,e)}}async isToolEnabled(e){try{return await V.invoke("is_tool_enabled",{request:{toolName:e}})}catch(n){throw J("is_tool_enabled",n,{toolName:e})}}async confirmToolExecution(e){try{const n=e.action||"confirm";if(n==="confirm"){const s={sessionId:e.sessionId,toolId:e.toolId,...e.updatedInput===void 0?{}:{updatedInput:e.updatedInput}};return await V.invoke("confirm_tool_execution",{request:s})}else if(n==="reject"){const s={sessionId:e.sessionId,toolId:e.toolId,reason:"User rejected"};return await V.invoke("reject_tool_execution",{request:s})}else throw new Error(`Unknown action type: ${n}`)}catch(n){throw eg.error("Tool confirmation/rejection failed",{action:e.action,sessionId:e.sessionId,toolId:e.toolId,error:n}),J(e.action==="reject"?"reject_tool_execution":"confirm_tool_execution",n,e)}}async cancelToolExecution(e){try{return await V.invoke("cancel_tool_execution",{request:{abortControllerId:e}})}catch(n){throw J("cancel_tool_execution",n,{abortControllerId:e})}}async submitUserAnswers(e,n){try{await V.invoke("submit_user_answers",{toolId:e,answers:n})}catch(s){throw eg.error("Failed to submit user answers",{toolId:e,error:s}),J("submit_user_answers",s,{toolId:e,answers:n})}}}const Wne=new kJ;async function SJ(i,e){await Ss("plugin:opener|open_url",{url:i,with:e})}async function xJ(i,e){await Ss("plugin:opener|open_path",{path:i,with:e})}async function CJ(){return await Ss("plugin:autostart|is_enabled")}async function AJ(){await Ss("plugin:autostart|enable")}async function _J(){await Ss("plugin:autostart|disable")}const pi=ft("SystemAPI");class TJ{async getSystemInfo(){try{return await V.invoke("get_system_info",{request:{}})}catch(e){throw J("get_system_info",e)}}async getMainWindowCloseIntent(){try{return await V.invoke("get_main_window_close_intent",{request:{}})}catch(e){throw J("get_main_window_close_intent",e)}}async getAppVersion(){try{return await V.invoke("get_app_version",{request:{}})}catch(e){throw J("get_app_version",e)}}async checkForUpdates(){try{return await V.invoke("check_for_updates",{request:{}})}catch(e){throw J("check_for_updates",e)}}async openExternal(e){try{await SJ(e)}catch(n){throw pi.error("Failed to open external URL",{url:e,error:n}),new Error(`Failed to open external URL: ${n}`)}}async openPath(e){try{await xJ(e)}catch(n){throw pi.error("Failed to open external path",{path:e,error:n}),new Error(`Failed to open external path: ${n}`)}}async showInFolder(e){try{await V.invoke("show_in_folder",{request:{path:e}})}catch(n){throw J("show_in_folder",n,{path:e})}}async checkPathExists(e){try{return await V.invoke("check_path_exists",{request:{path:e}})}catch(n){throw J("check_path_exists",n,{path:e})}}async getClipboard(){try{return await V.invoke("get_clipboard",{request:{}})}catch(e){throw J("get_clipboard",e)}}async setClipboard(e){try{await V.invoke("set_clipboard",{request:{text:e}})}catch(n){throw J("set_clipboard",n,{text:e})}}async checkCommandExists(e){try{return await V.invoke("check_command_exists",{command:e})}catch(n){throw J("check_command_exists",n,{command:e})}}async checkCommandsExist(e){try{return await V.invoke("check_commands_exist",{commands:e})}catch(n){throw J("check_commands_exist",n,{commands:e})}}async setMacosEditMenuMode(e){try{await V.invoke("set_macos_edit_menu_mode",{request:{mode:e}})}catch(n){throw J("set_macos_edit_menu_mode",n,{mode:e})}}async getLaunchAtLoginEnabled(){if(typeof window>"u"||!("__TAURI_INTERNALS__"in window||"__TAURI__"in window))return!1;try{return await CJ()}catch(e){throw pi.error("Failed to read launch-at-login state",e),J("autostart_is_enabled",e)}}async sendSystemNotification(e,n){if(!(typeof window>"u"||!("__TAURI_INTERNALS__"in window||"__TAURI__"in window)))try{await V.invoke("send_system_notification",{request:{title:e,body:n??null}})}catch(s){pi.warn("Failed to send system notification",{title:e,error:s})}}async setLaunchAtLoginEnabled(e){if(!(typeof window>"u"||!("__TAURI_INTERNALS__"in window||"__TAURI__"in window)))try{e?await AJ():await _J()}catch(n){throw pi.error("Failed to set launch-at-login",{enabled:e,error:n}),J("autostart_set",n,{enabled:e})}}}const zne=new TJ,ud=["bitfun-coder","bitfun-plan","bitfun-debug","bitfun-team"],mn=(i,e=[i],n=i)=>({defaultAgentId:i,activeAgentId:n,switchableAgentIds:[...e]}),dt={agenticOs:{hostKind:"system-agentic-os",profileId:"agentic-os",identityId:"agentic-os",labelKey:"apps.agenticOs.name",agentPolicy:mn("OSAgent"),sessionDomainKind:"os_agent"},runno:{hostKind:"agent-component",profileId:"runno",identityId:"runno",labelKey:"apps.runno.name",agentPolicy:mn("Runno"),sessionDomainKind:"workspace"},bitfunCoder:{hostKind:"agent-component",profileId:"bitfun-coder",identityId:"bitfun-coder",labelKey:"apps.bitfunCoder.name",agentPolicy:mn("bitfun-coder",ud),sessionDomainKind:"workspace"},cowork:{hostKind:"agent-component",profileId:"cowork",identityId:"cowork",labelKey:"apps.cowork.name",agentPolicy:mn("Cowork"),sessionDomainKind:"workspace"},design:{hostKind:"agent-component",profileId:"design",identityId:"design",labelKey:"apps.design.name",agentPolicy:mn("Design"),sessionDomainKind:"workspace"},deepResearch:{hostKind:"agent-component",profileId:"deep-research",identityId:"deep-research",labelKey:"apps.deepResearch.name",agentPolicy:mn("DeepResearch"),sessionDomainKind:"workspace"},appBuilder:{hostKind:"evolution-lab",profileId:"app-builder",identityId:"app-builder",labelKey:"apps.appBuilder.name",agentPolicy:mn("AppBuilder"),sessionDomainKind:"global"},settings:{hostKind:"system-settings",profileId:"settings",identityId:"settings",labelKey:"settings/ai-mode:session.title",agentPolicy:mn("SettingsAgent"),sessionDomainKind:"global"},productAppRuntime:{hostKind:"product-app-runtime",profileId:"product-app-runtime",identityId:"product-app-runtime",labelKey:"apps.productAppRuntime.name",agentPolicy:mn("Runno"),sessionDomainKind:"workspace"}};function PJ(i,e){return i.length===e.length&&i.every((n,s)=>n===e[s])}function tg(i){return ud.includes(i)}const it=(i,e=i.agentPolicy.activeAgentId)=>({...i,agentPolicy:{...i.agentPolicy,activeAgentId:e,switchableAgentIds:[...i.agentPolicy.switchableAgentIds]}});function Vg(){return it(dt.runno)}function hi(i){return i.profileId==="bitfun-coder"&&i.identityId==="bitfun-coder"&&i.agentPolicy.defaultAgentId===dt.bitfunCoder.agentPolicy.defaultAgentId&&tg(i.agentPolicy.activeAgentId)&&i.agentPolicy.switchableAgentIds.every(tg)&&!PJ(i.agentPolicy.switchableAgentIds,ud)?{...it(dt.bitfunCoder,i.agentPolicy.activeAgentId),sessionDomainKind:i.sessionDomainKind}:it(i)}function FJ(){return it(dt.agenticOs)}function RJ(i){return i?.chat?.agentType?.trim()||void 0}function NJ(i){const e=i?.trim();return e?{...it(dt.productAppRuntime,e),agentPolicy:mn(e)}:it(dt.productAppRuntime)}function DJ(i){const n=i?.trim()?.toLowerCase();return n==="osagent"||n==="os-agent"||n==="os_agent"||n==="dispatcher"?FJ():n==="cowork"?it(dt.cowork):n==="design"?it(dt.design):n==="deepresearch"?it(dt.deepResearch):n==="runno"?it(dt.runno):n==="appbuilder"||n==="app-builder"||n==="app_builder"?it(dt.appBuilder):n==="settingsagent"||n==="settings-agent"||n==="settings_agent"?it(dt.settings):n==="productappruntime"||n==="product-app-runtime"?it(dt.productAppRuntime):n==="bitfun-coder"?it(dt.bitfunCoder):n==="bitfun-plan"?it(dt.bitfunCoder,"bitfun-plan"):n==="bitfun-debug"?it(dt.bitfunCoder,"bitfun-debug"):n==="bitfun-team"?it(dt.bitfunCoder,"bitfun-team"):null}function IJ(i){return DJ(i)??Vg()}function Zn(i){return i?.agentPolicy.activeAgentId||i?.agentPolicy.defaultAgentId||"Runno"}function Va(i,e){if(i.sessionDomainKind==="workspace"){const n=e?.trim();if(!n)throw new Error(`Workspace session ${i.profileId} requires workspaceId`);return{kind:"workspace",workspace_id:n}}return{kind:i.sessionDomainKind}}function MJ(i,e){const n=hi(i),s=n.agentPolicy.switchableAgentIds.includes(e)?e:n.agentPolicy.defaultAgentId;return it(n,s)}function ws(i){return typeof i=="string"&&i.trim()?i.trim():void 0}function Gg(i){if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){const e=Number(i);return Number.isFinite(e)?e:void 0}}function pd(i){return i==="btw"||i==="internal"?i:"normal"}function fi(i){const e=pd(i?.sessionKind),n=ws(i?.btwOrigin?.parentSessionId??i?.parentSessionId);if(e!=="btw")return{sessionKind:e,parentSessionId:void 0,btwOrigin:void 0};const s={requestId:ws(i?.btwOrigin?.requestId),parentSessionId:n,parentDialogTurnId:ws(i?.btwOrigin?.parentDialogTurnId),parentTurnIndex:Gg(i?.btwOrigin?.parentTurnIndex)};return{sessionKind:e,parentSessionId:n,btwOrigin:s}}function jJ(i){const e=i?.customMetadata,n=pd(e?.kind);return fi({sessionKind:n==="btw"?"normal":n,parentSessionId:e?.parentSessionId??void 0,btwOrigin:n==="btw"?{requestId:ws(e?.parentRequestId),parentSessionId:ws(e?.parentSessionId),parentDialogTurnId:ws(e?.parentDialogTurnId),parentTurnIndex:Gg(e?.parentTurnIndex)}:void 0})}function EJ(i){if(pd(i?.customMetadata?.kind)==="btw")return!0;const n=i?.tags;return Array.isArray(n)&&n.includes("btw")}function LJ(i){const e=i?.customMetadata?.lastFinishedAt;return typeof e=="number"&&Number.isFinite(e)?e:void 0}const $J=new Set(["pending","processing","finishing","image_analyzing","cancelling","inprogress"]),OJ=new Set(["pending","streaming","pending_confirmation"]),Kg=new Set(["pending","preparing","streaming","running","receiving","starting","analyzing"]),BJ=new Set(["completed","cancelled","error","pending_confirmation","confirmed"]);function WJ(i){return typeof i=="string"&&Kg.has(i)}function zJ(i){return i.error?!0:(i.modelRounds??[]).some(e=>e.status==="error"?!0:[...e.items??[],...e.toolItems??[],...e.textItems??[],...e.thinkingItems??[]].some(s=>s?.status==="error"||s?.toolResult?.success===!1||s?.tool_result?.success===!1))}function ng(i){return zJ(i)?"error":"cancelled"}function UJ(i,e){return i==="completed"||i==="cancelled"||i==="error"?i:(typeof i=="string"&&$J.has(i),ng(e))}function HJ(i,e){return i==="pending_confirmation"||i==="completed"||i==="cancelled"||i==="error"?i:typeof i=="string"&&OJ.has(i)&&(e==="completed"||e==="error"||e==="cancelled")?e:e==="completed"?"completed":e==="error"?"error":"cancelled"}function qJ(i,e){return i==="completed"||i==="cancelled"||i==="error"?i:e==="completed"?"completed":e==="error"?"error":"cancelled"}function VJ(i,e){return i==="completed"||i==="cancelled"||i==="error"?i:e==="completed"?"completed":e==="error"?"error":"cancelled"}function GJ(i,e,n,s){return i==="completed"||i==="cancelled"||i==="error"?i:e==="cancelled"?"cancelled":e==="error"?n?.success===!1&&n.error?"error":"cancelled":e==="completed"?n?.success===!1?"error":"completed":typeof i=="string"&&(Kg.has(i)||BJ.has(i))?"cancelled":n?.success===!1?"error":"cancelled"}function ms(i){return i==="completed"||i==="cancelled"||i==="error"}function md(i){return i.runtime?{...og(i),...i.runtime,result:i.runtime.result??i.toolResult?.result,error:i.runtime.error??i.toolResult?.error,startedAt:i.runtime.startedAt??i.startTime,endedAt:i.runtime.endedAt??i.endTime}:og(i)}function og(i){const e=i.status,n=i.toolResult!==void 0,s=i.toolCall?.input!==void 0?"parsed":"none",r=i.userConfirmed===!0?"approved":i.userConfirmed===!1||e==="rejected"?"rejected":i.requiresConfirmation||e==="pending_confirmation"?"required":"none";let c;return e==="pending"?c="pending":e==="preparing"||e==="streaming"||e==="receiving"?c="preparing":e==="pending_confirmation"?c="waiting_confirmation":e==="confirmed"?c="ready":e==="running"?c="running":e==="completed"?c="completed":e==="cancelled"||e==="rejected"?c="cancelled":e==="error"?c="error":c=n?i.toolResult?.success===!1?"error":"completed":"preparing",r==="rejected"&&(c="cancelled"),{lifecycle:c,inputPhase:s,confirmation:r,input:i.toolCall?.input,result:i.toolResult?.result,error:i.toolResult?.error,startedAt:i.startTime,endedAt:i.endTime}}function KJ(i,e){const n=QJ(i);return{...i,status:n,error:e.error??i.error,endTime:i.endTime??e.settledAt,modelRounds:i.modelRounds.map(s=>JJ(s,n,e))}}function QJ(i,e){return ms(i.status)?i.status:"cancelled"}function JJ(i,e,n){const s=i.items.some(c=>c.type==="tool"&&md(c).lifecycle==="waiting_confirmation"),r=n.preserveWaitingConfirmation&&s?"pending_confirmation":e;return{...i,status:r,isStreaming:!1,isComplete:!0,endTime:i.endTime??n.settledAt,items:i.items.map(c=>YJ(c,e,n))}}function YJ(i,e,n){if(i.type==="text")return{...i,status:ms(i.status)?i.status:e,isStreaming:!1};if(i.type==="thinking")return{...i,status:ms(i.status)?i.status:e,isStreaming:!1,isCollapsed:!0};if(i.type==="tool"){const s=i,r=md(s),u=n.preserveWaitingConfirmation&&r.lifecycle==="waiting_confirmation"&&n.reason!=="user_cancelled"?"pending_confirmation":ms(r.lifecycle)?r.lifecycle:e;return{...s,status:u,runtime:{...r,lifecycle:u==="pending_confirmation"?"waiting_confirmation":u,inputPhase:r.inputPhase==="streaming"?"parsed":r.inputPhase,partialInput:void 0,endedAt:s.endTime??n.settledAt},endTime:s.endTime??n.settledAt,interruptionReason:n.reason==="app_restart"&&u==="cancelled"?"app_restart":s.interruptionReason}}return{...i,status:ms(i.status)?i.status:e}}function sg(i){if(typeof i!="string")return i;let e=i.replace(/\\/g,"/");for(;e.includes("//");)e=e.replace("//","/");return e==="/"?e:e.replace(/\/+$/,"")}function ZJ(i){return typeof i!="string"?!1:/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(i)&&!i.startsWith("file://")}function ig(i){if(typeof i!="string"||ZJ(i))return i;let e=i.replace(/^file:\/+/,"");e=e.replace(/\\/g,"/"),e=e.replace(/^\/+([a-zA-Z]:)/,"$1"),e=e.replace(/^([a-z]):/,(n,s)=>s.toUpperCase()+":"),e=e.replace(/\/+/g,"/");try{const n=decodeURIComponent(e);n!==e&&(e=n)}catch{}return e}function XJ(i,e){return ig(i)===ig(e)}function Qg(i,e){const n=i.workspacePath||e;return XJ(n,e)||sg(n)===sg(e)}function eY(i,e){const n=i.workspaceId?.trim(),s=e.id?.trim();return n&&s&&n===s?!0:Qg(i,e.rootPath)}const tY=()=>({counters:{},measures:{}});function Jg(){return typeof window>"u"?null:(window.__flowChatPerf||(window.__flowChatPerf=tY()),window.__flowChatPerf)}function nY(i,e=1){const n=Jg();n&&(n.counters[i]=(n.counters[i]??0)+e)}function oY(i,e){const n=Jg();if(!n)return;const s=n.measures[i]??{count:0,totalMs:0,maxMs:0,lastMs:0};s.count+=1,s.totalMs+=e,s.maxMs=Math.max(s.maxMs,e),s.lastMs=e,n.measures[i]=s}function xc(i,e){const n=typeof performance<"u"?performance.now():Date.now();try{return e()}finally{const s=typeof performance<"u"?performance.now():Date.now();oY(i,s-n)}}const sY=new Set(["Read","LS"]),iY=new Set(["Grep","Glob","WebSearch"]),aY=new Set(["Bash"]);new Map([...Array.from(sY,i=>[i,"read"]),...Array.from(iY,i=>[i,"search"]),["WebFetch","fetch"],...Array.from(aY,i=>[i,"command"])]);const rY=new Map,lY=new Map;let cY={version:0};function dY(i){return i?i==="agenticOsTimeline"?cY.version:i.startsWith("taskExecution:")?lY.get(i.slice(14))?.version??0:rY.get(i)?.version??0:0}const et=ft("FlowChatStore");function ag(i,e){const n=i.customMetadata?.productAppRuntime;return n?NJ(RJ(n)):IJ(i.agentType||e)}function Cc(i,e){return i.hostKind===e.hostKind&&i.profileId===e.profileId&&i.identityId===e.identityId&&i.sessionDomainKind===e.sessionDomainKind&&i.agentPolicy.defaultAgentId===e.agentPolicy.defaultAgentId&&i.agentPolicy.activeAgentId===e.agentPolicy.activeAgentId&&i.agentPolicy.switchableAgentIds.length===e.agentPolicy.switchableAgentIds.length&&i.agentPolicy.switchableAgentIds.every((n,s)=>n===e.agentPolicy.switchableAgentIds[s])}const uY=(i,e)=>Object.is(i,e);function rg(i,e){if(i.runtime&&typeof i.runtime=="object")return i.runtime;const n=e==="pending_confirmation"?"waiting_confirmation":e==="confirmed"?"ready":e==="completed"||e==="cancelled"||e==="error"?e:e==="running"?"running":e==="pending"?"pending":"preparing";return{lifecycle:n,inputPhase:i.toolCall?.input!==void 0?"parsed":"none",confirmation:n==="waiting_confirmation"?"required":e==="confirmed"?"approved":"none",input:i.toolCall?.input,result:i.toolResult?.result,error:i.toolResult?.error,startedAt:i.startTime,endedAt:i.endTime}}class Po{static instance;state;listeners=new Set;toolItemIndex=new Map;metadataPreloadedWorkspaceScopes=new Set;warmedSessionIds=new Set;pendingSessionHistoryLoads=new Map;onPersistUnreadCompletion;silentMode=!1;constructor(){this.clearOldStorage(),this.state={sessions:new Map}}clearOldStorage(){try{["sparo-flow-chat-state","sparo-flow-chat-global","sparo-session-ids"].forEach(n=>{localStorage.getItem(n)&&localStorage.removeItem(n)}),Object.keys(localStorage).forEach(n=>{n.startsWith("sparo-session-")&&localStorage.removeItem(n)})}catch(e){et.warn("Failed to clear old storage data",e)}}static getInstance(){return Po.instance||(Po.instance=new Po),Po.instance}getState(){return this.state}getSessionHeader(e){const n=this.state.sessions.get(e);return n?{sessionId:n.sessionId,title:n.title,titleStatus:n.titleStatus,status:n.status,descriptor:n.descriptor,lastActiveAt:n.lastActiveAt,lastFinishedAt:n.lastFinishedAt,loadPhase:n.loadPhase,isTransient:n.isTransient,parentSessionId:n.parentSessionId,sessionKind:n.sessionKind,workspacePath:n.workspacePath,domain:n.domain}:null}setSessionLoadPhase(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r||r.loadPhase===n)return s;const c=new Map(s.sessions);return c.set(e,{...r,loadPhase:n}),{...s,sessions:c}})}getActiveTurnTail(e){const n=this.state.sessions.get(e),s=n?.dialogTurns[n.dialogTurns.length-1];if(!n||!s)return null;const r=s.modelRounds[s.modelRounds.length-1],c=r?.items[r.items.length-1],u=c&&(c.type==="text"||c.type==="thinking")?c.content??"":"";return{sessionId:e,turnId:s.id,turnStatus:s.status,roundId:r?.id,itemId:c?.id,itemType:c?.type,itemStatus:c?.status,contentLength:u.length}}getToolRuntime(e){const n=this.findToolItemLocation(e);if(!n||n.item.type!=="tool")return null;const s=n.item;return rg(s,s.status)}getProjectionVersion(e){return dY(e)}setState(e){const n=this.state,s=e(this.state);this.syncToolIndexForStateChange(n,s),this.state=s,this.silentMode||xc("store.notify",()=>this.listeners.forEach(r=>{try{r(s)}catch(c){console.error("[FlowChatStore] Listener threw an error, skipping:",c)}}))}setStateSilent(e){const n=this.silentMode;this.silentMode=!0;try{this.setState(e)}finally{this.silentMode=n}}notifyListeners(){xc("store.notify",()=>this.listeners.forEach(e=>{try{e(this.state)}catch(n){console.error("[FlowChatStore] Listener threw an error during notifyListeners, skipping:",n)}}))}beginSilentMode(){this.silentMode=!0}endSilentMode(){this.silentMode=!1,this.notifyListeners()}getWorkspaceScopeKey(e){return e.trim()}hasWorkspaceMetadataPreloaded(e){return this.metadataPreloadedWorkspaceScopes.has(this.getWorkspaceScopeKey(e))}markWorkspaceMetadataPreloaded(e){this.metadataPreloadedWorkspaceScopes.add(this.getWorkspaceScopeKey(e))}hasSessionHistoryWarmed(e){return this.warmedSessionIds.has(e)}markSessionHistoryWarmed(e){this.warmedSessionIds.add(e)}collectCascadeSessionIds(e,n){if(!n.has(e))return[];const s=new Map;n.forEach(m=>{const h=m.parentSessionId;if(!h)return;const f=s.get(h)||[];f.push(m.sessionId),s.set(h,f)});const r=new Set,c=[],u=m=>{if(r.has(m))return;r.add(m),(s.get(m)||[]).forEach(f=>{u(f)}),c.push(m)};return u(e),c}getCascadeSessionIds(e){return this.collectCascadeSessionIds(e,this.state.sessions)}subscribeSelector(e,n,s=uY){let r=e(this.state);const c=u=>{const m=xc("store.selector.compute",()=>e(u));s(r,m)||(r=m,n(m,u))};return nY("store.subscribe.selector"),this.listeners.add(c),()=>{this.listeners.delete(c)}}registerPersistUnreadCompletionCallback(e){this.onPersistUnreadCompletion=e}createSession(e,n,s,r,c,u=Vg(),m){const h=hi(u),f=n.domain??Va(h,n.workspaceId);Xt(async()=>{const{stateMachineManager:y}=await import("./index-C_s2NvXm.js");return{stateMachineManager:y}},[]).then(({stateMachineManager:y})=>{y.getOrCreate(e)}),this.setState(y=>{const v=fi({sessionKind:"normal"}),b={sessionId:e,title:r||ar.t("flow-chat:session.new"),titleStatus:void 0,dialogTurns:[],status:"idle",config:{...n,agentType:Zn(h)},createdAt:Date.now(),lastActiveAt:Date.now(),lastFinishedAt:void 0,error:null,loadPhase:"live",maxContextTokens:c,descriptor:h,workspacePath:m,workspaceId:n.workspaceId,domain:f,customMetadata:n.customMetadata,parentSessionId:v.parentSessionId,sessionKind:v.sessionKind,btwThreads:[],btwOrigin:v.btwOrigin,isTransient:!1},S=new Map(y.sessions);return S.set(e,b),{...y,sessions:S}})}addExternalSession(e,n,s,r,c,u){const m=hi(s),h=u??Va(m,void 0);Xt(async()=>{const{stateMachineManager:f}=await import("./index-C_s2NvXm.js");return{stateMachineManager:f}},[]).then(({stateMachineManager:f})=>{f.getOrCreate(e)}),this.setState(f=>{if(f.sessions.has(e))return f;const y=fi(c),v={sessionId:e,title:n||ar.t("flow-chat:session.new"),titleStatus:"generated",dialogTurns:[],status:"idle",config:{autoCompact:!0,enableTools:!0,agentType:Zn(m)},createdAt:Date.now(),lastActiveAt:Date.now(),lastFinishedAt:void 0,error:null,descriptor:m,loadPhase:"live",workspacePath:r,domain:h,customMetadata:c?.customMetadata,parentSessionId:y.parentSessionId,sessionKind:y.sessionKind,btwThreads:[],btwOrigin:y.btwOrigin,isTransient:c?.isTransient??!1},b=new Map(f.sessions);return b.set(e,v),{...f,sessions:b}})}switchSession(e){let n;this.setState(s=>{if(!s.sessions.has(e))return s;const r=s.sessions.get(e);n=r.descriptor;const c={...r,lastActiveAt:Date.now()},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}}),window.dispatchEvent(new CustomEvent("sparo:session-switched",{detail:{sessionId:e,descriptor:n}}))}reconcileSessionDescriptor(e,n,s,r){const c=hi(n);this.setState(u=>{const m=u.sessions.get(e);if(!m)return u;const h=Zn(c),f=s||m.workspacePath,y=r??Va(c,m.workspaceId);if(Cc(m.descriptor,c)&&m.config.agentType===h&&m.workspacePath===f&&m.domain.kind===y.kind&&(m.domain.kind!=="workspace"||y.kind==="workspace"&&m.domain.workspace_id===y.workspace_id))return u;const v={...m,descriptor:c,config:{...m.config,agentType:h},workspacePath:f,domain:y},b=new Map(u.sessions);return b.set(e,v),{...u,sessions:b}})}retargetEmptySessionWorkspace(e,n,s){const r=n.rootPath.trim();if(!r)return!1;const c=hi(s),u=Zn(c),m=Va(c,n.id);let h=!1;return this.setState(f=>{const y=f.sessions.get(e);if(!y||y.dialogTurns.length>0||y.isTransient||Cc(y.descriptor,c)&&y.config.agentType===u&&y.workspacePath===r&&y.workspaceId===n.id&&y.domain.kind==="workspace"&&y.domain.workspace_id===n.id&&y.config.workspacePath===r&&y.config.workspaceId===n.id)return f;const v={...y,descriptor:c,config:{...y.config,agentType:u,workspacePath:r,workspaceId:n.id,domain:m},workspacePath:r,workspaceId:n.id,domain:m,loadPhase:"live",lastActiveAt:Date.now()},b=new Map(f.sessions);return b.set(e,v),h=!0,{...f,sessions:b}}),h}updateSessionActiveAgent(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=MJ(r.descriptor,n),u=Zn(c);if(Cc(r.descriptor,c)&&r.descriptor.agentPolicy.activeAgentId===u&&r.config.agentType===u)return s;const m={...r,descriptor:c,config:{...r.config,agentType:u},lastActiveAt:Date.now()},h=new Map(s.sessions);return h.set(e,m),{...s,sessions:h}})}updateSessionModelName(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=n.trim()||"primary";if((r.config.modelName||"primary")===c)return s;const u={...r,config:{...r.config,modelName:c},currentContextBudget:void 0,maxContextTokens:void 0,lastActiveAt:Date.now()},m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}invalidateSessionContextBudget(e){this.setState(n=>{const s=n.sessions.get(e);if(!s||!s.currentContextBudget&&s.maxContextTokens===void 0)return n;const r=new Map(n.sessions);return r.set(e,{...s,currentContextBudget:void 0,maxContextTokens:void 0}),{...n,sessions:r}})}updateSessionRelationship(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=fi({sessionKind:n.sessionKind??r.sessionKind,parentSessionId:n.parentSessionId??r.parentSessionId,btwOrigin:r.btwOrigin}),u={...r,parentSessionId:c.parentSessionId,sessionKind:c.sessionKind,btwOrigin:c.btwOrigin},m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}updateSessionBtwOrigin(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=fi({sessionKind:"btw",parentSessionId:n?.parentSessionId??r.parentSessionId,btwOrigin:{...r.btwOrigin||{},...n||{}}}),u={...r,parentSessionId:c.parentSessionId,sessionKind:c.sessionKind,btwOrigin:c.btwOrigin},m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}addBtwThreadMarker(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=r.btwThreads||[];if(c.some(h=>h.requestId===n.requestId))return s;const u={...r,btwThreads:[n,...c].slice(0,20),lastActiveAt:Date.now()},m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}updateBtwThreadMarker(e,n,s){this.setState(r=>{const c=r.sessions.get(e);if(!c)return r;const u=c.btwThreads||[];if(u.length===0)return r;const m=u.map(f=>f.requestId!==n?f:{...f,...s}),h=new Map(r.sessions);return h.set(e,{...c,btwThreads:m}),{...r,sessions:h}})}removeBtwThreadMarker(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const u=(r.btwThreads||[]).filter(h=>h.requestId!==n),m=new Map(s.sessions);return m.set(e,{...r,btwThreads:u}),{...s,sessions:m}})}moveSessionToFront(e){this.setState(n=>{const s=n.sessions.get(e);if(!s)return n;const r={...s,createdAt:Date.now(),lastActiveAt:Date.now()},c=new Map(n.sessions);return c.set(e,r),{...n,sessions:c}})}async deleteSession(e){const n=this.getCascadeSessionIds(e);if(n.length===0)return;const{agentAPI:s}=await Xt(async()=>{const{agentAPI:c}=await import("./index-DNunTB6S.js");return{agentAPI:c}},[]);await Promise.all(n.map(async c=>{const u=this.state.sessions.get(c);if(!u)throw new Error(`Session not found: ${c}`);await s.deleteSession({session_id:c,domain:u.domain})}));const{stateMachineManager:r}=await Xt(async()=>{const{stateMachineManager:c}=await import("./index-C_s2NvXm.js");return{stateMachineManager:c}},[]);n.forEach(c=>{r.delete(c)}),this.removeSession(e)}removeSession(e){const n=this.getCascadeSessionIds(e);return n.length===0?[]:(n.forEach(s=>{this.warmedSessionIds.delete(s),this.clearSessionToolIndex(s)}),this.setState(s=>{const r=new Set(n),c=new Map(s.sessions),u=n.map(m=>s.sessions.get(m)).filter(m=>!!m);return n.forEach(m=>{c.delete(m)}),u.forEach(m=>{const h=m.btwOrigin?.parentSessionId??m.parentSessionId;if(!h||r.has(h))return;const f=c.get(h);if(!f?.btwThreads?.length)return;const y=m.btwOrigin?.requestId,v=f.btwThreads.filter(b=>!(b.childSessionId===m.sessionId||y&&b.requestId===y));v.length!==f.btwThreads.length&&c.set(h,{...f,btwThreads:v})}),{...s,sessions:c}}),n)}clearSession(e){const n=e;n&&this.setState(s=>{const r=s.sessions.get(n);if(!r)return s;const c={...r,dialogTurns:[],error:null,lastActiveAt:Date.now()},u=new Map(s.sessions);return u.set(n,c),{...s,sessions:u}})}removeSessionsForWorkspace(e){const n=Array.from(this.state.sessions.values()).filter(s=>eY(s,e)).map(s=>s.sessionId);return this.removeSessionsByIds(n)}removeSessionsByWorkspace(e){const n=Array.from(this.state.sessions.values()).filter(s=>Qg(s,e)).map(s=>s.sessionId);return this.removeSessionsByIds(n)}removeSessionsByIds(e){if(e.length===0)return[];const n=new Set(e);return e.forEach(s=>{this.warmedSessionIds.delete(s),this.clearSessionToolIndex(s)}),this.setState(s=>{const r=new Map(s.sessions);return n.forEach(c=>{r.delete(c)}),{...s,sessions:r}}),e}indexToolItem(e,n,s){s.type==="tool"&&this.toolItemIndex.set(s.id,{sessionId:e,dialogTurnId:n,itemId:s.id})}clearSessionToolIndex(e){for(const[n,s]of this.toolItemIndex)s.sessionId===e&&this.toolItemIndex.delete(n)}clearDialogTurnToolIndex(e,n){for(const[s,r]of this.toolItemIndex)r.sessionId===e&&r.dialogTurnId===n&&this.toolItemIndex.delete(s)}syncToolIndexForStateChange(e,n){if(e.sessions!==n.sessions){for(const[s,r]of e.sessions){const c=n.sessions.get(s);if(!c)this.clearSessionToolIndex(s);else if(c!==r){this.clearSessionToolIndex(s);for(const u of c.dialogTurns)this.indexDialogTurnTools(s,u)}}for(const[s,r]of n.sessions)if(!e.sessions.has(s))for(const c of r.dialogTurns)this.indexDialogTurnTools(s,c)}}indexDialogTurnTools(e,n){this.clearDialogTurnToolIndex(e,n.id);for(const s of n.modelRounds)for(const r of s.items)this.indexToolItem(e,n.id,r)}dialogTurnHasTool(e){return e.modelRounds.some(n=>n.items.some(s=>s.type==="tool"))}isLiveDialogTurn(e){return e.status==="pending"||e.status==="image_analyzing"||e.status==="processing"||e.status==="finishing"||e.status==="cancelling"||e.modelRounds.some(n=>n.isStreaming||n.status==="pending"||n.status==="streaming")}getDialogTurnSortTime(e){return e.startTime??e.userMessage?.timestamp??0}mergeHydratedDialogTurns(e,n){if(e.length===0)return n;if(n.length===0)return e;const s=new Map,r=new Map;return n.forEach((c,u)=>{s.set(c.id,u),r.set(c.id,c)}),e.forEach((c,u)=>{if(!s.has(c.id)){s.set(c.id,n.length+u),r.set(c.id,c);return}this.isLiveDialogTurn(c)&&r.set(c.id,c)}),Array.from(r.values()).sort((c,u)=>{const m=this.getDialogTurnSortTime(c)-this.getDialogTurnSortTime(u);return m!==0?m:(s.get(c.id)??0)-(s.get(u.id)??0)})}addDialogTurn(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r||r.dialogTurns.some(m=>m.id===n.id))return s;const c={...r,dialogTurns:[...r.dialogTurns,n],lastActiveAt:Date.now()};for(const m of n.modelRounds)for(const h of m.items)this.indexToolItem(e,n.id,h);const u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}deleteDialogTurn(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=r.dialogTurns.filter(h=>h.id!==n),u={...r,dialogTurns:c,lastActiveAt:Date.now()};this.clearDialogTurnToolIndex(e,n);const m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}truncateDialogTurnsFrom(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c=Math.max(0,Math.min(n,r.dialogTurns.length)),u={...r,dialogTurns:r.dialogTurns.slice(0,c),lastActiveAt:Date.now()};for(const h of r.dialogTurns.slice(c))this.clearDialogTurnToolIndex(e,h.id);const m=new Map(s.sessions);return m.set(e,u),{...s,sessions:m}})}updateDialogTurn(e,n,s){this.setState(r=>{const c=r.sessions.get(e);if(!c)return r;let u,m;const h=c.dialogTurns.map(v=>v.id!==n?v:(u=v,m=s(v),m)),f={...c,dialogTurns:h,lastActiveAt:Date.now()};m&&(this.dialogTurnHasTool(m)||u&&this.dialogTurnHasTool(u))&&this.indexDialogTurnTools(e,m);const y=new Map(r.sessions);return y.set(e,f),{...r,sessions:y}})}addFollowUpUserMessage(e,n,s){this.updateDialogTurn(e,n,r=>{const c=r.followUpUserMessages??[];return c.some(u=>u.id===s.id)?r:{...r,followUpUserMessages:[...c,s]}})}updateFollowUpUserMessage(e,n,s,r){this.updateDialogTurn(e,n,c=>{const u=c.followUpUserMessages??[];return u.some(m=>m.id===s)?{...c,followUpUserMessages:u.map(m=>m.id===s?{...m,...r}:m)}:c})}addImageAnalysisPhase(e,n,s){this.updateDialogTurn(e,n,r=>{const c=s.map((u,m)=>({id:`img-analysis-${u.id}`,type:"image-analysis",imageContext:u,result:null,status:"analyzing",timestamp:Date.now()+m}));return{...r,imageAnalysisPhase:{items:c,status:"analyzing",startTime:Date.now()},status:"image_analyzing"}})}updateImageAnalysisResults(e,n,s){this.updateDialogTurn(e,n,r=>{if(!r.imageAnalysisPhase)return et.warn("Attempting to update non-existent image analysis phase",{sessionId:e,dialogTurnId:n}),r;const c=r.imageAnalysisPhase.items.map(m=>{const h=s.find(f=>f.image_id===m.imageContext.id);return h?{...m,result:h,status:"completed"}:m}),u=c.every(m=>m.status==="completed");return{...r,imageAnalysisPhase:{...r.imageAnalysisPhase,items:c,status:u?"completed":"analyzing",endTime:u?Date.now():void 0},status:u?"pending":"image_analyzing"}})}updateImageAnalysisItem(e,n,s,r){this.updateDialogTurn(e,n,c=>{if(!c.imageAnalysisPhase)return c;const u=c.imageAnalysisPhase.items.map(m=>m.imageContext.id===s?{...m,...r}:m);return{...c,imageAnalysisPhase:{...c.imageAnalysisPhase,items:u}}})}addModelRound(e,n,s){this.updateDialogTurn(e,n,r=>({...r,modelRounds:[...r.modelRounds,s],status:"processing"}))}updateModelRound(e,n,s,r){this.updateDialogTurn(e,n,c=>({...c,modelRounds:c.modelRounds.map(u=>u.id===s?r(u):u)}))}batchUpdateModelRoundItems(e,n,s){s.length!==0&&this.updateDialogTurn(e,n,r=>{const c=new Map(s.map(m=>[m.itemId,m.changes])),u=r.modelRounds.map(m=>({...m,items:m.items.map(h=>{const f=c.get(h.id);return f?{...h,...f}:h})}));return{...r,modelRounds:u}})}addModelRoundItem(e,n,s,r){this.updateDialogTurn(e,n,c=>{let u=c.modelRounds.length-1;if(r&&(u=c.modelRounds.findIndex(y=>y.id===r),u===-1))return et.warn("Model round not found",{sessionId:e,dialogTurnId:n,modelRoundId:r}),c;if(u===-1)return et.warn("No available model rounds",{sessionId:e,dialogTurnId:n}),c;const m=c.modelRounds[u];if(m.items.find(y=>y.id===s.id))return c;const f=[...c.modelRounds];return f[u]={...m,items:[...m.items,s]},{...c,modelRounds:f}})}addModelRoundItemSilent(e,n,s,r){const c=this.silentMode;this.silentMode=!0;try{this.addModelRoundItem(e,n,s,r)}finally{this.silentMode=c}}updateModelRoundItem(e,n,s,r){this.updateDialogTurn(e,n,c=>{for(let u=0;uv.id===s);if(h===-1)continue;const f=[...m.items];f[h]={...f[h],...r};const y=[...c.modelRounds];return y[u]={...m,items:f},{...c,modelRounds:y}}return et.warn("Item not found for update",{sessionId:e,dialogTurnId:n,itemId:s}),c})}updateModelRoundItemSilent(e,n,s,r){const c=this.silentMode;this.silentMode=!0;try{this.updateModelRoundItem(e,n,s,r)}finally{this.silentMode=c}}findToolItem(e,n,s){const r=this.state.sessions.get(e);if(!r)return null;const c=r.dialogTurns.find(u=>u.id===n);if(!c)return null;for(const u of c.modelRounds){const m=u.items.find(h=>h.id===s);if(m)return this.indexToolItem(e,n,m),m}return null}findToolItemLocation(e){const n=this.toolItemIndex.get(e);if(n){const s=this.findToolItem(n.sessionId,n.dialogTurnId,e);if(s)return{...n,item:s};this.toolItemIndex.delete(e)}return null}updateTokenUsage(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,currentTokenUsage:{inputTokens:n.inputTokens,outputTokens:n.outputTokens,totalTokens:n.totalTokens,timestamp:Date.now()}},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}updateContextBudget(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,currentContextBudget:n,maxContextTokens:n.contextWindow},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}rollbackTokenUsage(){}updateSessionMaxContextTokens(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r||r.maxContextTokens===n)return s;const c={...r,maxContextTokens:n},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}setError(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,error:n,status:n?"error":"idle",lastActiveAt:Date.now()},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}markSessionFinished(e,n=Date.now()){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,lastActiveAt:n,lastFinishedAt:n},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}markSessionUnreadCompletion(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,hasUnreadCompletion:n},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}}),this.onPersistUnreadCompletion?.(e,n)}clearSessionUnreadCompletion(e){let n=!1;this.setState(s=>{const r=s.sessions.get(e);if(!r||!r.hasUnreadCompletion)return s;const c={...r,hasUnreadCompletion:void 0},u=new Map(s.sessions);return u.set(e,c),n=!0,{...s,sessions:u}}),n&&this.onPersistUnreadCompletion?.(e,void 0)}setSessionNeedsAttention(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,needsUserAttention:n},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}}),this.onPersistUnreadCompletion?.(e,void 0)}clearSessionNeedsAttention(e){let n=!1;this.setState(s=>{const r=s.sessions.get(e);if(!r||!r.needsUserAttention)return s;const c={...r,needsUserAttention:void 0},u=new Map(s.sessions);return u.set(e,c),n=!0,{...s,sessions:u}}),n&&this.onPersistUnreadCompletion?.(e,void 0)}async updateSessionTitle(e,n,s){this.setState(r=>{const c=r.sessions.get(e);if(!c)return r;const u={...c,title:n,titleStatus:s,lastActiveAt:Date.now()},m=new Map(r.sessions);return m.set(e,u),{...r,sessions:m}})}cancelSessionTask(e){this.setState(n=>{const s=n.sessions.get(e);if(!s)return et.warn("Session not found",{sessionId:e}),n;const r=s.dialogTurns[s.dialogTurns.length-1];if(!r)return et.warn("No dialog turns found",{sessionId:e}),n;if(r.status==="completed"||r.status==="cancelled")return n;const c=Date.now(),u=s.dialogTurns.map((y,v)=>v===s.dialogTurns.length-1?KJ(y,{settledAt:c,reason:"user_cancelled"}):y),m={...s,dialogTurns:u,status:"idle",lastActiveAt:Date.now()},h=new Map(n.sessions);h.set(e,m),window.dispatchEvent(new CustomEvent("sparo:dialog-cancelled",{detail:{sessionId:e}}));const f=u[u.length-1];return f&&f.status==="cancelled"&&this.saveCancelledDialogTurn(e,f.id).catch(y=>{et.error("Failed to save cancelled dialog turn",{sessionId:e,turnId:f.id,error:y})}),{...n,sessions:h}})}async saveCancelledDialogTurn(e,n){try{const{sessionAPI:s}=await Xt(async()=>{const{sessionAPI:f}=await import("./index-DNunTB6S.js");return{sessionAPI:f}},[]),r=this.state.sessions.get(e);if(!r){et.warn("Session not found, skipping save",{sessionId:e,turnId:n});return}if(r.isTransient)return;if(!r.workspacePath){et.warn("Workspace path not available, skipping save",{sessionId:e,turnId:n});return}const u=r.dialogTurns.find(f=>f.id===n);if(!u){et.warn("Dialog turn not found, skipping save",{sessionId:e,turnId:n});return}const m=r.dialogTurns.findIndex(f=>f.id===n),h={turnId:n,turnIndex:m,sessionId:e,timestamp:u.startTime,kind:u.kind||"user_dialog",userMessage:{id:u.userMessage.id,content:u.userMessage.content,timestamp:u.userMessage.timestamp,metadata:u.userMessage.metadata},followUpUserMessages:u.followUpUserMessages?.map(f=>({id:f.id,content:f.content,timestamp:f.timestamp,kind:f.kind,status:f.status,guidanceId:f.guidanceId,sourceTurnId:f.sourceTurnId,appliedAt:f.appliedAt,error:f.error,hasImages:f.hasImages,imageCount:f.imageCount,metadata:f.metadata})),modelRounds:u.modelRounds.map((f,y)=>{const v=f.items.filter(A=>A.type==="text").map(A=>({id:A.id,content:A.content||"",isStreaming:!1,timestamp:A.timestamp,status:A.status})),b=f.items.filter(A=>A.type==="tool").map(A=>({id:A.id,toolName:A.toolName||"",interruptionReason:A.interruptionReason,toolCall:A.toolCall||{input:{},id:A.id},toolResult:A.toolResult,aiIntent:A.aiIntent,startTime:A.startTime||A.timestamp,endTime:A.endTime,status:A.status,executionProjection:A.executionProjection,durationMs:A.endTime?A.endTime-A.startTime:void 0})),S=f.items.filter(A=>A.type==="thinking").map(A=>({id:A.id,content:A.content||"",isStreaming:!1,isCollapsed:A.isCollapsed||!1,timestamp:A.timestamp,status:A.status}));return{id:f.id,turnId:n,roundIndex:y,timestamp:f.startTime,textItems:v,toolItems:b,thinkingItems:S,startTime:f.startTime,endTime:f.endTime||Date.now(),status:f.status}}),startTime:u.startTime,endTime:u.endTime||Date.now(),durationMs:(u.endTime||Date.now())-u.startTime,status:"cancelled"};await s.saveSessionTurn(h,r.domain)}catch(s){et.error("Failed to save cancelled dialog turn",{sessionId:e,turnId:n,error:s})}}async hydrateWorkspaceSessionsMetadata(e,n){if(e.length===0)return this.markWorkspaceMetadataPreloaded(n),0;const s=this.state,r=new Map(s.sessions);let c=0,u=!1;for(const m of e){const h=r.get(m.sessionId),f=jJ(m),y=LJ(m);if(h){const F=m.lastActiveAt??m.createdAt??0,_=h.updatedAt??h.lastActiveAt??h.lastFinishedAt??h.createdAt,E=m.customMetadata?.productAppRuntime!=null,j=h.customMetadata?.productAppRuntime!=null,z=h.descriptor.hostKind==="product-app-runtime";if(!E&&(j||z)||!(E&&(!j||!z))&&F<=_)continue;const I=ag(m,Zn(h.descriptor));r.set(m.sessionId,{...h,descriptor:I,config:{...h.config,agentType:Zn(I)},title:m.sessionName,lastActiveAt:Math.max(m.lastActiveAt??0,h.lastActiveAt??0),lastFinishedAt:y??h.lastFinishedAt,updatedAt:Math.max(F,_),todos:m.todos||h.todos||[],workspacePath:m.workspacePath||h.workspacePath||n,domain:m.domain,customMetadata:m.customMetadata||h.customMetadata,parentSessionId:f.parentSessionId,sessionKind:f.sessionKind,btwOrigin:f.btwOrigin,hasUnreadCompletion:m.unreadCompletion,needsUserAttention:m.needsUserAttention,isTransient:!1,loadPhase:h.loadPhase}),u=!0;continue}if(EJ(m))continue;const v=m.agentType||"Runno",b=ag(m,v),S=Zn(b),A={sessionId:m.sessionId,title:m.sessionName,titleStatus:"generated",dialogTurns:[],status:"idle",config:{agentType:S,modelName:m.modelName},createdAt:m.createdAt,lastActiveAt:m.lastActiveAt,lastFinishedAt:y,updatedAt:m.lastActiveAt??m.createdAt,error:null,loadPhase:"metadata-only",todos:m.todos||[],descriptor:b,workspacePath:m.workspacePath||n,domain:m.domain,customMetadata:m.customMetadata,parentSessionId:f.parentSessionId,sessionKind:f.sessionKind,btwThreads:[],btwOrigin:f.btwOrigin,hasUnreadCompletion:m.unreadCompletion,needsUserAttention:m.needsUserAttention,isTransient:!1};r.set(m.sessionId,A),c+=1,u=!0}return u&&this.setState(m=>({...m,sessions:r})),this.markWorkspaceMetadataPreloaded(n),c}async initializeFromDisk(e,n){try{const{sessionAPI:s}=await Xt(async()=>{const{sessionAPI:c}=await import("./index-DNunTB6S.js");return{sessionAPI:c}},[]),r=await s.listSessions(n);await this.hydrateWorkspaceSessionsMetadata(r,e)}catch(s){et.error("Failed to load persisted sessions",s)}}loadSessionHistory(e,n,s,r){const c=this.pendingSessionHistoryLoads.get(e);if(c)return c;let u;return u=this.loadSessionHistoryOnce(e,n,s,r).finally(()=>{this.pendingSessionHistoryLoads.get(e)===u&&this.pendingSessionHistoryLoads.delete(e)}),this.pendingSessionHistoryLoads.set(e,u),u}getPendingSessionHistoryLoad(e){return this.pendingSessionHistoryLoads.get(e)??null}async loadSessionHistoryOnce(e,n,s,r){const c=Date.now();this.setSessionLoadPhase(e,"hydrating");try{const{stateMachineManager:u}=await Xt(async()=>{const{stateMachineManager:v}=await import("./index-C_s2NvXm.js");return{stateMachineManager:v}},[]);u.getOrCreate(e);const{sessionAPI:m}=await Xt(async()=>{const{sessionAPI:v}=await import("./index-DNunTB6S.js");return{sessionAPI:v}},[]),h=await m.loadSessionTurns({session_id:e,domain:s},r),f=this.convertToDialogTurns(h);let y=f;this.setState(v=>{const b=v.sessions.get(e);if(!b)return v;y=this.mergeHydratedDialogTurns(b.dialogTurns,f);const S={...b,dialogTurns:y,loadPhase:"hydrated"},A=new Map(v.sessions);return A.set(e,S),{...v,sessions:A}}),this.markSessionHistoryWarmed(e),et.debug("Session transcript hydrated",{sessionId:e,turnCount:h.length,durationMs:Date.now()-c}),this.scheduleExecutionProjectionHydration(y)}catch(u){throw this.setSessionLoadPhase(e,"hydrate-failed"),et.error("Failed to load session history",{sessionId:e,error:u}),u}}scheduleExecutionProjectionHydration(e){const n=()=>{this.hydrateExecutionProjections(e).catch(s=>{et.warn("Failed to hydrate deferred execution projections",{error:s})})};if(typeof window<"u"&&typeof window.requestAnimationFrame=="function"){window.requestAnimationFrame(()=>window.setTimeout(n,0));return}setTimeout(n,0)}async hydrateExecutionProjections(e){const n=e.flatMap(r=>r.modelRounds.flatMap(c=>c.items.filter(u=>u.type==="tool").map(u=>u.executionProjection).filter(Boolean)));if(n.length===0)return;const{executionGraphStore:s}=await Xt(async()=>{const{executionGraphStore:r}=await import("./index-DgcE1LoE.js");return{executionGraphStore:r}},[]);n.forEach(r=>{r&&r.id&&r.parentSessionId&&r.parentToolId&&r.childSessionId&&s.hydrateNode(r)})}cleanRemoteUserInput(e){const n=e.trim(),s=n.match(/\s*([\s\S]*?)\s*<\/user_query>/);return s?s[1].trim():n.replace(/[\s\S]*?<\/system(?:_|-)reminder>/g,"").trim()}convertToDialogTurns(e){return e.map(n=>{const s=n.userMessage.metadata,r=s?.images,c=Array.isArray(r)&&r.length>0,u=c?r.map(y=>({id:y.id||y.name||`img-${Date.now()}`,name:y.name||"image",dataUrl:y.data_url,imagePath:y.image_path,mimeType:y.mime_type})):void 0,m=s?.original_text||this.cleanRemoteUserInput(n.userMessage.content),h=s?.triggerSource||n.userMessage.triggerSource,f=UJ(n.status,{error:n.error,modelRounds:n.modelRounds});return{id:n.turnId,sessionId:n.sessionId,kind:n.kind||"user_dialog",userMessage:{id:n.userMessage.id,type:"user",content:m,timestamp:n.userMessage.timestamp,hasImages:c,triggerSource:h,metadata:s,images:u},followUpUserMessages:Array.isArray(n.followUpUserMessages)?n.followUpUserMessages.map(y=>({id:y.id,content:this.cleanRemoteUserInput(y.content||""),timestamp:y.timestamp,kind:y.kind||"guidance",status:y.status||"applied",guidanceId:y.guidanceId,sourceTurnId:y.sourceTurnId,appliedAt:y.appliedAt,error:y.error,hasImages:y.hasImages,imageCount:y.imageCount,metadata:y.metadata})):void 0,modelRounds:n.modelRounds.map(y=>{const v=HJ(y.status,f),b=v==="pending_confirmation"?"cancelled":v;return{id:y.id,turnId:y.turnId,index:y.roundIndex??0,items:[...y.textItems.map(S=>({id:S.id,type:"text",content:S.content,isStreaming:!1,isMarkdown:S.isMarkdown!==void 0?S.isMarkdown:!0,timestamp:S.timestamp,status:qJ(S.status,f),orderIndex:S.orderIndex})),...y.toolItems.map(S=>{const A=S.status==="pending_confirmation"||S.status==="confirmed"?"cancelled":GJ(S.status,f,S.toolResult);return{id:S.id,type:"tool",toolName:S.toolName,interruptionReason:S.interruptionReason==="app_restart"||S.status==="pending_confirmation"||WJ(S.status)?"app_restart":void 0,toolCall:S.toolCall,toolResult:S.toolResult,aiIntent:S.aiIntent,startTime:S.startTime,endTime:S.endTime,executionProjection:S.executionProjection,runtime:rg(S,A),timestamp:S.startTime,status:A,orderIndex:S.orderIndex}}),...(y.thinkingItems||[]).map(S=>({id:S.id,type:"thinking",content:S.content,isStreaming:!1,isCollapsed:S.isCollapsed??!0,timestamp:S.timestamp,status:VJ(S.status,f),orderIndex:S.orderIndex}))].sort((S,A)=>{const F=S.orderIndex!==void 0?S.orderIndex:S.timestamp||0,_=A.orderIndex!==void 0?A.orderIndex:A.timestamp||0;return F-_}),isStreaming:!1,isComplete:b!=="pending"&&b!=="streaming",status:b,startTime:y.startTime??y.timestamp,endTime:y.endTime,timestamp:y.timestamp}}),timestamp:n.timestamp,status:f,startTime:n.startTime,endTime:n.endTime,backendTurnIndex:n.turnIndex}})}setDialogTurnTodos(e,n,s){this.setState(r=>{const c=r.sessions.get(e);if(!c)return et.warn("Session not found, cannot set turn todos",{sessionId:e,turnId:n}),r;const u=c.dialogTurns.findIndex(y=>y.id===n);if(u===-1)return et.warn("Dialog turn not found, cannot set turn todos",{sessionId:e,turnId:n}),r;const m=[...c.dialogTurns];m[u]={...m[u],todos:[...s]};const h={...c,dialogTurns:m,lastActiveAt:Date.now()},f=new Map(r.sessions);return f.set(e,h),{...r,sessions:f}})}getDialogTurnTodos(e,n){const s=this.state.sessions.get(e);return s?s.dialogTurns.find(c=>c.id===n)?.todos||[]:[]}deleteTodo(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return et.warn("Session not found, cannot delete todo",{sessionId:e,todoId:n}),s;const u=(r.todos||[]).filter(f=>f.id!==n),m={...r,todos:u,lastActiveAt:Date.now()},h=new Map(s.sessions);return h.set(e,m),{...s,sessions:h}})}getTodos(e){const n=this.state.sessions.get(e);if(!n)return[];const s=[];return n.dialogTurns.forEach(r=>{r.todos&&r.todos.length>0&&s.push(...r.todos)}),n.todos&&n.todos.length>0&&s.push(...n.todos),s}setTodos(e,n){this.setState(s=>{const r=s.sessions.get(e);if(!r)return s;const c={...r,todos:[...n],lastActiveAt:Date.now()},u=new Map(s.sessions);return u.set(e,c),{...s,sessions:u}})}}const Yg=Po.getInstance(),Une=Object.freeze(Object.defineProperty({__proto__:null,FlowChatStore:Po,flowChatStore:Yg},Symbol.toStringTag,{value:"Module"})),pY=ft("SnapshotAPI"),mi=i=>{if(!i)throw new Error("workspacePath is required for snapshot operations");return i},ht=(i,e)=>{const n=e||Yg.getState().sessions.get(i)?.workspacePath;if(!n)throw new Error(`workspacePath is required for snapshot session: ${i}`);return n};class mY{async getSessionStats(e,n){try{const s=ht(e,n);return await V.invoke("get_session_stats",{request:{session_id:e,workspacePath:s}})}catch(s){throw J("get_session_stats",s,{sessionId:e,workspacePath:n})}}async getSessionFiles(e,n){try{const s=ht(e,n);return await V.invoke("get_session_files",{request:{session_id:e,workspacePath:s}})}catch(s){throw J("get_session_files",s,{sessionId:e,workspacePath:n})}}async getOperationDiff(e,n,s,r){try{const c=ht(e,r);return await V.invoke("get_operation_diff",{request:{sessionId:e,filePath:n,operationId:s,workspacePath:c}})}catch(c){throw J("get_operation_diff",c,{sessionId:e,filePath:n,operationId:s,workspacePath:r})}}async getOperationSummary(e,n,s){try{const r=ht(e,s);return await V.invoke("get_operation_summary",{request:{sessionId:e,operationId:n,workspacePath:r}})}catch(r){throw J("get_operation_summary",r,{sessionId:e,operationId:n,workspacePath:s})}}async getBaselineSnapshotDiff(e,n){try{const s=mi(n);return await V.invoke("get_baseline_snapshot_diff",{request:{filePath:e,workspacePath:s}})}catch(s){throw J("get_baseline_snapshot_diff",s,{filePath:e,workspacePath:n})}}async acceptSessionModifications(e,n){try{const s=ht(e,n);await V.invoke("accept_session",{request:{sessionId:e,workspacePath:s}})}catch(s){throw J("accept_session",s,{sessionId:e,workspacePath:n})}}async rejectSessionModifications(e,n){try{const s=ht(e,n);await V.invoke("rollback_session",{request:{sessionId:e,deleteSession:!0,workspacePath:s}})}catch(s){throw J("rollback_session",s,{sessionId:e,workspacePath:n})}}async acceptFileModifications(e,n,s){try{const r=ht(e,s);await V.invoke("accept_file",{request:{sessionId:e,filePath:n,workspacePath:r}})}catch(r){throw J("accept_file",r,{sessionId:e,filePath:n,workspacePath:s})}}async rejectFileModifications(e,n,s){try{const r=ht(e,s);await V.invoke("reject_file",{request:{sessionId:e,filePath:n,workspacePath:r}})}catch(r){throw J("reject_file",r,{sessionId:e,filePath:n,workspacePath:s})}}async acceptDiffBlock(e,n,s){try{await V.invoke("accept_diff_block",{request:{sessionId:e,filePath:n,blockId:s.toString()}})}catch(r){throw J("accept_diff_block",r,{sessionId:e,filePath:n,blockIndex:s})}}async rejectDiffBlock(e,n,s){try{await V.invoke("reject_diff_block",{request:{sessionId:e,filePath:n,blockId:s.toString()}})}catch(r){throw J("reject_diff_block",r,{sessionId:e,filePath:n,blockIndex:s})}}async acceptOperation(e,n,s){try{const r=ht(e,s);await V.invoke("accept_operation",{request:{sessionId:e,operationId:n,workspacePath:r}})}catch(r){throw J("accept_operation",r,{sessionId:e,operationId:n,workspacePath:s})}}async rejectOperation(e,n,s){try{const r=ht(e,s);await V.invoke("reject_operation",{request:{sessionId:e,operationId:n,workspacePath:r}})}catch(r){throw J("reject_operation",r,{sessionId:e,operationId:n,workspacePath:s})}}async rollbackSession(e,n){try{const s=ht(e,n);await V.invoke("rollback_session",{request:{sessionId:e,workspacePath:s}})}catch(s){throw J("rollback_session",s,{sessionId:e,workspacePath:n})}}async cleanupEmptySessions(){try{return await V.invoke("cleanup_empty_sessions",{request:{}})}catch(e){throw J("cleanup_empty_sessions",e)}}async getSnapshotStats(e){try{const n=mi(e);return await V.invoke("get_snapshot_system_stats",{request:{workspacePath:n}})}catch(n){throw J("get_snapshot_system_stats",n,{workspacePath:e})}}async getSnapshotSessions(e){try{const n=mi(e);return await V.invoke("get_snapshot_sessions",{request:{workspacePath:n}})}catch(n){throw J("get_snapshot_sessions",n,{workspacePath:e})}}async getSessionOperations(e,n){try{const s=ht(e,n);return await V.invoke("get_session_operations",{request:{sessionId:e,workspacePath:s}})}catch(s){throw J("get_session_operations",s,{sessionId:e,workspacePath:n})}}async recordTurnSnapshot(e,n,s,r){try{const c=ht(e,r);await V.invoke("record_turn_snapshot",{session_id:e,turn_index:n,modified_files:s,workspacePath:c})}catch(c){throw J("record_turn_snapshot",c,{sessionId:e,turnIndex:n,modifiedFiles:s,workspacePath:r})}}async rollbackToTurn(e,n,s=!1,r){try{const c=ht(e,r);return await V.invoke("rollback_to_turn",{request:{session_id:e,turn_index:n,delete_turns:s,workspacePath:c}})}catch(c){throw J("rollback_to_turn",c,{sessionId:e,turnIndex:n,deleteTurns:s,workspacePath:r})}}async rollbackEntireSession(e,n=!0,s){try{const r=ht(e,s);return await V.invoke("rollback_session",{request:{session_id:e,delete_session:n,workspacePath:r}})}catch(r){throw J("rollback_session",r,{sessionId:e,workspacePath:s})}}async getSessionTurnSnapshots(e,n){try{const s=ht(e,n),r=await V.invoke("get_session_turns",{request:{session_id:e,workspacePath:s}}),c=[];for(const u of r)try{const m=await V.invoke("get_turn_files",{request:{session_id:e,turn_index:u,workspacePath:s}});c.push({sessionId:e,turnIndex:u,modifiedFiles:m,timestamp:Date.now()/1e3})}catch(m){pY.warn("Failed to get turn files",{sessionId:e,turnIndex:u,error:m}),c.push({sessionId:e,turnIndex:u,modifiedFiles:[],timestamp:Date.now()/1e3})}return c}catch(s){throw J("get_session_turns",s,{sessionId:e,workspacePath:n})}}async getFileChangeHistory(e,n){try{const s=mi(n);return await V.invoke("get_file_change_history",{request:{file_path:e,workspacePath:s}})}catch(s){throw J("get_file_change_history",s,{filePath:e,workspacePath:n})}}async getAllModifiedFiles(e){try{const n=mi(e);return await V.invoke("get_all_modified_files",{request:{workspacePath:n}})}catch(n){throw J("get_all_modified_files",n,{workspacePath:e})}}}const Hne=new mY,Ga=ft("ConfigSnapshotStore"),gY={status:"idle",snapshot:null,isRefreshing:!1,error:null};function Ac(i,e){return i.kind!==e.kind?!1:i.kind==="workspace"&&e.kind==="workspace"?i.workspaceId===e.workspaceId:i.kind==="session"&&e.kind==="session"?i.sessionId===e.sessionId:i.kind==="user"&&e.kind==="user"}function Vc(i,e){if(Object.is(i,e))return!0;if(Array.isArray(i)||Array.isArray(e))return Array.isArray(i)&&Array.isArray(e)&&i.length===e.length&&i.every((u,m)=>Vc(u,e[m]));if(i===null||e===null||typeof i!="object"||typeof e!="object")return!1;const n=i,s=e,r=Object.keys(n),c=Object.keys(s);return r.length===c.length&&r.every(u=>Object.prototype.hasOwnProperty.call(s,u)&&Vc(n[u],s[u]))}class hY{constructor(e,n={kind:"user"}){this.transport=e,this.scope=n}state=gY;listeners=new Set;acceptedListeners=new Set;pendingEvents=new Map;lastChangedRevision=new Map;refreshPromise=null;refreshRequestedDuringRefresh=!1;unlisten=null;getState=()=>this.state;subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));subscribeAccepted=e=>(this.acceptedListeners.add(e),()=>this.acceptedListeners.delete(e));getValue(e){return this.state.snapshot?.values[e]}didSettingChangeAfter(e,n){return(this.lastChangedRevision.get(e)??-1)>n}start(){if(this.unlisten)return this.state.snapshot?Promise.resolve(this.state.snapshot):this.refresh();const e=this.transport.onConfigCommitted(s=>{this.handleCommittedEvent(s)}),n=this.transport.onConfigSnapshotRefreshed(s=>{this.handleAuthoritativeSnapshot(s)});return this.unlisten=()=>{e(),n()},this.refresh()}stop(){this.unlisten?.(),this.unlisten=null,this.pendingEvents.clear(),this.lastChangedRevision.clear(),this.refreshRequestedDuringRefresh=!1}refresh(){return this.refreshPromise?this.refreshPromise:(this.updateState({...this.state,status:this.state.snapshot?this.state.status:"loading",isRefreshing:!0,error:null}),this.refreshPromise=this.transport.getConfigSnapshot({scope:this.scope}).then(e=>{if(!Ac(e.scope,this.scope))throw new Error(`Config snapshot scope mismatch: expected ${this.scope.kind}, received ${e.scope.kind}`);const n=this.state.snapshot;!n||e.revision>n.revision?this.acceptSnapshot(e):this.updateState({...this.state,status:"ready",isRefreshing:!1,error:null}),this.discardAppliedEvents(),this.applyContiguousPendingEvents();const s=this.state.snapshot;if(!s)throw new Error("Config snapshot refresh completed without a snapshot");const r=Math.min(...this.pendingEvents.keys());return Number.isFinite(r)&&r>s.revision+1&&Ga.warn("Config event gap remains after snapshot refresh",{revision:s.revision,nextPendingRevision:r}),s}).catch(e=>{const n=e instanceof Error?e:new Error(String(e));throw this.updateState({...this.state,status:"error",isRefreshing:!1,error:n}),Ga.error("Failed to refresh config snapshot",{error:n}),n}).finally(()=>{const e=this.refreshRequestedDuringRefresh&&this.hasPendingGap();this.refreshRequestedDuringRefresh=!1,this.refreshPromise=null,e&&this.refresh().catch(()=>{})}),this.refreshPromise)}handleCommittedEvent(e){if(!Ac(e.scope,this.scope))return;const n=this.state.snapshot;if(!(n&&e.revision<=n.revision)){if(!n||this.refreshPromise){this.pendingEvents.set(e.revision,e),this.refreshRequestedDuringRefresh||=!!this.refreshPromise,this.refreshPromise||this.refresh().catch(()=>{});return}if(e.revision===n.revision+1){this.applyEvent(e),this.applyContiguousPendingEvents();return}this.pendingEvents.set(e.revision,e),this.refresh().catch(()=>{})}}handleAuthoritativeSnapshot(e){if(!Ac(e.scope,this.scope)){Ga.error("Rejected config snapshot refresh with a mismatched scope",{expectedScope:this.scope,receivedScope:e.scope,revision:e.revision});return}const n=this.state.snapshot;n&&e.revision<=n.revision||(this.acceptSnapshot(e),this.discardAppliedEvents(),this.applyContiguousPendingEvents())}applyEvent(e){const n=this.state.snapshot;if(!n||e.revision!==n.revision+1)return;const s={...n.values};for(const r of e.changes)s[r.settingId]=r.newValue;this.acceptSnapshot({...n,revision:e.revision,catalogVersion:e.catalogVersion,values:s})}applyContiguousPendingEvents(){let e=this.state.snapshot;for(;e;){const n=e.revision+1,s=this.pendingEvents.get(n);if(!s)return;this.pendingEvents.delete(n),this.applyEvent(s),e=this.state.snapshot}}discardAppliedEvents(){const e=this.state.snapshot?.revision;if(e!==void 0)for(const n of this.pendingEvents.keys())n<=e&&this.pendingEvents.delete(n)}hasPendingGap(){const e=this.state.snapshot?.revision;return e===void 0||this.pendingEvents.size===0?this.pendingEvents.size>0:Math.min(...this.pendingEvents.keys())>e+1}acceptSnapshot(e){const n=this.state.snapshot;if(n&&e.revision<=n.revision)return;const s=n?this.diffSettingIds(n,e):[];for(const c of s)this.lastChangedRevision.set(c,e.revision);this.updateState({status:"ready",snapshot:e,isRefreshing:!1,error:null});const r={previous:n,snapshot:e,changedSettingIds:s};for(const c of this.acceptedListeners)try{c(r)}catch(u){Ga.error("Config snapshot accepted listener failed",{revision:e.revision,error:u})}}diffSettingIds(e,n){const s=new Set([...Object.keys(e.values),...Object.keys(n.values)]),r=[];for(const c of s)Vc(e.values[c],n.values[c])||r.push(c);return r}updateState(e){this.state=e,this.listeners.forEach(n=>n())}}const Zg=new hY(_i),_c=ft("ConfigCatalogStore"),fY={status:"idle",catalog:null,error:null};class yY{constructor(e,n,s={kind:"user"}){this.transport=e,this.getSnapshotSource=n,this.scope=s}state=fY;listeners=new Set;descriptorIndex=new Map;versionLoadPromises=new Map;requestSequence=0;activeRequestSequence=0;unlisten=null;getState=()=>this.state;subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));getDescriptor(e){return this.descriptorIndex.get(e)}async load(e=!1){this.ensureSnapshotSubscription();const n=await this.getSnapshotSource().start();return this.loadVersion(n.catalogVersion,e)}async ensureVersion(e){return this.ensureSnapshotSubscription(),this.loadVersion(e,!1)}loadVersion(e,n){if(!n&&this.state.catalog?.version===e)return Promise.resolve(this.state.catalog);const s=this.versionLoadPromises.get(e);if(s)return s;const r=this.requestCatalog(e);return this.versionLoadPromises.set(e,r),r.finally(()=>{this.versionLoadPromises.get(e)===r&&this.versionLoadPromises.delete(e)}).catch(()=>{}),r}stop(){this.unlisten?.(),this.unlisten=null}ensureSnapshotSubscription(){if(this.unlisten)return;const e=this.getSnapshotSource();this.unlisten=e.subscribeAccepted(s=>{this.ensureVersion(s.snapshot.catalogVersion).catch(r=>{_c.error("Failed to refresh config catalog for accepted snapshot",{revision:s.snapshot.revision,catalogVersion:s.snapshot.catalogVersion,error:r})})});const n=e.getState().snapshot;n&&this.ensureVersion(n.catalogVersion).catch(s=>{_c.error("Failed to align config catalog with current snapshot",{revision:n.revision,catalogVersion:n.catalogVersion,error:s})})}requestCatalog(e){const n=++this.requestSequence;return this.activeRequestSequence=n,this.updateState({...this.state,status:"loading",error:null}),this.transport.describeConfigCatalog({scope:this.scope}).then(s=>{if(s.version!==e)throw new Error(`Config catalog version mismatch: expected ${e}, received ${s.version}`);const r=this.indexDescriptors(s);return n===this.activeRequestSequence&&(this.descriptorIndex.clear(),r.forEach((c,u)=>this.descriptorIndex.set(u,c)),this.updateState({status:"ready",catalog:s,error:null})),s}).catch(s=>{const r=s instanceof Error?s:new Error(String(s));throw n===this.activeRequestSequence&&this.updateState({...this.state,status:"error",error:r}),_c.error("Failed to load config catalog",{targetVersion:e,error:r}),r})}indexDescriptors(e){const n=new Map;for(const s of e.settings){if(n.has(s.id))throw new Error(`Duplicate setting descriptor id: ${s.id}`);n.set(s.id,s)}return n}updateState(e){this.state=e,this.listeners.forEach(n=>n())}}const wY=new yY(_i,()=>Zg);function lg(i){return i?.mode==="readOnlyDefaults"||i?.writesAllowed===!1}const Ka=ft("ConfigStartupStatusStore"),vY={loadState:"idle",value:null,error:null};class bY extends Error{code="config.recovery_read_only";constructor(){super("Configuration is read-only while Sparo OS is using recovery defaults"),this.name="ConfigReadOnlyRecoveryError"}}class kY{state=vY;listeners=new Set;loadPromise=null;rebuildPromise=null;getState=()=>this.state;subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));load(){return this.state.loadState==="ready"?Promise.resolve(this.state.value):this.loadPromise?this.loadPromise:(this.updateState({loadState:"loading",value:null,error:null}),this.loadPromise=_i.getConfigStartupStatus().then(e=>(this.updateState({loadState:"ready",value:e,error:null}),lg(e)&&Ka.warn("Configuration started with read-only recovery defaults",{mode:e.mode,schemaVersion:e.schemaVersion,sourcePreserved:e.sourcePreserved,rebuildAllowed:e.rebuildAllowed,issueCode:e.issue?.code,issuePhase:e.issue?.phase}),e)).catch(e=>{const n=e instanceof Error?e:new Error(String(e));return this.updateState({loadState:"error",value:null,error:n}),Ka.error("Failed to load configuration startup status",{error:n}),null}).finally(()=>{this.loadPromise=null}),this.loadPromise)}rebuildDefaults(){return this.rebuildPromise?this.rebuildPromise:(this.rebuildPromise=_i.rebuildDefaultConfig().then(e=>(this.updateState({loadState:"ready",value:e,error:null}),Ka.info("Current default configuration rebuilt after user confirmation",{schemaVersion:e.schemaVersion}),e)).catch(e=>{const n=e instanceof Error?e:new Error(String(e));throw Ka.error("Failed to rebuild default configuration",{error:n}),n}).finally(()=>{this.rebuildPromise=null}),this.rebuildPromise)}assertWritesAllowed(){if(lg(this.state.value))throw new bY}updateState(e){this.state=e,this.listeners.forEach(n=>n())}}const Qa=new kY;class yi extends Error{constructor(e,n){super("Config plan requires confirmation"),this.plan=e,this.commitRequest=n,this.name="ConfigConfirmationRequiredError"}}class Ja extends Error{constructor(){super("Config change confirmation was rejected"),this.name="ConfigConfirmationRejectedError"}}class SY{constructor(e){this.transport=e}async plan(e){return Qa.assertWritesAllowed(),this.transport.planConfigPatch(e)}async commit(e){return Qa.assertWritesAllowed(),this.transport.commitConfigPatch(e)}async undo(e){return Qa.assertWritesAllowed(),this.transport.undoConfigCommit(e)}getCommit(e){return this.transport.getConfigCommit(e)}async retryApply(e){return Qa.assertWritesAllowed(),this.transport.retryConfigApply(e)}onCommitted(e){return this.transport.onConfigCommitted(e)}onRolledBack(e){return this.transport.onConfigRolledBack(e)}onApplyStatus(e){return this.transport.onConfigApplyStatus(e)}async apply(e,n){const s=await this.plan(e);if(s.requiresConfirmation)throw new yi(s,n);return this.commit({...n,planId:s.planId,confirmed:!1})}}const xY=new SY(_i);function cg(i){const e=globalThis.crypto?.randomUUID?.()??`${Date.now()}-${Math.random().toString(16).slice(2)}`;return`${i}-${e}`}const xo=ft("ConfigManager"),CY={get catalog(){return wY},get snapshot(){return Zg},get transaction(){return xY}};function dg(i){return i.kind==="value"?Ti(i.value):{configured:i.configured,provider:i.provider,maskedSuffix:i.maskedSuffix}}function sr(i,e){const n=i.values[e];if(!n)throw new Error(`Accepted config snapshot revision ${i.revision} is missing Catalog setting "${e}"`);return n}function Ti(i){return Array.isArray(i)?i.map(e=>Ti(e)):i!==null&&typeof i=="object"?Object.fromEntries(Object.entries(i).map(([e,n])=>[e,Ti(n)])):i}function ir(i,e){if(i===null||typeof i=="string"||typeof i=="boolean")return i;if(typeof i=="number"){if(!Number.isFinite(i))throw new Error(`Config value at "${e}" must be a finite number`);return i}if(Array.isArray(i))return i.map((n,s)=>ir(n,`${e}[${s}]`));if(typeof i=="object"){const n={};for(const[s,r]of Object.entries(i))r!==void 0&&(n[s]=ir(r,`${e}.${s}`));return n}throw new Error(`Config value at "${e}" is not JSON serializable`)}function AY(i,e){let n=i;for(const s of e.split(".")){if(n===null||typeof n!="object"||Array.isArray(n))return{found:!1};if(!Object.prototype.hasOwnProperty.call(n,s))return{found:!1};n=n[s]}return{found:!0,value:n}}function _Y(i,e,n){const s=e.split(".");let r=i;s.forEach((c,u)=>{if(u===s.length-1){r[c]=Ti(n);return}const m=r[c];(m===null||Array.isArray(m)||typeof m!="object")&&(r[c]={}),r=r[c]})}function ug(i){if(i===null||typeof i!="object"||Array.isArray(i))return!1;const e=i,n=Object.keys(e);return typeof e.configured=="boolean"&&n.every(s=>s==="configured"||s==="provider"||s==="maskedSuffix")}function Gc(i,e){const n=`${e}.`;return i.settings.filter(s=>s.id===e||s.id.startsWith(n)).sort((s,r)=>s.id.localeCompare(r.id))}function pg(i,e,n){const s=Gc(i,n),r=s.find(m=>m.id===n);if(r){const m=sr(e,r.id);return m.kind==="value"?Ti(m.value):void 0}if(s.length===0)throw new Error(`No Catalog setting matches ID or namespace "${n}"`);const c={};let u=!1;for(const m of s){const h=sr(e,m.id);if(h.kind!=="value")continue;const f=m.id.slice(n.length+1);_Y(c,f,h.value),u=!0}return u?c:void 0}class TY{constructor(e=CY){this.dependencies=e}listeners=new Set;settingListeners=new Map;writeTail=Promise.resolve();notificationTail=Promise.resolve();snapshotUnlisten=null;confirmationHandler=null;ensureSnapshotSubscription(){this.snapshotUnlisten||(this.snapshotUnlisten=this.dependencies.snapshot.subscribeAccepted(e=>{!e.previous||e.changedSettingIds.length===0||(this.notificationTail=this.notificationTail.then(()=>this.publishAcceptedSnapshotUpdate(e)).catch(n=>{xo.error("Failed to publish accepted config snapshot update",{revision:e.snapshot.revision,error:n})}))}))}async getSetting(e){const n=this.requireSettingId(e);try{const{catalog:s,snapshot:r}=await this.loadAuthoritativeState();return pg(s,r,n)}catch(s){throw xo.error("Failed to get setting",{settingId:n,error:s}),s}}async setSetting(e,n,s={}){const r=this.requireSettingId(e);try{await this.enqueueWrite(async()=>{const c=await this.loadAuthoritativeState(),u=this.buildSetOperations(c.catalog,r,n);await this.applyOperations(c.snapshot,u,s)})}catch(c){throw!(c instanceof yi)&&!(c instanceof Ja)&&xo.error("Failed to set setting",{settingId:r,error:c}),c}}async updateSetting(e,n,s={}){const r=this.requireSettingId(e);try{await this.enqueueWrite(async()=>{const c=await this.loadAuthoritativeState(),u=pg(c.catalog,c.snapshot,r),m=n(u),h=this.buildSetOperations(c.catalog,r,m);await this.applyOperations(c.snapshot,h,s)})}catch(c){throw!(c instanceof yi)&&!(c instanceof Ja)&&xo.error("Failed to update setting",{settingId:r,error:c}),c}}async resetSetting(e,n={}){const s=this.requireSettingId(e);try{await this.enqueueWrite(async()=>{const r=await this.loadAuthoritativeState(),c=Gc(r.catalog,s);if(c.length===0)throw new Error(`No Catalog setting matches ID or namespace "${s}"`);await this.applyOperations(r.snapshot,c.map(u=>({op:"reset",settingId:u.id})),n)})}catch(r){throw!(r instanceof yi)&&!(r instanceof Ja)&&xo.error("Failed to reset setting",{settingId:s,error:r}),r}}onSettingChange(e){return this.listeners.add(e),this.ensureSnapshotSubscription(),()=>this.listeners.delete(e)}setConfirmationHandler(e){return this.confirmationHandler=e,()=>{this.confirmationHandler===e&&(this.confirmationHandler=null)}}watch(e,n){const s=this.requireSettingId(e),r=this.settingListeners.get(s)??new Set;return r.add(n),this.settingListeners.set(s,r),this.ensureSnapshotSubscription(),()=>{r.delete(n),r.size===0&&this.settingListeners.delete(s)}}async loadAuthoritativeState(){let[e,n]=await Promise.all([this.dependencies.catalog.load(),this.dependencies.snapshot.start()]);return n=this.dependencies.snapshot.getState().snapshot??n,e.version!==n.catalogVersion&&(e=await this.dependencies.catalog.ensureVersion(n.catalogVersion)),{catalog:e,snapshot:n}}enqueueWrite(e){const n=this.writeTail.then(e,e);return this.writeTail=n.catch(()=>{}),n}buildSetOperations(e,n,s){const r=Gc(e,n),c=r.find(m=>m.id===n);if(c){if(c.policy.sensitivity==="secret"&&ug(s))throw new Error(`Refusing to write a redacted secret setting "${n}"`);return[{op:"set",settingId:c.id,value:ir(s,n)}]}if(r.length===0)throw new Error(`No Catalog setting matches ID or namespace "${n}"`);if(s===null||typeof s!="object"||Array.isArray(s))throw new Error(`Setting namespace "${n}" must be written with an object`);const u=[];for(const m of r){const h=m.id.slice(n.length+1),f=AY(s,h);f.found&&(m.policy.sensitivity==="secret"&&ug(f.value)||u.push({op:"set",settingId:m.id,value:ir(f.value,m.id)}))}if(u.length===0)throw new Error(`Setting namespace "${n}" does not cover a writable Catalog setting`);return u}async applyOperations(e,n,s){const r=cg("config-plan"),c=cg("config-change"),u=await this.dependencies.transaction.plan({requestId:r,idempotencyKey:c,expectedRevision:e.revision,scope:e.scope,operations:n}),m={expectedRevision:e.revision,idempotencyKey:c};let h=s.confirmed===!0;if(u.requiresConfirmation&&!h){const y=new yi(u,m);if(!this.confirmationHandler)throw y;if(h=await this.confirmationHandler(y),!h)throw new Ja}const f=await this.dependencies.transaction.commit({...m,planId:u.planId,confirmed:h});await this.synchronizeSnapshot(f.revision)}async synchronizeSnapshot(e){let n=this.dependencies.snapshot.getState().snapshot;if((!n||n.revision[r.id,r]));for(const r of e.changedSettingIds){if(!s.get(r))throw new Error(`Accepted config snapshot references unknown setting "${r}" at revision ${e.snapshot.revision}`);const u=sr(e.previous,r),m=sr(e.snapshot,r);this.notifySettingChange(r,dg(u),dg(m))}}requireSettingId(e){const n=e.trim();if(!n)throw new Error("A non-empty Catalog setting ID or namespace is required");if(n!=="core"&&!n.startsWith("core."))throw new Error(`ConfigManager accepts only stable Catalog setting IDs or namespaces; received "${n}"`);return n}notifySettingChange(e,n,s){for(const r of this.listeners)try{r(e,n,s)}catch(c){xo.error("Setting change listener failed",{settingId:e,error:c})}for(const[r,c]of this.settingListeners)if(e===r||e.startsWith(`${r}.`)||r.startsWith(`${e}.`))for(const m of c)try{m()}catch(h){xo.error("Setting listener failed",{settingId:e,watchedSettingId:r,error:h})}}}const Tc=new TY,Dt=ft("I18nService"),Pc="core.app.language",PY=Object.assign({"../../../locales/en-US/common.json":ov,"../../../locales/en-US/components.json":Lv,"../../../locales/en-US/design-system/preview.json":Vv,"../../../locales/en-US/errors.json":ab,"../../../locales/en-US/flow-chat.json":zb,"../../../locales/en-US/flow-chat/chat-input.json":Zk,"../../../locales/en-US/flow-chat/design-canvas.json":oS,"../../../locales/en-US/flow-chat/session.json":LS,"../../../locales/en-US/flow-chat/tool-cards.json":Bx,"../../../locales/en-US/flow-chat/welcome.json":M1,"../../../locales/en-US/notifications.json":W1,"../../../locales/en-US/panels/files.json":Z1,"../../../locales/en-US/panels/git.json":F0,"../../../locales/en-US/panels/terminal.json":I0,"../../../locales/en-US/scenes/app-builder.json":W0,"../../../locales/en-US/scenes/apps.json":G0,"../../../locales/en-US/scenes/capabilities.json":gA,"../../../locales/en-US/scenes/daily-letter.json":FA,"../../../locales/en-US/scenes/files.json":VA,"../../../locales/en-US/scenes/memory.json":g_,"../../../locales/en-US/scenes/skills.json":T_,"../../../locales/en-US/scenes/subagents.json":O_,"../../../locales/en-US/scenes/tools.json":J_,"../../../locales/en-US/scenes/welcome.json":kT,"../../../locales/en-US/scenes/work-center.json":GT,"../../../locales/en-US/settings.json":hP,"../../../locales/en-US/settings/agentic-tools.json":_P,"../../../locales/en-US/settings/agents.json":LP,"../../../locales/en-US/settings/ai-features.json":KP,"../../../locales/en-US/settings/ai-mode.json":oF,"../../../locales/en-US/settings/ai-model.json":MF,"../../../locales/en-US/settings/ai-usage.json":VF,"../../../locales/en-US/settings/appearance.json":JF,"../../../locales/en-US/settings/basics.json":sR,"../../../locales/en-US/settings/config-center.json":yR,"../../../locales/en-US/settings/data-storage.json":FR,"../../../locales/en-US/settings/debug.json":OR,"../../../locales/en-US/settings/default-model.json":QR,"../../../locales/en-US/settings/editor.json":a2,"../../../locales/en-US/settings/keyboard.json":_2,"../../../locales/en-US/settings/mcp.json":H2,"../../../locales/en-US/settings/memory.json":X2,"../../../locales/en-US/settings/permissions.json":lN,"../../../locales/en-US/settings/personalization.json":yN,"../../../locales/en-US/settings/voice-input.json":TN,"../../../locales/en-US/shell/header.json":kD,"../../../locales/en-US/shell/navigation.json":KD,"../../../locales/en-US/shell/remote-connect.json":Pj,"../../../locales/en-US/tools.json":$j,"../../../locales/en-US/tray.json":Qj,"../../../locales/zh-CN/common.json":SE,"../../../locales/zh-CN/components.json":nL,"../../../locales/zh-CN/design-system/preview.json":uL,"../../../locales/zh-CN/errors.json":AL,"../../../locales/zh-CN/flow-chat.json":r$,"../../../locales/zh-CN/flow-chat/chat-input.json":yO,"../../../locales/zh-CN/flow-chat/design-canvas.json":SO,"../../../locales/zh-CN/flow-chat/session.json":n4,"../../../locales/zh-CN/flow-chat/tool-cards.json":i5,"../../../locales/zh-CN/flow-chat/welcome.json":X3,"../../../locales/zh-CN/notifications.json":aB,"../../../locales/zh-CN/panels/files.json":yB,"../../../locales/zh-CN/panels/git.json":KB,"../../../locales/zh-CN/panels/terminal.json":ZB,"../../../locales/zh-CN/scenes/app-builder.json":aW,"../../../locales/zh-CN/scenes/apps.json":pW,"../../../locales/zh-CN/scenes/capabilities.json":IW,"../../../locales/zh-CN/scenes/daily-letter.json":KW,"../../../locales/zh-CN/scenes/files.json":u8,"../../../locales/zh-CN/scenes/memory.json":I8,"../../../locales/zh-CN/scenes/skills.json":V8,"../../../locales/zh-CN/scenes/subagents.json":s6,"../../../locales/zh-CN/scenes/tools.json":h6,"../../../locales/zh-CN/scenes/welcome.json":B6,"../../../locales/zh-CN/scenes/work-center.json":pz,"../../../locales/zh-CN/settings.json":Mz,"../../../locales/zh-CN/settings/agentic-tools.json":qz,"../../../locales/zh-CN/settings/agents.json":nU,"../../../locales/zh-CN/settings/ai-features.json":mU,"../../../locales/zh-CN/settings/ai-mode.json":SU,"../../../locales/zh-CN/settings/ai-model.json":XU,"../../../locales/zh-CN/settings/ai-usage.json":uH,"../../../locales/zh-CN/settings/appearance.json":hH,"../../../locales/zh-CN/settings/basics.json":xH,"../../../locales/zh-CN/settings/config-center.json":EH,"../../../locales/zh-CN/settings/data-storage.json":KH,"../../../locales/zh-CN/settings/debug.json":s7,"../../../locales/zh-CN/settings/default-model.json":g7,"../../../locales/zh-CN/settings/editor.json":A7,"../../../locales/zh-CN/settings/keyboard.json":q7,"../../../locales/zh-CN/settings/mcp.json":c9,"../../../locales/zh-CN/settings/memory.json":w9,"../../../locales/zh-CN/settings/permissions.json":T9,"../../../locales/zh-CN/settings/personalization.json":E9,"../../../locales/zh-CN/settings/voice-input.json":V9,"../../../locales/zh-CN/shell/header.json":Bq,"../../../locales/zh-CN/shell/navigation.json":mV,"../../../locales/zh-CN/shell/remote-connect.json":GK,"../../../locales/zh-CN/tools.json":oQ,"../../../locales/zh-CN/tray.json":gQ}),FY=[{namespace:"flow-chat/chat-input",legacyNamespace:"flow-chat",legacyKey:"chatInput"},{namespace:"flow-chat/design-canvas",legacyNamespace:"flow-chat",legacyKey:"designCanvas"},{namespace:"flow-chat/session",legacyNamespace:"flow-chat",legacyKey:"session"},{namespace:"flow-chat/tool-cards",legacyNamespace:"flow-chat",legacyKey:"toolCards"},{namespace:"flow-chat/welcome",legacyNamespace:"flow-chat",legacyKey:"welcome"},{namespace:"scenes/app-builder",legacyNamespace:"common",legacyKey:"appBuilder"},{namespace:"scenes/memory",legacyNamespace:"common",legacyKey:"memoryLibrary"},{namespace:"scenes/work-center",legacyNamespace:"common",legacyKey:"workCenterScene"},{namespace:"scenes/welcome",legacyNamespace:"common",legacyKey:"welcomeScene"},{namespace:"settings/config-center",legacyNamespace:"settings",legacyKey:"configCenter"},{namespace:"settings/keyboard",legacyNamespace:"settings",legacyKey:"keyboard"},{namespace:"shell/header",legacyNamespace:"common",legacyKey:"header"},{namespace:"shell/navigation",legacyNamespace:"common",legacyKey:"nav"},{namespace:"shell/remote-connect",legacyNamespace:"common",legacyKey:"remoteConnect"}];function RY(i){return JSON.parse(JSON.stringify(i))}function NY(){const i=Object.fromEntries(fs.map(e=>[e.id,{}]));for(const[e,n]of Object.entries(PY)){const s=e.replace(/\\/g,"/"),r="/locales/",c=s.lastIndexOf(r);if(c<0)continue;const u=s.slice(c+r.length),[m,...h]=u.split("/"),f=h.join("/").replace(/\.json$/,"");er(m)&&Hg.includes(f)&&(i[m][f]=n)}for(const e of fs){const n=i[e.id];for(const s of FY){const r=n[s.namespace];if(!r)continue;const c=n[s.legacyNamespace]??{};n[s.legacyNamespace]={...c,[s.legacyKey]:RY(r)}}}return i}const DY=NY();class IY{i18nInstance;currentLocaleId=Xa;listeners=new Map;hooks={};initialized=!1;configWatchCleanup=null;configRefreshSeq=0;localeChangeSeq=0;constructor(){this.i18nInstance=vt.createInstance(),this.i18nInstance.use(xw).init({resources:DY,lng:Xa,fallbackLng:Ug,defaultNS:yQ,ns:[...Hg],interpolation:{escapeValue:!1},react:{useSuspense:!1}})}async initialize(){if(this.initialized){Dt.debug("Already initialized, skipping");return}try{let e=Xa;const n=document.documentElement.getAttribute("lang");n&&er(n)&&(Dt.debug("Using pre-injected locale",{locale:n}),e=n),e!==this.currentLocaleId&&(await this.i18nInstance.changeLanguage(e),this.currentLocaleId=e);const s=di.getState();s.setCurrentLanguage(this.currentLocaleId),s.setInitialized(!0),this.updateHtmlLang(this.currentLocaleId),this.initialized=!0,Dt.info("Initialization completed",{locale:this.currentLocaleId});const r=this.localeChangeSeq,c=this.currentLocaleId;this.ensureConfigWatch(),this.refreshLocaleFromConfig(r,c)}catch(e){Dt.error("Initialization failed",e),this.initialized=!0,di.getState().setInitialized(!0),this.ensureConfigWatch()}}async refreshLocaleFromConfig(e,n){const s=++this.configRefreshSeq;try{const r=await this.loadCurrentLocale();if(s!==this.configRefreshSeq||!r||r===this.currentLocaleId||e!==void 0&&(this.localeChangeSeq!==e||this.currentLocaleId!==n))return;await this.changeLanguage(r,{persist:!1})}catch(r){Dt.error("Failed to apply authoritative locale",{error:r})}}ensureConfigWatch(){this.configWatchCleanup||(this.configWatchCleanup=Tc.watch(Pc,()=>{this.refreshLocaleFromConfig()}))}async loadCurrentLocale(){try{const e=new Promise(s=>{setTimeout(()=>s(null),2e3)}),n=await Promise.race([Tc.getSetting(Pc),e]);return n&&er(n)?n:null}catch(e){return Dt.debug("Failed to load locale config (ignored)",e),null}}async saveCurrentLocale(e){try{await Tc.setSetting(Pc,e)}catch(n){Dt.warn("Failed to save locale config",{locale:e,error:n})}}getI18nInstance(){return this.i18nInstance}getT(){return this.i18nInstance.t.bind(this.i18nInstance)}getCurrentLocale(){return this.currentLocaleId}getCurrentLocaleMetadata(){return fs.find(e=>e.id===this.currentLocaleId)}getSupportedLocales(){return fs}async changeLanguage(e,n={}){if(!er(e))throw Dt.error("Unsupported locale",{locale:e}),new Error(`Unsupported locale: ${e}`);if(e===this.currentLocaleId){Dt.debug("Locale unchanged, skipping",{locale:e});return}const s=this.currentLocaleId,r=di.getState();try{this.localeChangeSeq+=1,r.setChanging(!0),this.hooks.beforeChange&&await this.hooks.beforeChange(e,s),this.emitEvent("i18n:before-change",e,s),await this.i18nInstance.changeLanguage(e),this.currentLocaleId=e,this.updateHtmlLang(e),r.setCurrentLanguage(e),(n.persist??!0)&&await this.saveCurrentLocale(e),this.hooks.afterChange&&await this.hooks.afterChange(e,s),this.emitEvent("i18n:after-change",e,s),Dt.info("Language changed",{locale:e,previousLocale:s})}catch(c){throw Dt.error("Failed to change language",{locale:e,error:c}),this.emitEvent("i18n:error",e,s,void 0,c),c}finally{r.setChanging(!1)}}updateHtmlLang(e){document.documentElement.setAttribute("lang",e),fs.find(s=>s.id===e)?.rtl?document.documentElement.setAttribute("dir","rtl"):document.documentElement.setAttribute("dir","ltr")}async loadNamespace(e){const n=di.getState();if(!n.loadedNamespaces.includes(e))try{await this.i18nInstance.loadNamespaces(e),n.addLoadedNamespace(e),this.emitEvent("i18n:namespace-loaded",this.currentLocaleId,void 0,e)}catch(s){throw Dt.error("Failed to load namespace",{namespace:e,error:s}),s}}isNamespaceLoaded(e){return di.getState().loadedNamespaces.includes(e)}t(e,n){return this.i18nInstance.t(e,{...n,returnObjects:!1})}exists(e){return this.i18nInstance.exists(e)}formatDate(e,n){return new Intl.DateTimeFormat(this.currentLocaleId,n).format(e)}formatNumber(e,n){return new Intl.NumberFormat(this.currentLocaleId,n).format(e)}formatCurrency(e,n="CNY"){return this.formatNumber(e,{style:"currency",currency:n})}formatRelativeTime(e,n){const s=new Intl.RelativeTimeFormat(this.currentLocaleId,{numeric:"auto"}),r=Date.now(),u=(typeof e=="number"?e:e.getTime())-r,m=Math.round(u/1e3),h=Math.round(u/6e4),f=Math.round(u/36e5),y=Math.round(u/864e5);return n?s.format(Math.round(u/this.getUnitMilliseconds(n)),n):Math.abs(m)<60?s.format(m,"second"):Math.abs(h)<60?s.format(h,"minute"):Math.abs(f)<24?s.format(f,"hour"):s.format(y,"day")}getUnitMilliseconds(e){switch(e){case"second":return 1e3;case"minute":return 6e4;case"hour":return 36e5;case"day":return 864e5;case"week":return 6048e5;case"month":return 2592e6;case"year":return 31536e6;default:return 1e3}}on(e,n){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n),()=>{this.listeners.get(e)?.delete(n)}}emitEvent(e,n,s,r,c){const u={type:e,locale:n,previousLocale:s,namespace:r,error:c,timestamp:Date.now()},m=this.listeners.get(e);m&&m.forEach(h=>{try{h(u)}catch(f){Dt.error("Event listener execution failed",{eventType:e,error:f})}})}registerHooks(e){this.hooks={...this.hooks,...e}}isInitialized(){return this.initialized}isRTL(){return this.getCurrentLocaleMetadata()?.rtl??!1}}const ar=new IY;const MY=i=>i.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),jY=i=>i.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,n,s)=>s?s.toUpperCase():n.toLowerCase()),mg=i=>{const e=jY(i);return e.charAt(0).toUpperCase()+e.slice(1)},Xg=(...i)=>i.filter((e,n,s)=>!!e&&e.trim()!==""&&s.indexOf(e)===n).join(" ").trim(),EY=i=>{for(const e in i)if(e.startsWith("aria-")||e==="role"||e==="title")return!0};var LY={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const $Y=k.forwardRef(({color:i="currentColor",size:e=24,strokeWidth:n=2,absoluteStrokeWidth:s,className:r="",children:c,iconNode:u,...m},h)=>k.createElement("svg",{ref:h,...LY,width:e,height:e,stroke:i,strokeWidth:s?Number(n)*24/Number(e):n,className:Xg("lucide",r),...!c&&!EY(m)&&{"aria-hidden":"true"},...m},[...u.map(([f,y])=>k.createElement(f,y)),...Array.isArray(c)?c:[c]]));const ye=(i,e)=>{const n=k.forwardRef(({className:s,...r},c)=>k.createElement($Y,{ref:c,iconNode:e,className:Xg(`lucide-${MY(mg(i))}`,`lucide-${i}`,s),...r}));return n.displayName=mg(i),n};const OY=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],BY=ye("arrow-right",OY);const WY=[["path",{d:"M10 22V7a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5a1 1 0 0 0-1-1H2",key:"1ah6g2"}],["rect",{x:"14",y:"2",width:"8",height:"8",rx:"1",key:"88lufb"}]],zY=ye("blocks",WY);const UY=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]],HY=ye("book-open",UY);const qY=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],gg=ye("bot",qY);const VY=[["path",{d:"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z",key:"hh9hay"}],["path",{d:"m3.3 7 8.7 5 8.7-5",key:"g66t2b"}],["path",{d:"M12 22V12",key:"d0xqtd"}]],GY=ye("box",VY);const KY=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],QY=ye("chart-column",KY);const JY=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],xs=ye("check",JY);const YY=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],no=ye("chevron-down",YY);const ZY=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],gd=ye("chevron-left",ZY);const XY=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],oo=ye("chevron-right",XY);const eZ=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],tZ=ye("chevron-up",eZ);const nZ=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],oZ=ye("circle-check",nZ);const sZ=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],iZ=ye("circle-x",sZ);const aZ=[["path",{d:"M12 6v6l4 2",key:"mmk7yg"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],eh=ye("clock",aZ);const rZ=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],th=ye("copy",rZ);const lZ=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"22",x2:"18",y1:"12",y2:"12",key:"l9bcsi"}],["line",{x1:"6",x2:"2",y1:"12",y2:"12",key:"13hhkx"}],["line",{x1:"12",x2:"12",y1:"6",y2:"2",key:"10w3f3"}],["line",{x1:"12",x2:"12",y1:"22",y2:"18",key:"15g9kq"}]],cZ=ye("crosshair",lZ);const dZ=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],uZ=ye("download",dZ);const pZ=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],mZ=ye("ellipsis",pZ);const gZ=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],hZ=ye("eye",gZ);const fZ=[["path",{d:"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4",key:"1pf5j1"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"m5 12-3 3 3 3",key:"oke12k"}],["path",{d:"m9 18 3-3-3-3",key:"112psh"}]],Kc=ye("file-code-2",fZ);const yZ=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M9 15h6",key:"cctwl0"}],["path",{d:"M12 18v-6",key:"17g6i2"}]],wZ=ye("file-plus",yZ);const vZ=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}]],bZ=ye("file",vZ);const kZ=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M7 3v18",key:"bbkbws"}],["path",{d:"M3 7.5h4",key:"zfgn84"}],["path",{d:"M3 12h18",key:"1i2n21"}],["path",{d:"M3 16.5h4",key:"1230mu"}],["path",{d:"M17 3v18",key:"in4fa5"}],["path",{d:"M17 7.5h4",key:"myr1c1"}],["path",{d:"M17 16.5h4",key:"go4c1d"}]],SZ=ye("film",kZ);const xZ=[["path",{d:"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2",key:"usdka0"}]],bi=ye("folder-open",xZ);const CZ=[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],AZ=ye("folder",CZ);const _Z=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],TZ=ye("funnel",_Z);const PZ=[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]],Qc=ye("git-branch",PZ);const FZ=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M3 15h18",key:"5xshup"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]],RZ=ye("grid-3x3",FZ);const NZ=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]],DZ=ye("history",NZ);const IZ=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],MZ=ye("info",IZ);const jZ=[["path",{d:"m5 8 6 6",key:"1wu5hv"}],["path",{d:"m4 14 6-6 2-3",key:"1k1g8d"}],["path",{d:"M2 5h12",key:"or177f"}],["path",{d:"M7 2h1",key:"1t2jsx"}],["path",{d:"m22 22-5-10-5 10",key:"don7ne"}],["path",{d:"M14 18h6",key:"1m8k6r"}]],EZ=ye("languages",jZ);const LZ=[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]],$Z=ye("layers",LZ);const OZ=[["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M3 18h.01",key:"1tta3j"}],["path",{d:"M3 6h.01",key:"1rqtza"}],["path",{d:"M8 12h13",key:"1za7za"}],["path",{d:"M8 18h13",key:"1lx6n3"}],["path",{d:"M8 6h13",key:"ik3vkj"}]],BZ=ye("list",OZ);const WZ=[["path",{d:"M5 12h14",key:"1ays0h"}]],nh=ye("minus",WZ);const zZ=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],UZ=ye("palette",zZ);const HZ=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"m16 15-3-3 3-3",key:"14y99z"}]],qZ=ye("panel-left-close",HZ);const VZ=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M15 3v18",key:"14nvp0"}],["path",{d:"m10 15-3-3 3-3",key:"1pgupc"}]],GZ=ye("panel-right-open",VZ);const KZ=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],QZ=ye("play",KZ);const JZ=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],oh=ye("plus",JZ);const YZ=[["path",{d:"M2 3h20",key:"91anmk"}],["path",{d:"M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3",key:"2k9sn8"}],["path",{d:"m7 21 5-5 5 5",key:"bip4we"}]],ZZ=ye("presentation",YZ);const XZ=[["path",{d:"m15 14 5-5-5-5",key:"12vg1m"}],["path",{d:"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13",key:"6uklza"}]],eX=ye("redo-2",XZ);const tX=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],hd=ye("refresh-cw",tX);const nX=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],oX=ye("save",nX);const sX=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],fd=ye("search",sX);const iX=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],aX=ye("settings-2",iX);const rX=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],lX=ye("shield-check",rX);const cX=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],dX=ye("smartphone",cX);const uX=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],Jc=ye("sparkles",uX);const pX=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],sh=ye("square",pX);const mX=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 3v1",key:"1asbbs"}],["path",{d:"M12 20v1",key:"1wcdkc"}],["path",{d:"M3 12h1",key:"lp3yf2"}],["path",{d:"M20 12h1",key:"1vloll"}],["path",{d:"m18.364 5.636-.707.707",key:"1hakh0"}],["path",{d:"m6.343 17.657-.707.707",key:"18m9nf"}],["path",{d:"m5.636 5.636.707.707",key:"1xv1c5"}],["path",{d:"m17.657 17.657.707.707",key:"vl76zb"}]],gX=ye("sun-medium",mX);const hX=[["path",{d:"M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18",key:"gugj83"}]],fX=ye("table-2",hX);const yX=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],ih=ye("terminal",yX);const wX=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],vX=ye("trash-2",wX);const bX=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],kX=ye("triangle-alert",bX);const SX=[["path",{d:"M9 14 4 9l5-5",key:"102s5s"}],["path",{d:"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",key:"f3b9sd"}]],xX=ye("undo-2",SX);const CX=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],ah=ye("wrench",CX);const AX=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Cs=ye("x",AX);function rh(i){return i??16}const _X=k.forwardRef(({size:i,strokeWidth:e=1.8,...n},s)=>{const r=rh(i);return l.jsxs("svg",{ref:s,width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:e,strokeLinecap:"round",strokeLinejoin:"round",xmlns:"http://www.w3.org/2000/svg",...n,children:[l.jsx("rect",{x:"4",y:"3.5",width:"16",height:"17",rx:"4.5"}),l.jsx("ellipse",{cx:"12",cy:"12",rx:"4.4",ry:"5.8",transform:"rotate(24 12 12)"}),l.jsx("path",{d:"M8.5 7.5h7"}),l.jsx("path",{d:"M8.5 16.7h7"})]})});_X.displayName="SparoAgentIcon";const TX=k.forwardRef(({size:i,strokeWidth:e=1.8,...n},s)=>{const r=rh(i);return l.jsxs("svg",{ref:s,width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:e,strokeLinecap:"round",strokeLinejoin:"round",xmlns:"http://www.w3.org/2000/svg",...n,children:[l.jsx("rect",{x:"3.5",y:"4.5",width:"12.5",height:"14",rx:"3.6"}),l.jsx("ellipse",{cx:"9.8",cy:"11.6",rx:"3",ry:"4",transform:"rotate(24 9.8 11.6)"}),l.jsx("path",{d:"M16 11h1.6c1.4 0 2.6 1.1 2.6 2.5v.2"}),l.jsx("rect",{x:"15.7",y:"13.2",width:"5.3",height:"5.8",rx:"1.7"})]})});TX.displayName="SparoSubagentIcon";const ki=k.forwardRef(({size:i=24,strokeWidth:e=6.5,...n},s)=>l.jsxs("svg",{ref:s,width:i,height:i,viewBox:"-3 -3 88 106",fill:"none",stroke:"currentColor",strokeWidth:e,strokeLinecap:"round",strokeLinejoin:"round",xmlns:"http://www.w3.org/2000/svg",focusable:"false",...n,children:[l.jsx("path",{d:"M52.3 2.7C40.8 4.9 25.5 13.4 16.4 24.8C6.3 37.6 1.4 52.7 2.8 66.9C4.4 82.5 12.9 94.2 25.7 98.1C39.1 102.2 53.2 95.4 63.9 84.5C75.7 72.3 82.2 55.2 79.2 42.3C77.4 34.4 73.3 29.4 67.6 24.7C61.4 19.5 58.6 15 57.7 8.5C56.9 3.3 55 2.2 52.3 2.7Z"}),l.jsx("path",{d:"M52.4 34.4C44.2 33.2 35.5 41 31.2 52.2C26.4 64.7 28.9 74.2 35.9 76.6C43.4 79.1 52.3 72.2 56.6 62.3C61 52.2 60.4 41.8 55 36.5C54.1 35.6 53.2 34.9 52.4 34.4Z"})]}));ki.displayName="SparoLogoMark";const PX=[{id:"sparo-hub",family:"system",componentName:"SparoHubIcon",label:"Sparo Hub",labelZh:"Sparo Hub",tags:["home","hub","workspace","首页","工作区"]},{id:"work-center",family:"system",componentName:"WorkCenterIcon",label:"Work Center",labelZh:"工作中心",tags:["work","task","folder","工作","任务"]},{id:"app-center",family:"system",componentName:"AppCenterIcon",label:"App Center",labelZh:"应用中心",tags:["app","grid","product","应用","产品"]},{id:"daily-letter",family:"system",componentName:"DailyLetterIcon",label:"Daily Letter",labelZh:"每日来信",tags:["mail","letter","daily","邮件","来信"]},{id:"memory",family:"system",componentName:"MemoryIcon",label:"Memory",labelZh:"记忆",tags:["memory","spiral","context","记忆","上下文"]},{id:"files",family:"system",componentName:"FilesIcon",label:"Files",labelZh:"文件",tags:["files","folder","workspace","文件","目录"]},{id:"terminal",family:"system",componentName:"TerminalIcon",label:"Terminal",labelZh:"终端",tags:["terminal","shell","command","终端","命令"]},{id:"skills",family:"system",componentName:"SkillsIcon",label:"Skills",labelZh:"技能",tags:["skill","puzzle","capability","技能","能力"]},{id:"tools",family:"system",componentName:"ToolsIcon",label:"Tools",labelZh:"工具",tags:["tool","wrench","utility","工具"]},{id:"subagent",family:"system",componentName:"SubagentIcon",label:"Subagent",labelZh:"子智能体",tags:["agent","subagent","delegation","智能体","子智能体"]},{id:"settings",family:"system",componentName:"SettingsIcon",label:"Settings",labelZh:"设置",tags:["settings","gear","preferences","设置","偏好"]},{id:"full-open",family:"system",componentName:"FullOpenIcon",label:"Open Full",labelZh:"完整打开",tags:["open","expand","focus","打开","展开"]},{id:"normal-work",family:"work-type",componentName:"NormalWorkIcon",label:"Normal Work",labelZh:"普通工作",tags:["work","task","normal","standard","普通","工作"]},{id:"multi-step-work",family:"work-type",componentName:"MultiStepWorkIcon",label:"Multi-step Work",labelZh:"多步骤工作",tags:["workflow","steps","sequence","多步骤","流程"]},{id:"long-running-work",family:"work-type",componentName:"LongRunningWorkIcon",label:"Long-running Work",labelZh:"长期工作",tags:["long-running","continuous","infinity","长期","持续"]},{id:"topic-work",family:"work-type",componentName:"TopicWorkIcon",label:"Topic Work",labelZh:"主题工作",tags:["topic","folder","bookmark","主题","专题"]},{id:"recurring-work",family:"work-type",componentName:"RecurringWorkIcon",label:"Recurring Work",labelZh:"周期工作",tags:["recurring","schedule","calendar","周期","定时"]},{id:"intelligent-app-work",family:"work-type",componentName:"IntelligentAppWorkIcon",label:"Intelligent App Work",labelZh:"智能应用工作",tags:["intelligent app","product app","agentic","智能应用"]},{id:"delegated-work",family:"work-type",componentName:"DelegatedWorkIcon",label:"Delegated Work",labelZh:"委派工作",tags:["delegated","handoff","transfer","委派","转交"]},{id:"system-work",family:"work-type",componentName:"SystemWorkIcon",label:"System Work",labelZh:"系统工作",tags:["system","background","orbit","系统","后台"]},{id:"back",family:"navigation",componentName:"BackIcon",label:"Back",labelZh:"返回",tags:["back","previous","left","arrow","返回","后退","导航"]},{id:"forward",family:"navigation",componentName:"ForwardIcon",label:"Forward / Enter",labelZh:"前进 / 进入",tags:["forward","next","enter","right","arrow","前进","进入","导航"]},{id:"external-open",family:"navigation",componentName:"ExternalOpenIcon",label:"Open Externally",labelZh:"外部打开",tags:["external","open","outbound","link","外部打开","新窗口","导航"]},{id:"expand",family:"navigation",componentName:"ExpandIcon",label:"Expand",labelZh:"展开",tags:["expand","unfold","down","chevron","展开","下拉","导航"]},{id:"collapse",family:"navigation",componentName:"CollapseIcon",label:"Collapse",labelZh:"收起",tags:["collapse","fold","up","chevron","收起","折叠","导航"]},{id:"close",family:"navigation",componentName:"CloseIcon",label:"Close",labelZh:"关闭",tags:["close","dismiss","remove","x","关闭","退出","导航"]},{id:"search",family:"search-filter",componentName:"SearchIcon",label:"Search",labelZh:"搜索",tags:["search","find","magnifier","lookup","搜索","查找","检索"]},{id:"clear",family:"search-filter",componentName:"ClearIcon",label:"Clear",labelZh:"清除",tags:["clear","erase","remove filter","清除","擦除","清空"]},{id:"filter",family:"search-filter",componentName:"FilterIcon",label:"Filter",labelZh:"筛选",tags:["filter","funnel","narrow","筛选","过滤","条件"]},{id:"sort",family:"search-filter",componentName:"SortIcon",label:"Sort",labelZh:"排序",tags:["sort","order","ascending","descending","排序","升序","降序"]},{id:"open-directory",family:"files-transfer",componentName:"OpenDirectoryIcon",label:"Open Directory",labelZh:"打开目录",tags:["folder","directory","open","文件夹","目录","打开"]},{id:"upload",family:"files-transfer",componentName:"UploadIcon",label:"Upload / Import",labelZh:"上传 / 导入",tags:["upload","import","transfer","上传","导入","传输"]},{id:"download",family:"files-transfer",componentName:"DownloadIcon",label:"Download / Install",labelZh:"下载 / 安装",tags:["download","install","transfer","下载","安装","传输"]},{id:"export",family:"files-transfer",componentName:"ExportIcon",label:"Export",labelZh:"导出",tags:["export","document","transfer","导出","文件","转换"]},{id:"copy",family:"files-transfer",componentName:"CopyIcon",label:"Copy",labelZh:"复制",tags:["copy","duplicate","clipboard","复制","副本","克隆"]},{id:"add",family:"edit-manage",componentName:"AddIcon",label:"Add",labelZh:"添加",tags:["add","create","plus","添加","新建","创建"]},{id:"edit",family:"edit-manage",componentName:"EditIcon",label:"Edit",labelZh:"编辑",tags:["edit","pencil","modify","编辑","修改","铅笔"]},{id:"delete",family:"edit-manage",componentName:"DeleteIcon",label:"Delete",labelZh:"删除",tags:["delete","trash","remove","删除","垃圾桶","移除"]},{id:"save-apply",family:"edit-manage",componentName:"SaveApplyIcon",label:"Save / Apply",labelZh:"保存 / 应用",tags:["save","apply","confirm","保存","应用","确认"]},{id:"cancel",family:"edit-manage",componentName:"CancelIcon",label:"Cancel",labelZh:"取消",tags:["cancel","dismiss","x","取消","放弃","关闭"]},{id:"reset",family:"edit-manage",componentName:"ResetIcon",label:"Reset",labelZh:"重置",tags:["reset","restore","frame","重置","恢复","重新设置"]},{id:"undo",family:"edit-manage",componentName:"UndoIcon",label:"Undo",labelZh:"撤销",tags:["undo","back","history","撤销","回退","历史"]},{id:"refresh",family:"edit-manage",componentName:"RefreshIcon",label:"Refresh",labelZh:"刷新",tags:["refresh","sync","reload","刷新","同步","重新加载"]},{id:"retry",family:"edit-manage",componentName:"RetryIcon",label:"Retry",labelZh:"重试",tags:["retry","again","repeat","重试","再次","重新执行"]}],lh=["sparo-hub","work-center","app-center","daily-letter","memory","files","terminal","skills","tools","subagent","settings","full-open","normal-work","multi-step-work","long-running-work","topic-work","recurring-work","intelligent-app-work","delegated-work","system-work","back","forward","external-open","expand","collapse","close","search","clear","filter","sort","open-directory","upload","download","export","copy","add","edit","delete","save-apply","cancel","reset","undo","refresh","retry"],FX=new Set(lh);for(const i of PX)if(!FX.has(i.id))throw new Error(`Unknown Sparo system icon in metadata: ${i.id}`);const Co=48,RX=64,NX=2,hg=.78,fg=5.28,DX=22,Ya=2,yg=10,IX=22,MX=`\r + \r + \r +\r +`,jX=`\r + \r + \r + \r + \r +\r +`,EX=`\r + \r + \r + \r + \r +\r +`,LX=`\r + \r + \r +\r +`,$X=`\r + \r +\r +`,OX=`\r + \r + \r +\r +`,BX=`\r + \r + \r + \r +\r +`,WX=`\r + \r +\r +`,zX=`\r + \r +\r +`,UX=`\r + \r + \r + \r + \r +\r +`,HX=`\r + \r + \r +\r +`,qX=`\r + \r + \r + \r + \r +\r +`,VX=`\r + \r + \r + \r +\r +`,GX=`\r + \r + \r + \r + \r + \r +\r +`,KX=`\r + \r + \r + \r +\r +`,QX=`\r + \r + \r +\r +`,JX=`\r + \r + \r + \r + \r + \r +\r +`,YX=`\r + \r + \r +\r +`,ZX=`\r + \r + \r + \r + \r +\r +`,XX=`\r + \r + \r + \r +\r +`,eee=`\r + \r + \r +\r +`,tee=`\r + \r + \r +\r +`,nee=`\r + \r + \r + \r +\r +`,oee=`\r + \r + \r +\r +`,see=`\r + \r + \r +\r +`,iee=`\r + \r + \r +\r +`,aee=`\r + \r + \r +\r +`,ree=`\r + \r + \r + \r +\r +`,lee=`\r + \r + \r + \r +\r +`,cee=`\r + \r + \r + \r + \r + \r + \r + \r +\r +`,dee=`\r + \r + \r +\r +`,uee=`\r + \r + \r + \r +\r +`,pee=`\r + \r + \r + \r +\r +`,mee=`\r + \r + \r + \r + \r + \r + \r + \r + \r + \r + \r + \r + \r +\r +`,gee=`\r + \r + \r +\r +`,hee=`\r + \r + \r + \r + \r +\r +`,fee=`\r + \r + \r + \r + \r +\r +`,yee=`\r + \r + \r + \r + \r + \r + \r +\r +`,wee=`\r + \r + \r +\r +`,vee=`\r + \r + \r +\r +`,bee=`\r + \r + \r + \r + \r + \r + \r +\r +`,kee=`\r + \r + \r +\r +`,See=`\r + \r + \r + \r + \r +\r +`,xee=`\r + \r + \r +\r +`,Cee={"sparo-hub":MX,"work-center":jX,"app-center":EX,"daily-letter":LX,memory:$X,files:OX,terminal:BX,skills:WX,tools:zX,subagent:UX,settings:HX,"full-open":qX,"normal-work":VX,"multi-step-work":GX,"long-running-work":KX,"topic-work":QX,"recurring-work":JX,"intelligent-app-work":YX,"delegated-work":ZX,"system-work":XX,back:eee,forward:tee,"external-open":nee,expand:oee,collapse:see,close:iee,search:aee,clear:ree,filter:lee,sort:cee,"open-directory":dee,upload:uee,download:pee,export:mee,copy:gee,add:hee,edit:fee,delete:yee,"save-apply":wee,cancel:vee,reset:bee,undo:kee,refresh:See,retry:xee};function Aee(i){const e=i.match(/]*>([\s\S]*)<\/svg>/);if(!e)throw new Error("Invalid canonical Sparo icon SVG.");return e[1].trim()}const _ee=Object.fromEntries(Object.entries(Cee).map(([i,e])=>[i,Aee(e)])),ch=k.forwardRef(({name:i,variant:e="base",size:n=RX,color:s="currentColor",backgroundColor:r="#d9231b",backgroundShape:c="circle",backgroundRadius:u=yg,strokeWidth:m=NX,absoluteStrokeWidth:h=!1,title:f,className:y,style:v,"aria-label":b,...S},A)=>{const F=k.useId(),_=!!(f||b),E=typeof n=="number"?n:null,j=h&&E?m*(Co/E):m,z=j/hg,B=Number.isFinite(u)?Math.min(Math.max(u,0),IX):yg,W=_ee[i];return l.jsxs("svg",{...S,ref:A,className:y,width:n,height:n,viewBox:`0 0 ${Co} ${Co}`,fill:"none",focusable:"false",role:_?"img":void 0,"aria-hidden":_?void 0:!0,"aria-label":b,"aria-labelledby":!b&&f?F:void 0,"data-sparo-icon":i,"data-sparo-variant":e,style:{display:"block",flexShrink:0,...v},children:[f?l.jsx("title",{id:F,children:f}):null,e==="emphasis"?l.jsxs(l.Fragment,{children:[c==="circle"?l.jsx("circle",{cx:Co/2,cy:Co/2,r:DX,fill:r}):l.jsx("rect",{x:Ya,y:Ya,width:Co-Ya*2,height:Co-Ya*2,rx:B,fill:r}),l.jsx("g",{transform:`translate(${fg} ${fg}) scale(${hg})`,stroke:s,strokeWidth:z,strokeLinecap:"round",strokeLinejoin:"round",dangerouslySetInnerHTML:{__html:W}})]}):l.jsx("g",{stroke:s,strokeWidth:j,strokeLinecap:"round",strokeLinejoin:"round",dangerouslySetInnerHTML:{__html:W}})]})});ch.displayName="SparoSystemIcon";function vs(i,e){Object.entries(e).forEach(([n,s])=>{i.style.setProperty(n,s)})}function dh(i){const{colors:e}=i,n={},s=i.components?.button;if(s)n["--btn-default-bg"]=s.default.background,n["--btn-default-color"]=s.default.color,n["--btn-default-border"]=s.default.border,n["--btn-default-shadow"]=s.default.shadow||"none",n["--btn-default-hover-bg"]=s.hover.background,n["--btn-default-hover-color"]=s.hover.color,n["--btn-default-hover-border"]=s.hover.border,n["--btn-default-hover-shadow"]=s.hover.shadow||"none",n["--btn-default-hover-transform"]=s.hover.transform||"none",n["--btn-default-active-bg"]=s.active.background,n["--btn-default-active-color"]=s.active.color,n["--btn-default-active-border"]=s.active.border,n["--btn-default-active-shadow"]=s.active.shadow||"none",n["--btn-default-active-transform"]=s.active.transform||"none",n["--btn-primary-bg"]=s.primary.default.background,n["--btn-primary-color"]=s.primary.default.color,n["--btn-primary-border"]=s.primary.default.border,n["--btn-primary-shadow"]=s.primary.default.shadow||"none",n["--btn-primary-hover-bg"]=s.primary.hover.background,n["--btn-primary-hover-color"]=s.primary.hover.color,n["--btn-primary-hover-border"]=s.primary.hover.border,n["--btn-primary-hover-shadow"]=s.primary.hover.shadow||"none",n["--btn-primary-hover-transform"]=s.primary.hover.transform||"none",n["--btn-primary-active-bg"]=s.primary.active.background,n["--btn-primary-active-color"]=s.primary.active.color,n["--btn-primary-active-border"]=s.primary.active.border,n["--btn-primary-active-shadow"]=s.primary.active.shadow||"none",n["--btn-primary-active-transform"]=s.primary.active.transform||"none",n["--btn-ghost-bg"]=s.ghost.default.background,n["--btn-ghost-color"]=s.ghost.default.color,n["--btn-ghost-border"]=s.ghost.default.border,n["--btn-ghost-shadow"]=s.ghost.default.shadow||"none",n["--btn-ghost-hover-bg"]=s.ghost.hover.background,n["--btn-ghost-hover-color"]=s.ghost.hover.color,n["--btn-ghost-hover-border"]=s.ghost.hover.border,n["--btn-ghost-hover-shadow"]=s.ghost.hover.shadow||"none",n["--btn-ghost-hover-transform"]=s.ghost.hover.transform||"none",n["--btn-ghost-active-bg"]=s.ghost.active.background,n["--btn-ghost-active-color"]=s.ghost.active.color,n["--btn-ghost-active-border"]=s.ghost.active.border,n["--btn-ghost-active-shadow"]=s.ghost.active.shadow||"none",n["--btn-ghost-active-transform"]=s.ghost.active.transform||"none";else{const c=e.accent;n["--btn-default-bg"]=e.element.base,n["--btn-default-color"]=e.text.secondary,n["--btn-default-border"]=e.border.base,n["--btn-default-shadow"]="none",n["--btn-default-hover-bg"]=e.element.medium,n["--btn-default-hover-color"]=e.text.primary,n["--btn-default-hover-border"]=e.border.medium,n["--btn-default-hover-shadow"]="none",n["--btn-default-hover-transform"]="none",n["--btn-primary-bg"]=c[200],n["--btn-primary-color"]=c[600],n["--btn-primary-border"]="transparent",n["--btn-primary-shadow"]="none",n["--btn-primary-hover-bg"]=c[300],n["--btn-primary-hover-color"]=e.text.primary,n["--btn-primary-hover-border"]="transparent",n["--btn-primary-hover-shadow"]="none",n["--btn-primary-hover-transform"]="none",n["--btn-primary-active-bg"]=c[200],n["--btn-primary-active-color"]=e.text.primary,n["--btn-primary-active-border"]="transparent",n["--btn-primary-active-shadow"]="none",n["--btn-primary-active-transform"]="none"}const r=i.components?.windowControls;return r?(n["--window-control-minimize-dot"]=r.minimize.dot,n["--window-control-minimize-dot-shadow"]=r.minimize.dotShadow||"none",n["--window-control-minimize-hover-bg"]=r.minimize.hoverBg,n["--window-control-minimize-hover-color"]=r.minimize.hoverColor,n["--window-control-minimize-hover-border"]=r.minimize.hoverBorder,n["--window-control-minimize-hover-shadow"]=r.minimize.hoverShadow||"none",n["--window-control-maximize-dot"]=r.maximize.dot,n["--window-control-maximize-dot-shadow"]=r.maximize.dotShadow||"none",n["--window-control-maximize-hover-bg"]=r.maximize.hoverBg,n["--window-control-maximize-hover-color"]=r.maximize.hoverColor,n["--window-control-maximize-hover-border"]=r.maximize.hoverBorder,n["--window-control-maximize-hover-shadow"]=r.maximize.hoverShadow||"none",n["--window-control-close-dot"]=r.close.dot,n["--window-control-close-dot-shadow"]=r.close.dotShadow||"none",n["--window-control-close-hover-bg"]=r.close.hoverBg,n["--window-control-close-hover-color"]=r.close.hoverColor,n["--window-control-close-hover-border"]=r.close.hoverBorder,n["--window-control-close-hover-shadow"]=r.close.hoverShadow||"none",n["--window-control-default-color"]=r.common.defaultColor,n["--window-control-default-dot"]=r.common.defaultDot,n["--window-control-disabled-dot"]=r.common.disabledDot,n["--window-control-flow-gradient"]=r.common.flowGradient||"none"):(n["--window-control-minimize-dot"]=e.accent[400],n["--window-control-minimize-dot-shadow"]="none",n["--window-control-minimize-hover-bg"]=e.accent[100],n["--window-control-minimize-hover-color"]=e.accent[500],n["--window-control-minimize-hover-border"]=e.accent[200],n["--window-control-minimize-hover-shadow"]="none",n["--window-control-maximize-dot"]=e.accent[400],n["--window-control-maximize-dot-shadow"]="none",n["--window-control-maximize-hover-bg"]=e.accent[100],n["--window-control-maximize-hover-color"]=e.accent[500],n["--window-control-maximize-hover-border"]=e.accent[200],n["--window-control-maximize-hover-shadow"]="none",n["--window-control-close-dot"]=e.semantic.error,n["--window-control-close-dot-shadow"]="none",n["--window-control-close-hover-bg"]=e.semantic.errorBg,n["--window-control-close-hover-color"]=e.semantic.error,n["--window-control-close-hover-border"]=e.semantic.errorBorder,n["--window-control-close-hover-shadow"]="none",n["--window-control-default-color"]=e.text.primary,n["--window-control-default-dot"]=e.text.muted,n["--window-control-disabled-dot"]=e.text.disabled,n["--window-control-flow-gradient"]="none"),n["--input-bg"]=e.element.base,n["--input-bg-hover"]=e.element.medium,n["--input-bg-focus"]=e.element.soft,n["--input-bg-disabled"]=e.element.subtle,n["--input-border"]=e.border.base,n["--input-border-hover"]=e.border.medium,n["--input-border-focus"]=e.accent[400],n["--input-border-error"]=e.semantic.error,n["--input-text"]=e.text.primary,n["--input-placeholder"]="color-mix(in srgb, var(--color-text-muted) 40%, var(--color-bg-primary))",n["--card-bg"]=e.element.base,n["--card-bg-hover"]=e.element.medium,n["--card-bg-active"]=e.element.elevated,n["--card-border"]=e.border.base,n["--card-border-hover"]=e.border.medium,n["--card-border-active"]=e.accent[300],i.type==="dark"?(n["--card-bg-default"]="rgba(255, 255, 255, 0.025)",n["--card-bg-elevated"]="rgba(255, 255, 255, 0.035)",n["--card-bg-subtle"]="rgba(255, 255, 255, 0.015)",n["--card-bg-hover"]="rgba(255, 255, 255, 0.04)",n["--card-bg-active"]="rgba(255, 255, 255, 0.05)",n["--card-bg-accent"]="rgba(255, 255, 255, 0.09)",n["--card-bg-accent-hover"]="rgba(255, 255, 255, 0.13)",n["--card-bg-purple"]="rgba(139, 92, 246, 0.08)",n["--card-bg-purple-hover"]="rgba(139, 92, 246, 0.12)"):(n["--card-bg-default"]="rgba(0, 0, 0, 0.06)",n["--card-bg-elevated"]="rgba(0, 0, 0, 0.08)",n["--card-bg-subtle"]="rgba(0, 0, 0, 0.04)",n["--card-bg-hover"]="rgba(0, 0, 0, 0.065)",n["--card-bg-active"]="rgba(0, 0, 0, 0.09)",n["--card-bg-accent"]="rgba(15, 23, 42, 0.08)",n["--card-bg-accent-hover"]="rgba(15, 23, 42, 0.12)",n["--card-bg-purple"]="rgba(124, 58, 237, 0.12)",n["--card-bg-purple-hover"]="rgba(124, 58, 237, 0.18)"),n["--modal-bg"]=e.background.elevated,n["--modal-border"]=e.border.base,n["--modal-overlay"]="var(--ds-overlay-scrim-strong)",n["--nav-bg"]=e.background.secondary,n["--nav-item-bg-hover"]=e.element.base,n["--nav-item-bg-active"]=e.element.medium,n["--nav-item-text"]=e.text.secondary,n["--nav-item-text-active"]=e.text.primary,n["--panel-bg"]=e.background.primary,n["--panel-header-bg"]=e.background.secondary,n["--panel-border"]=e.border.base,n["--tooltip-bg"]=e.background.elevated,n["--tooltip-border"]=e.border.medium,n["--tooltip-text"]=e.text.primary,n["--tool-card-bg-primary"]=e.element.base,n["--tool-card-bg-secondary"]=e.element.soft,n["--tool-card-bg-hover"]=e.element.medium,n["--tool-card-bg-elevated"]=e.element.elevated,n["--tool-card-border"]=e.border.base,n["--tool-card-border-subtle"]=e.border.subtle,n["--tool-card-text-primary"]=e.text.primary,n["--tool-card-text-secondary"]=e.text.secondary,n["--tool-card-text-muted"]=e.text.muted,n}function Ao(i){return Object.fromEntries(Object.entries(i).map(([e,n])=>[e,String(n)]))}function wg(i){return Object.fromEntries(Object.entries(i).map(([e,n])=>[e,Number(n)]))}function Ie(i,e,n){return{fg:i,bg:e,border:n}}function Tee(i){const{colors:e,effects:n,motion:s,typography:r}=i,c=i.type==="dark",u=e.purple??e.accent,m=Ie(e.text.secondary,e.element.base,e.border.base),h=Ie(e.accent[500],e.accent[100],e.accent[300]);return{color:{bg:{app:e.background.primary,scene:e.background.scene,panel:e.background.secondary,elevated:e.background.elevated,overlay:i.type==="dark"?"rgba(0, 0, 0, 0.5)":"rgba(0, 0, 0, 0.3)",tooltip:e.background.tooltip??e.background.elevated},text:{primary:e.text.primary,secondary:e.text.secondary,muted:e.text.muted,disabled:e.text.disabled,inverse:"#ffffff"},border:{...e.border,focus:e.accent[400]},element:e.element,accent:Ao(e.accent),purple:Ao(e.purple??e.accent),success:{fg:e.semantic.success,bg:e.semantic.successBg,border:e.semantic.successBorder},warning:{fg:e.semantic.warning,bg:e.semantic.warningBg,border:e.semantic.warningBorder},danger:{fg:e.semantic.error,bg:e.semantic.errorBg,border:e.semantic.errorBorder},info:{fg:e.semantic.info,bg:e.semantic.infoBg,border:e.semantic.infoBorder},overlay:{scrim:c?"rgba(0, 0, 0, 0.56)":"rgba(15, 23, 42, 0.34)",scrimStrong:c?"rgba(0, 0, 0, 0.72)":"rgba(15, 23, 42, 0.48)",backdrop:c?"rgba(10, 10, 12, 0.78)":"rgba(248, 250, 252, 0.78)"},focus:{ring:e.accent[400],ringSubtle:e.accent[200],outline:e.accent[500]},selection:{bg:e.semantic.highlightBg||e.accent[200],fg:e.text.primary,inactiveBg:e.accent[100]},shadowColor:{subtle:c?"rgba(0, 0, 0, 0.18)":"rgba(15, 23, 42, 0.06)",soft:c?"rgba(0, 0, 0, 0.24)":"rgba(15, 23, 42, 0.08)",card:c?"rgba(0, 0, 0, 0.32)":"rgba(15, 23, 42, 0.10)",floating:c?"rgba(0, 0, 0, 0.40)":"rgba(15, 23, 42, 0.14)",popover:c?"rgba(0, 0, 0, 0.44)":"rgba(15, 23, 42, 0.16)",modal:c?"rgba(0, 0, 0, 0.52)":"rgba(15, 23, 42, 0.22)",strong:c?"rgba(0, 0, 0, 0.60)":"rgba(15, 23, 42, 0.28)",text:c?"rgba(0, 0, 0, 0.50)":"rgba(15, 23, 42, 0.18)"},diff:{added:Ie(e.git.added,e.git.addedBg,e.semantic.successBorder),deleted:Ie(e.git.deleted,e.git.deletedBg,e.semantic.errorBorder),modified:Ie(e.git.changes,e.git.changesBg,e.semantic.warningBorder),unchanged:m,gutter:{added:e.git.added,deleted:e.git.deleted,modified:e.git.changes}},terminal:{bg:e.background.primary,fg:e.text.primary,muted:e.text.muted,prompt:e.accent[500],cursor:e.accent[500],selection:e.accent[200],success:e.semantic.success,warning:e.semantic.warning,danger:e.semantic.error},syntax:{keyword:u[500],string:e.semantic.success,number:e.semantic.warning,function:e.accent[500],type:e.semantic.info,variable:e.text.primary,constant:e.semantic.warning,operator:e.text.secondary,comment:e.text.muted,punctuation:e.text.secondary},language:{typescript:Ie(e.accent[500],e.accent[100],e.accent[300]),javascript:Ie(e.semantic.warning,e.semantic.warningBg,e.semantic.warningBorder),json:Ie(u[500],u[100],u[300]),markdown:Ie(e.text.secondary,e.element.soft,e.border.base),rust:Ie(e.semantic.error,e.semantic.errorBg,e.semantic.errorBorder),css:Ie(e.accent[600],e.accent[100],e.accent[300]),html:Ie(e.semantic.error,e.semantic.errorBg,e.semantic.errorBorder),shell:Ie(e.semantic.success,e.semantic.successBg,e.semantic.successBorder),python:Ie(e.semantic.info,e.semantic.infoBg,e.semantic.infoBorder)},toolFamily:{agent:Ie(u[500],u[100],u[300]),code:Ie(e.accent[500],e.accent[100],e.accent[300]),files:Ie(e.semantic.info,e.semantic.infoBg,e.semantic.infoBorder),terminal:Ie(e.semantic.success,e.semantic.successBg,e.semantic.successBorder),git:Ie(e.git.branch,e.git.branchBg,e.border.medium),search:Ie(e.semantic.warning,e.semantic.warningBg,e.semantic.warningBorder),browser:Ie(e.accent[600],e.accent[100],e.accent[300]),design:Ie(u[600],u[100],u[300])},markdown:{link:e.accent[500],inlineCode:Ie(e.text.primary,e.element.soft,e.border.subtle),codeBlock:Ie(e.text.primary,e.background.tertiary,e.border.base),blockquote:Ie(e.text.secondary,e.element.subtle,e.border.medium),table:{headerBg:e.element.soft,border:e.border.base,rowHoverBg:e.element.subtle},hr:e.border.base},statusSurface:{neutral:m,success:Ie(e.semantic.success,e.semantic.successBg,e.semantic.successBorder),warning:Ie(e.semantic.warning,e.semantic.warningBg,e.semantic.warningBorder),danger:Ie(e.semantic.error,e.semantic.errorBg,e.semantic.errorBorder),info:Ie(e.semantic.info,e.semantic.infoBg,e.semantic.infoBorder),running:h,pending:Ie(e.text.muted,e.element.subtle,e.border.subtle)}},space:Ao(n.spacing),radius:{xs:n.radius.sm,sm:n.radius.sm,md:n.radius.base,lg:n.radius.lg,xl:n.radius.xl,"2xl":n.radius["2xl"]??n.radius.xl,full:n.radius.full},typography:{family:r.font,size:Ao(r.size),weight:wg(r.weight),lineHeight:wg(r.lineHeight)},shadow:Ao(n.shadow),motion:{duration:Ao(s.duration),easing:Ao(s.easing)},zIndex:{underlay:-1,base:0,local:1,raised:2,header:10,sticky:20,floating:50,dropdown:80,scrim:120,overlay:160,drawer:180,dialog:240,fullscreen:280,toast:320,popover:340,tooltip:360,notification:400,contextMenu:500}}}function un(i,e,n){Object.entries(n).forEach(([s,r])=>{i[`${e}-${s}`]=String(r)})}function pn(i,e,n){i[`${e}-fg`]=n.fg,i[`${e}-bg`]=n.bg,i[`${e}-border`]=n.border}function Pee(i){const e=i.trim(),n=/^#([0-9a-f]{6})$/i.exec(e);if(n){const r=parseInt(n[1],16);return`${r>>16&255} ${r>>8&255} ${r&255}`}const s=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(e);return s?`${s[1]} ${s[2]} ${s[3]}`:null}function uh(i){const e=Tee(i),n={"--ds-color-bg-app":e.color.bg.app,"--ds-color-bg-scene":e.color.bg.scene,"--ds-color-bg-panel":e.color.bg.panel,"--ds-color-bg-elevated":e.color.bg.elevated,"--ds-color-bg-overlay":e.color.bg.overlay,"--ds-color-bg-tooltip":e.color.bg.tooltip,"--ds-color-text-primary":e.color.text.primary,"--ds-color-text-secondary":e.color.text.secondary,"--ds-color-text-muted":e.color.text.muted,"--ds-color-text-disabled":e.color.text.disabled,"--ds-color-text-inverse":e.color.text.inverse,"--ds-color-border-subtle":e.color.border.subtle,"--ds-color-border-base":e.color.border.base,"--ds-color-border-medium":e.color.border.medium,"--ds-color-border-strong":e.color.border.strong,"--ds-color-border-prominent":e.color.border.prominent,"--ds-color-border-focus":e.color.border.focus,"--ds-color-success":e.color.success.fg,"--ds-color-success-bg":e.color.success.bg,"--ds-color-success-border":e.color.success.border,"--ds-color-warning":e.color.warning.fg,"--ds-color-warning-bg":e.color.warning.bg,"--ds-color-warning-border":e.color.warning.border,"--ds-color-danger":e.color.danger.fg,"--ds-color-danger-bg":e.color.danger.bg,"--ds-color-danger-border":e.color.danger.border,"--ds-color-info":e.color.info.fg,"--ds-color-info-bg":e.color.info.bg,"--ds-color-info-border":e.color.info.border,"--ds-overlay-scrim":e.color.overlay.scrim,"--ds-overlay-scrim-strong":e.color.overlay.scrimStrong,"--ds-overlay-backdrop":e.color.overlay.backdrop,"--ds-focus-ring":e.color.focus.ring,"--ds-focus-ring-subtle":e.color.focus.ringSubtle,"--ds-focus-outline":e.color.focus.outline,"--ds-selection-bg":e.color.selection.bg,"--ds-selection-fg":e.color.selection.fg,"--ds-selection-inactive-bg":e.color.selection.inactiveBg,"--ds-shadow-color-subtle":e.color.shadowColor.subtle,"--ds-shadow-color-soft":e.color.shadowColor.soft,"--ds-shadow-color-card":e.color.shadowColor.card,"--ds-shadow-color-floating":e.color.shadowColor.floating,"--ds-shadow-color-popover":e.color.shadowColor.popover,"--ds-shadow-color-modal":e.color.shadowColor.modal,"--ds-shadow-color-strong":e.color.shadowColor.strong,"--ds-shadow-color-text":e.color.shadowColor.text,"--ds-diff-gutter-added":e.color.diff.gutter.added,"--ds-diff-gutter-deleted":e.color.diff.gutter.deleted,"--ds-diff-gutter-modified":e.color.diff.gutter.modified,"--ds-terminal-bg":e.color.terminal.bg,"--ds-terminal-fg":e.color.terminal.fg,"--ds-terminal-muted":e.color.terminal.muted,"--ds-terminal-prompt":e.color.terminal.prompt,"--ds-terminal-cursor":e.color.terminal.cursor,"--ds-terminal-selection":e.color.terminal.selection,"--ds-terminal-success":e.color.terminal.success,"--ds-terminal-warning":e.color.terminal.warning,"--ds-terminal-danger":e.color.terminal.danger,"--ds-markdown-link":e.color.markdown.link,"--ds-markdown-table-header-bg":e.color.markdown.table.headerBg,"--ds-markdown-table-border":e.color.markdown.table.border,"--ds-markdown-table-row-hover-bg":e.color.markdown.table.rowHoverBg,"--ds-markdown-hr":e.color.markdown.hr,"--ds-radius-xs":e.radius.xs,"--ds-radius-sm":e.radius.sm,"--ds-radius-md":e.radius.md,"--ds-radius-lg":e.radius.lg,"--ds-radius-xl":e.radius.xl,"--ds-radius-2xl":e.radius["2xl"],"--ds-radius-full":e.radius.full,"--ds-z-underlay":String(e.zIndex.underlay),"--ds-z-base":String(e.zIndex.base),"--ds-z-local":String(e.zIndex.local),"--ds-z-raised":String(e.zIndex.raised),"--ds-z-header":String(e.zIndex.header),"--ds-z-sticky":String(e.zIndex.sticky),"--ds-z-floating":String(e.zIndex.floating),"--ds-z-dropdown":String(e.zIndex.dropdown),"--ds-z-scrim":String(e.zIndex.scrim),"--ds-z-overlay":String(e.zIndex.overlay),"--ds-z-drawer":String(e.zIndex.drawer),"--ds-z-dialog":String(e.zIndex.dialog),"--ds-z-modal":String(e.zIndex.dialog),"--ds-z-fullscreen":String(e.zIndex.fullscreen),"--ds-z-toast":String(e.zIndex.toast),"--ds-z-popover":String(e.zIndex.popover),"--ds-z-tooltip":String(e.zIndex.tooltip),"--ds-z-notification":String(e.zIndex.notification),"--ds-z-context-menu":String(e.zIndex.contextMenu)};pn(n,"--ds-diff-added",e.color.diff.added),pn(n,"--ds-diff-deleted",e.color.diff.deleted),pn(n,"--ds-diff-modified",e.color.diff.modified),pn(n,"--ds-diff-unchanged",e.color.diff.unchanged),Object.entries(e.color.syntax).forEach(([r,c])=>{n[`--ds-syntax-${r}`]=c}),Object.entries(e.color.language).forEach(([r,c])=>{pn(n,`--ds-language-${r}`,c)}),Object.entries(e.color.toolFamily).forEach(([r,c])=>{pn(n,`--ds-tool-family-${r}`,c)}),pn(n,"--ds-markdown-inline-code",e.color.markdown.inlineCode),pn(n,"--ds-markdown-code-block",e.color.markdown.codeBlock),pn(n,"--ds-markdown-blockquote",e.color.markdown.blockquote),Object.entries(e.color.statusSurface).forEach(([r,c])=>{pn(n,`--ds-status-surface-${r}`,c)}),un(n,"--ds-color-accent",e.color.accent),un(n,"--ds-color-purple",e.color.purple),un(n,"--ds-color-element",e.color.element),un(n,"--ds-space",e.space),un(n,"--ds-font-size",e.typography.size),un(n,"--ds-font-weight",e.typography.weight),un(n,"--ds-line-height",e.typography.lineHeight),un(n,"--ds-shadow",e.shadow),n["--ds-shadow-card"]=e.shadow.lg??e.shadow.base??`0 4px 12px ${e.color.shadowColor.card}`,n["--ds-shadow-floating"]=e.shadow.xl??e.shadow.lg??`0 12px 32px ${e.color.shadowColor.floating}`,n["--ds-shadow-popover"]=`0 8px 24px ${e.color.shadowColor.popover}`,n["--ds-shadow-modal"]=e.shadow["2xl"]??e.shadow.xl??`0 16px 40px ${e.color.shadowColor.modal}`,un(n,"--ds-motion",e.motion.duration),un(n,"--ds-easing",e.motion.easing),n["--ds-font-family-sans"]=e.typography.family.sans,n["--ds-font-family-mono"]=e.typography.family.mono;const s=Pee(String(e.color.accent[500]));return s&&(n["--ds-color-accent-rgb"]=s),n}function Zt(i,e,n){Object.entries(n).forEach(([s,r])=>{i[`${e}-${s}`]=String(r)})}function Fee(i){const e=i.trim(),n=/^#([0-9a-f]{6})$/i.exec(e);if(n){const r=parseInt(n[1],16);return`${r>>16&255} ${r>>8&255} ${r&255}`}const s=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(e);return s?`${s[1]} ${s[2]} ${s[3]}`:null}function ph(i){const{colors:e,effects:n,motion:s,typography:r}=i,c={"--color-bg-primary":e.background.primary,"--color-bg-secondary":e.background.secondary,"--color-bg-tertiary":e.background.tertiary,"--color-bg-quaternary":e.background.quaternary,"--color-bg-elevated":e.background.elevated,"--color-bg-workbench":e.background.workbench,"--color-bg-scene":e.background.scene,"--color-bg-flowchat":e.background.scene,"--color-overlay":"var(--ds-overlay-scrim)","--color-text-primary":e.text.primary,"--color-text-secondary":e.text.secondary,"--color-text-muted":e.text.muted,"--color-text-disabled":e.text.disabled,"--color-primary":e.accent[500],"--color-primary-hover":e.accent[600],"--color-accent":e.accent[500],"--color-accent-primary":e.accent[500],"--color-success":e.semantic.success,"--color-success-bg":e.semantic.successBg,"--color-success-border":e.semantic.successBorder,"--color-warning":e.semantic.warning,"--color-warning-bg":e.semantic.warningBg,"--color-warning-border":e.semantic.warningBorder,"--color-error":e.semantic.error,"--color-error-bg":e.semantic.errorBg,"--color-error-border":e.semantic.errorBorder,"--color-info":e.semantic.info,"--color-info-bg":e.semantic.infoBg,"--color-info-border":e.semantic.infoBorder,"--color-highlight":e.semantic.highlight,"--color-highlight-bg":e.semantic.highlightBg,"--border-subtle":e.border.subtle,"--border-base":e.border.base,"--border-medium":e.border.medium,"--border-strong":e.border.strong,"--border-prominent":e.border.prominent,"--scene-viewport-border-width":i.layout?.sceneViewportBorder??!0?"1px":"0","--element-bg-subtle":e.element.subtle,"--element-bg-soft":e.element.soft,"--element-bg-base":e.element.base,"--element-bg-medium":e.element.medium,"--element-bg-strong":e.element.strong,"--element-bg-elevated":e.element.elevated,"--git-color-branch":e.git.branch,"--git-color-branch-bg":e.git.branchBg,"--git-color-changes":e.git.changes,"--git-color-changes-bg":e.git.changesBg,"--git-color-added":e.git.added,"--git-color-added-bg":e.git.addedBg,"--git-color-deleted":e.git.deleted,"--git-color-deleted-bg":e.git.deletedBg,"--git-color-staged":e.git.staged,"--git-color-staged-bg":e.git.stagedBg,"--scrollbar-thumb":e.scrollbar?.thumb??(i.type==="dark"?"rgba(255, 255, 255, 0.12)":"rgba(0, 0, 0, 0.15)"),"--scrollbar-thumb-hover":e.scrollbar?.thumbHover??(i.type==="dark"?"rgba(255, 255, 255, 0.22)":"rgba(0, 0, 0, 0.28)"),"--glow-blue":n.glow.blue,"--glow-purple":n.glow.purple,"--glow-mixed":n.glow.mixed,"--opacity-disabled":String(n.opacity.disabled),"--opacity-hover":String(n.opacity.hover),"--opacity-focus":String(n.opacity.focus),"--opacity-overlay":String(n.opacity.overlay),"--font-sans":r.font.sans,"--font-mono":r.font.mono};e.background.tooltip&&(c["--color-bg-tooltip"]=e.background.tooltip);const u=Fee(e.accent[500]);return u&&(c["--color-primary-rgb"]=u),Zt(c,"--color-accent",e.accent),e.purple&&Zt(c,"--color-purple",e.purple),Zt(c,"--shadow",n.shadow),Zt(c,"--blur",n.blur),Zt(c,"--radius",n.radius),Zt(c,"--spacing",n.spacing),Zt(c,"--motion",s.duration),Zt(c,"--easing",s.easing),Zt(c,"--font-weight",r.weight),Zt(c,"--font-size",r.size),Zt(c,"--line-height",r.lineHeight),c}const Ree={tiny:"dot-matrix-loader--tiny",small:"dot-matrix-loader--small",medium:"dot-matrix-loader--medium",large:"dot-matrix-loader--large"},Pi=({size:i="medium",className:e="",ariaHidden:n=!0})=>l.jsx("span",{className:`dot-matrix-loader ${Ree[i]} ${e}`.trim(),"aria-hidden":n,children:Array.from({length:9},(s,r)=>l.jsx("span",{className:"dot-matrix-loader__dot"},r))});Pi.displayName="DotMatrixLoader";const Ce=k.forwardRef(({children:i,variant:e="primary",size:n="medium",shape:s="default",isLoading:r=!1,iconOnly:c=!1,loadingLabel:u="Loading",className:m="",disabled:h,type:f="button",...y},v)=>{const b={small:"sm",medium:"base",large:"lg"},A=["btn",(F=>{switch(F){case"primary":case"accent":return"btn-primary";case"secondary":return"btn-secondary";case"ai":return"btn-action btn-action-ai";case"danger":return"btn-action btn-action-danger";case"success":return"btn-action btn-action-success";case"ghost":return"btn-ghost";case"dashed":return"btn-dashed";default:return"btn-secondary"}})(e),`btn-${b[n]||"base"}`,s==="pill"&&"btn-pill",c&&"btn-icon-only",r&&"btn-loading",h&&"btn-disabled",m].filter(Boolean).join(" ");return l.jsx("button",{ref:v,className:A,disabled:h||r,type:f,"aria-busy":r||void 0,...y,children:r?l.jsxs(l.Fragment,{children:[l.jsx(Pi,{size:"tiny",className:"btn-loading-icon"}),l.jsx("span",{className:"btn-loading-text",children:u})]}):i})});Ce.displayName="Button";var fr=Mg();let gi=0,Fc="";function Nee(i){k.useEffect(()=>{if(!(!i||typeof document>"u"))return gi===0&&(Fc=document.body.style.overflow,document.body.style.overflow="hidden"),gi+=1,()=>{gi=Math.max(0,gi-1),gi===0&&(document.body.style.overflow=Fc,Fc="")}},[i])}const Dee=["a[href]","area[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","iframe","object","embed",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(",");function Rc(i){return Array.from(i.querySelectorAll(Dee)).filter(e=>{const n=window.getComputedStyle(e);return!e.hasAttribute("disabled")&&n.display!=="none"&&n.visibility!=="hidden"})}function Iee({enabled:i,containerRef:e,initialFocusRef:n,restoreFocus:s=!0,onEscape:r}){const c=k.useRef(r);c.current=r;const u=k.useRef(null);k.useEffect(()=>{if(!i||typeof document>"u"){if(!i&&u.current){const y=u.current;u.current=null,s&&y.isConnected&&y.focus({preventScroll:!0})}return}const m=e.current;if(!m)return;u.current=document.activeElement instanceof HTMLElement?document.activeElement:null,window.requestAnimationFrame(()=>{const y=n?.current??Rc(m)[0]??m;m.contains(y)&&y.focus({preventScroll:!0})});const h=y=>{if(y.key==="Escape"){c.current?.();return}if(y.key!=="Tab")return;const v=Rc(m);if(v.length===0){y.preventDefault(),m.focus({preventScroll:!0});return}const b=v[0],S=v[v.length-1],A=document.activeElement;if(!(A instanceof HTMLElement)||!m.contains(A)){y.preventDefault(),(y.shiftKey?S:b).focus({preventScroll:!0});return}if(y.shiftKey&&A===b){y.preventDefault(),S.focus();return}!y.shiftKey&&A===S&&(y.preventDefault(),b.focus())},f=y=>{if(y.target instanceof Node&&m.contains(y.target))return;(Rc(m)[0]??m).focus({preventScroll:!0})};return document.addEventListener("keydown",h,!0),document.addEventListener("focusin",f,!0),()=>{document.removeEventListener("keydown",h,!0),document.removeEventListener("focusin",f,!0)}},[e,i,n,s])}function Fo(...i){return i.filter(Boolean).join(" ")}function Mee(i){return De.Children.toArray(i).some(e=>{if(!De.isValidElement(e))return!1;const n=e.type;return n.displayName==="DialogHeader"||n.displayName==="DialogBody"||n.displayName==="DialogFooter"})}const mh=k.forwardRef(({title:i,titleExtra:e,className:n,children:s,...r},c)=>l.jsxs("div",{ref:c,className:Fo("ds-dialog__header",n),...r,children:[(i||e)&&l.jsxs("div",{className:"ds-dialog__title-group",children:[i&&l.jsx("h2",{className:"ds-dialog__title",children:i}),e&&l.jsx("span",{className:"ds-dialog__title-extra",children:e})]}),s]}));mh.displayName="DialogHeader";const yd=k.forwardRef(({className:i,...e},n)=>l.jsx("div",{ref:n,className:Fo("ds-dialog__body",i),...e}));yd.displayName="DialogBody";const gh=k.forwardRef(({className:i,...e},n)=>l.jsx("div",{ref:n,className:Fo("ds-dialog__footer",i),...e}));gh.displayName="DialogFooter";function hh({open:i,onOpenChange:e,title:n,titleExtra:s,children:r,size:c="medium",placement:u="center",contentInset:m=!1,showDividers:h=!0,contentClassName:f,className:y,overlayClassName:v,showCloseButton:b=!0,closeOnEscape:S=!0,closeOnOverlayClick:A=!0,restoreFocus:F=!0,initialFocusRef:_,labelledBy:E,describedBy:j,ariaLabel:z,closeLabel:B="Close dialog",role:W="dialog"}){const I=i,ee=k.useRef(null),oe=k.useId(),O=E??(n?oe:void 0),U=k.useCallback(()=>{e?.(!1)},[e]);if(Nee(I),Iee({enabled:I,containerRef:ee,initialFocusRef:_,restoreFocus:F,onEscape:S?U:void 0}),!I)return null;const Z=Mee(r),re=se=>{A&&se.target===se.currentTarget&&U()};return fr.createPortal(l.jsx("div",{className:Fo("ds-dialog-overlay",u!=="center"&&`ds-dialog-overlay--${u}`,v),onMouseDown:re,children:l.jsxs("div",{ref:ee,className:Fo("ds-dialog",`ds-dialog--${c}`,m&&"ds-dialog--content-inset",!h&&"ds-dialog--without-dividers",b&&"ds-dialog--with-close",y),role:W,"aria-modal":"true","aria-label":z,"aria-labelledby":O,"aria-describedby":j,tabIndex:-1,children:[(n||s||b)&&l.jsxs("div",{className:Fo("ds-dialog__header-shell",!n&&b&&"ds-dialog__header-shell--close-only"),children:[(n||s)&&l.jsx(mh,{id:O,title:n,titleExtra:s}),b&&l.jsx("button",{className:"ds-dialog__close",type:"button","aria-label":B,onClick:U,children:l.jsx(Cs,{"aria-hidden":"true",size:14,strokeWidth:2})})]}),Z?r:l.jsx(yd,{className:Fo(m&&"ds-dialog__body--inset",f),children:r})]})}),document.body)}const jee=450,Eee=(i,e)=>{if(i){if(typeof i=="function"){i(e);return}i.current=e}},Lee=i=>({top:"bottom",bottom:"top",left:"right",right:"left"})[i],vg=(i,e,n)=>{switch(e){case"top":return i.top-n;case"bottom":return window.innerHeight-i.bottom-n;case"left":return i.left-n;case"right":return window.innerWidth-i.right-n}},$ee=(i,e,n,s)=>{let r=0,c=0;switch(n){case"top":r=i.top-e.height-s,c=i.left+(i.width-e.width)/2;break;case"bottom":r=i.bottom+s,c=i.left+(i.width-e.width)/2;break;case"left":r=i.top+(i.height-e.height)/2,c=i.left-e.width-s;break;case"right":r=i.top+(i.height-e.height)/2,c=i.right+s;break}return{top:r,left:c}},Oee=(i,e,n,s,r)=>{const c=n==="top"||n==="bottom"?e.height+s:e.width+s,u=vg(i,n,r);if(u>=c)return n;const m=Lee(n),h=vg(i,m,r);return h>=c||h>u?m:n},bg=(i,e,n)=>{let{top:s,left:r}=i;return rwindow.innerWidth-n&&(r=window.innerWidth-e.width-n),swindow.innerHeight-n&&(s=window.innerHeight-e.height-n),{top:s,left:r}},Bee=12,Wee=8,yr=({content:i,children:e,placement:n="top",followCursor:s=!1,trigger:r="hover",delay:c=jee,disabled:u=!1,className:m="",interactive:h=!1})=>{const[f,y]=k.useState(!1),[v,b]=k.useState({top:0,left:0}),[S,A]=k.useState(!1),[F,_]=k.useState(n),[E,j]=k.useState(null),z=k.useRef(null),B=k.useRef(null),W=k.useRef(null),I=k.useRef(null),ee=k.useRef(null),oe=8,O=8,U=k.useCallback(()=>{if(!B.current)return;const ne=B.current.getBoundingClientRect();if(s&&E){const xe=E.x+Bee,Pe=E.y+Wee,Ye=bg({top:Pe,left:xe},ne,O);_("bottom"),b(Ye),A(!0);return}if(!z.current)return;const ue=z.current.getBoundingClientRect(),Se=Oee(ue,ne,n,oe,O);let me=$ee(ue,ne,Se,oe);me=bg(me,ne,O),_(Se),b(me),A(!0)},[n,s,E]),Z=ne=>{u||(W.current&&clearTimeout(W.current),I.current&&(clearTimeout(I.current),I.current=null),s&&ne&&(ee.current={x:ne.clientX,y:ne.clientY}),W.current=setTimeout(()=>{W.current=null,s&&j(ee.current),A(!1),y(!0)},c))},re=k.useCallback(()=>{W.current&&(clearTimeout(W.current),W.current=null),I.current&&(clearTimeout(I.current),I.current=null),y(!1),A(!1),s&&(ee.current=null,j(null))},[s]),se=k.useCallback(()=>{if(!h){re();return}I.current&&clearTimeout(I.current),I.current=setTimeout(()=>{I.current=null,re()},150)},[re,h]),pe=k.useCallback(ne=>{s&&!f&&(ee.current={x:ne.clientX,y:ne.clientY});const ue=e.props;typeof ue.onMouseMove=="function"&&ue.onMouseMove(ne)},[s,f,e.props]);k.useEffect(()=>{_(n)},[n]),k.useEffect(()=>{u&&re()},[u,re]),k.useEffect(()=>{if(f)return requestAnimationFrame(()=>{U()}),s||window.addEventListener("scroll",U,!0),window.addEventListener("resize",U),()=>{s||window.removeEventListener("scroll",U,!0),window.removeEventListener("resize",U)}},[f,s,U]),k.useEffect(()=>()=>{W.current&&clearTimeout(W.current),I.current&&clearTimeout(I.current)},[]);const fe=e.props,we=e.ref,L=k.useCallback(ne=>{z.current=ne,Eee(we,ne)},[we]),$=ne=>{r==="hover"&&Z(ne),typeof fe.onMouseEnter=="function"&&fe.onMouseEnter(ne)},te=ne=>{r==="hover"&&se(),typeof fe.onMouseLeave=="function"&&fe.onMouseLeave(ne)},G=ne=>{W.current&&(clearTimeout(W.current),W.current=null),f?re():r==="click"&&Z(),typeof fe.onClick=="function"&&fe.onClick(ne)},C=ne=>{r==="focus"&&Z(),typeof fe.onFocus=="function"&&fe.onFocus(ne)},N=ne=>{r==="focus"&&re(),typeof fe.onBlur=="function"&&fe.onBlur(ne)},X=De.cloneElement(e,{ref:L,onMouseEnter:$,onMouseLeave:te,onMouseMove:s?pe:e.props.onMouseMove,onClick:G,onFocus:C,onBlur:N}),ie=["ds-tooltip",`ds-tooltip--${F}`,f&&S&&"ds-tooltip--visible",h&&"ds-tooltip--interactive",m].filter(Boolean).join(" ");return l.jsxs(l.Fragment,{children:[X,f&&fr.createPortal(l.jsx("div",{ref:B,className:ie,onMouseEnter:h?()=>{I.current&&(clearTimeout(I.current),I.current=null)}:void 0,onMouseLeave:h?se:void 0,style:{position:"fixed",top:`${v.top}px`,left:`${v.left}px`},role:"tooltip",children:l.jsx("div",{className:"ds-tooltip__content",children:i})}),document.body)]})};yr.displayName="Tooltip";const ze=De.forwardRef(({children:i,variant:e="default",size:n="medium",shape:s="circle",isLoading:r=!1,tooltip:c,tooltipPlacement:u="top",tooltipFollowCursor:m=!0,className:h="",disabled:f,type:y="button","aria-label":v,...b},S)=>{const A=["icon-btn",`icon-btn--${n}`,`icon-btn--${e}`,s==="circle"&&"icon-btn--circle",r&&"icon-btn--loading",h].filter(Boolean).join(" "),F=l.jsx("button",{ref:S,className:A,disabled:f||r,type:y,"aria-label":v,"aria-busy":r||void 0,...b,children:i});return c&&!f?l.jsx(yr,{content:c,placement:u,followCursor:m,children:F}):F});ze.displayName="IconButton";function kg(...i){return i.filter(Boolean).join(" ")}function Ut(i){return new Date(i.getFullYear(),i.getMonth(),i.getDate())}function Yc(){return Ut(new Date)}function zee(i,e){return i.getFullYear()===e.getFullYear()&&i.getMonth()===e.getMonth()&&i.getDate()===e.getDate()}function Nc(i,e){return Ut(i).getTime()-Ut(e).getTime()}function Sg(i){if(!i)return null;const e=Ut(i.startDate),n=Ut(i.endDate);return e.getTime()<=n.getTime()?{startDate:e,endDate:n}:{startDate:n,endDate:e}}function Uee(){const i=Yc(),e=new Date(i);return e.setDate(e.getDate()-7),{startDate:e,endDate:i}}function wd(i,e,n){if(!e)return"none";const s=Ut(i).getTime(),r=Ut(e).getTime();if(!n)return s===r?"edge-start":"none";const c=Ut(n).getTime();return r===c&&s===r?"single":sc?"none":s===r?"edge-start":s===c?"edge-end":"in-range"}function xg(i,e,n){return wd(i,e,n)!=="none"}function Hee(i,e,n){const s=wd(i,e,n);if(s==="none"||s==="single")return{bridgeLeft:!1,bridgeRight:!1};if(!n&&s==="edge-start")return{bridgeLeft:!1,bridgeRight:!1};const r=new Date(i.getFullYear(),i.getMonth(),i.getDate()-1),c=new Date(i.getFullYear(),i.getMonth(),i.getDate()+1);return{bridgeLeft:xg(r,e,n),bridgeRight:xg(c,e,n)}}const fh=({open:i,onOpenChange:e,onApply:n,title:s="Date range",initialRange:r,defaultRange:c,minDate:u,maxDate:m,locale:h,labels:f,dateFormatOptions:y,size:v="small",contentClassName:b,className:S,closeLabel:A})=>{const F=h||(typeof navigator<"u"?navigator.language:void 0)||"en-US",[_,E]=k.useState(null),[j,z]=k.useState(null),[B,W]=k.useState(()=>{const C=Yc();return new Date(C.getFullYear(),C.getMonth(),1)}),[I,ee]=k.useState(null);k.useEffect(()=>{if(!i)return;ee(null);const C=Sg(r)??Sg(c)??Uee();E(C.startDate),z(C.endDate),W(new Date(C.startDate.getFullYear(),C.startDate.getMonth(),1))},[c,r,i]);const oe=k.useMemo(()=>new Intl.DateTimeFormat(F,{year:"numeric",month:"long"}).format(B),[F,B]),O=k.useMemo(()=>{const C=new Intl.DateTimeFormat(F,{weekday:"narrow"}),N=[];for(let X=0;X<7;X+=1)N.push(C.format(new Date(2024,0,1+X)));return N},[F]),U=k.useMemo(()=>new Intl.DateTimeFormat(F,{year:"numeric",month:"short",day:"numeric",...y}),[y,F]),Z=k.useMemo(()=>{const C=B.getFullYear(),N=B.getMonth(),X=new Date(C,N,1),ie=new Date(C,N+1,0).getDate(),ne=(X.getDay()+6)%7,ue=[];for(let Se=0;Se!!(u&&Nc(C,u)<0||m&&Nc(C,m)>0),[m,u]),se=k.useMemo(()=>{if(!_)return f?.hint??"Click a start date, then an end date.";const C=U.format(_);if(_&&j){const N=U.format(j);return f?.summary?.(C,N)??`${C} - ${N}`}return f?.pickEndHint?.(C)??`Now choose an end date (from ${C}).`},[U,f,j,_]),pe=k.useCallback(C=>{if(re(C))return;const N=Ut(C);if(ee(null),!_||_&&j){E(N),z(null);return}Nc(N,_)<0?(z(Ut(_)),E(N)):z(N)},[re,j,_]),fe=k.useCallback(()=>{W(C=>new Date(C.getFullYear(),C.getMonth()-1,1))},[]),we=k.useCallback(()=>{W(C=>new Date(C.getFullYear(),C.getMonth()+1,1))},[]),L=k.useCallback(()=>{if(!_||!j){ee(f?.pickEndError??"Select an end date to complete the range.");return}n({startDate:Ut(_),endDate:Ut(j)}),e(!1)},[f?.pickEndError,n,e,j,_]),$=Yc(),te=f?.previousMonth??"Previous month",G=f?.nextMonth??"Next month";return l.jsx(hh,{open:i,onOpenChange:e,title:s,size:v,contentInset:!0,showCloseButton:!0,contentClassName:kg("ds-date-range-dialog__content",b),className:S,closeLabel:A,children:l.jsxs("div",{className:"ds-date-range-dialog",children:[l.jsx("p",{className:"ds-date-range-dialog__summary","aria-live":"polite",children:se}),l.jsxs("div",{className:"ds-date-range-dialog__calendar",children:[l.jsxs("div",{className:"ds-date-range-dialog__calendar-nav",children:[l.jsx(ze,{variant:"ghost",size:"xs",type:"button",onClick:fe,"aria-label":te,tooltip:te,children:l.jsx(gd,{size:16})}),l.jsx("span",{className:"ds-date-range-dialog__calendar-title",children:oe}),l.jsx(ze,{variant:"ghost",size:"xs",type:"button",onClick:we,"aria-label":G,tooltip:G,children:l.jsx(oo,{size:16})})]}),l.jsx("div",{className:"ds-date-range-dialog__dow-row","aria-hidden":!0,children:O.map((C,N)=>l.jsx("span",{className:"ds-date-range-dialog__dow",children:C},N))}),l.jsx("div",{className:"ds-date-range-dialog__grid",role:"grid","aria-label":oe,children:Z.map(({key:C,date:N})=>{if(!N)return l.jsx("div",{className:"ds-date-range-dialog__cell ds-date-range-dialog__cell--empty"},C);const X=re(N),ie=wd(N,_,j),ne=zee(N,$),{bridgeLeft:ue,bridgeRight:Se}=Hee(N,_,j),me=ie!=="none";return l.jsx(Ce,{type:"button",role:"gridcell","aria-current":ne?"date":void 0,"aria-label":U.format(N),"aria-selected":me,disabled:X,variant:"ghost",size:"small",className:kg("ds-date-range-dialog__cell",X&&"ds-date-range-dialog__cell--disabled",ie==="in-range"&&"ds-date-range-dialog__cell--in-range",ie==="edge-start"&&"ds-date-range-dialog__cell--edge-start",ie==="edge-end"&&"ds-date-range-dialog__cell--edge-end",ie==="single"&&"ds-date-range-dialog__cell--single",ue&&"ds-date-range-dialog__cell--bridge-left",Se&&"ds-date-range-dialog__cell--bridge-right",ne&&"ds-date-range-dialog__cell--today"),onClick:()=>pe(N),children:N.getDate()},C)})})]}),I?l.jsx("p",{className:"ds-date-range-dialog__error",role:"alert",children:I}):null,l.jsxs("div",{className:"ds-date-range-dialog__actions",children:[l.jsx(Ce,{variant:"secondary",size:"small",onClick:()=>e(!1),type:"button",children:f?.cancel??"Cancel"}),l.jsx(Ce,{variant:"primary",size:"small",onClick:L,type:"button",children:f?.apply??"Apply"})]})]})})};fh.displayName="DateRangeDialog";const Xn={placeholder:"Select an option",searchPlaceholder:"Search options",empty:"No options",loading:"Loading",selectAll:"Select all",customValueHint:"Use value",clear:"Clear selection",clearSearch:"Clear search"};function Dc({size:i=12}){return l.jsx("svg",{width:i,height:i,viewBox:"0 0 12 12",fill:"none","aria-hidden":"true",children:l.jsx("path",{d:"M2 2L10 10M10 2L2 10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}function Cg(){return l.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":"true",children:l.jsx("path",{d:"M2.5 6L5 8.5L9.5 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const to=({id:i,options:e=[],value:n,defaultValue:s,placeholder:r,disabled:c=!1,onChange:u,size:m="medium",shape:h="default",label:f,multiple:y=!1,searchable:v=!1,clearable:b=!1,showSelectAll:S=!1,loading:A=!1,error:F=!1,errorMessage:_,maxTagCount:E=3,searchPlaceholder:j,emptyText:z,renderOption:B,renderValue:W,dropdownWidth:I,dropdownAlign:ee="start",className:oe="",placement:O="bottom",autoClose:U=!1,allowCustomValue:Z=!1,customValueHint:re,selectAllText:se=Xn.selectAll,loadingText:pe=Xn.loading,clearAriaLabel:fe=Xn.clear,clearSearchAriaLabel:we=Xn.clearSearch,getRemoveOptionAriaLabel:L=te=>`Remove ${te.label}`,onOpenChange:$})=>{const te=k.useId(),G=i??`select-${te}`,C=`${G}-label`,N=`${G}-listbox`,X=`${G}-error`,ie=r??Xn.placeholder,ne=j??Xn.searchPlaceholder,ue=z??Xn.empty,Se=re??Xn.customValueHint,[me,xe]=k.useState(!1),[Pe,Ye]=k.useState(n!==void 0?n:s!==void 0?s:y?[]:""),[je,tt]=k.useState(""),[qe,ce]=k.useState(-1),at=k.useRef(!1),It=k.useRef(null),wn=k.useRef(null),so=k.useRef(null),Mt=k.useRef(!1);k.useEffect(()=>{n!==void 0&&Ye(n)},[n]);const Le=k.useMemo(()=>{if(!je||!v)return e;const K=je.toLowerCase();return e.filter(ve=>ve.label.toLowerCase().includes(K)||ve.description?.toLowerCase().includes(K))},[e,je,v]),Do=me&&qe>=0&&qe{const K={},ve=[];return Le.forEach(Fe=>{Fe.group?(K[Fe.group]||(K[Fe.group]=[]),K[Fe.group].push(Fe)):ve.push(Fe)}),{groups:K,ungrouped:ve,hasGroups:Object.keys(K).length>0}},[Le]),Mo=k.useCallback(K=>y?Pe.includes(K):Pe===K,[Pe,y]),jo=k.useMemo(()=>y?e.filter(K=>Pe.includes(K.value)):e.find(K=>K.value===Pe),[Pe,e,y]),sn=k.useCallback(K=>{if(K.disabled)return;let ve;if(y){const Fe=Pe;Fe.includes(K.value)?ve=Fe.filter(Ve=>Ve!==K.value):ve=[...Fe,K.value],Ye(ve),u?.(ve),U&&ve.length>0&&(xe(!1),tt(""))}else ve=K.value,Ye(ve),u?.(ve),xe(!1),tt("");ce(-1)},[Pe,y,u,U]),As=k.useCallback(()=>{if(!y)return;const K=Pe,Fe=Le.filter(Ht=>!Ht.disabled).map(Ht=>Ht.value),Ve=Fe.every(Ht=>K.includes(Ht));let Tt;Ve?Tt=K.filter(Ht=>!Fe.includes(Ht)):Tt=[...new Set([...K,...Fe])],Ye(Tt),u?.(Tt)},[y,Pe,Le,u]),Eo=k.useCallback(K=>{K.stopPropagation();const ve=y?[]:"";Ye(ve),u?.(ve),tt("")},[y,u]),vn=k.useCallback(()=>{if(!Z||y||!je.trim())return!1;const K=je.trim(),ve=e.find(Fe=>Fe.value===K||Fe.label.toLowerCase()===K.toLowerCase());return ve?sn(ve):(Ye(K),u?.(K),xe(!1),tt("")),!0},[Z,y,je,e,sn,u]),io=k.useCallback(K=>{if(!c)switch(K.key){case"Enter":K.preventDefault(),me?qe>=0&&qeveve>0?ve-1:0);break;case"Tab":me&&(Z&&!y&&je.trim()&&vn(),xe(!1));break}},[c,me,qe,Le,sn,Z,y,je,vn]);k.useEffect(()=>{const K=ve=>{if(It.current&&!It.current.contains(ve.target)){if(Z&&!y&&je.trim()){const Fe=je.trim(),Ve=e.find(Tt=>Tt.value===Fe||Tt.label.toLowerCase()===Fe.toLowerCase());Ve?(Ye(Ve.value),u?.(Ve.value)):(Ye(Fe),u?.(Fe))}xe(!1),tt("")}};return document.addEventListener("mousedown",K),()=>document.removeEventListener("mousedown",K)},[Z,y,je,e,u]),k.useEffect(()=>{if(!at.current){at.current=!0;return}$?.(me)},[me,$]),k.useEffect(()=>{me&&v&&wn.current&&wn.current.focus()},[me,v]),k.useEffect(()=>{qe>=0&&Mt.current&&(document.getElementById(`${G}-option-${qe}`)?.scrollIntoView({block:"nearest",behavior:"smooth"}),Mt.current=!1)},[qe,G]);const ao=["select",`select--${m}`,`select--shape-${h}`,`select--placement-${O}`,me&&"select--open",c&&"select--disabled",F&&"select--error",y&&"select--multiple",oe].filter(Boolean).join(" "),Ar=()=>{if(W){const K=W(jo);if(K)return K}if(y){const K=jo;if(K.length===0)return l.jsx("span",{className:"select__placeholder",children:ie});const ve=K.slice(0,E),Fe=K.length-E;return l.jsxs("div",{className:"select__tags",children:[ve.map(Ve=>l.jsxs("span",{className:"select__tag",children:[Ve.icon&&l.jsx("span",{className:"select__tag-icon",children:Ve.icon}),l.jsx("span",{className:"select__tag-label",children:Ve.label}),l.jsx("button",{className:"select__tag-remove",type:"button","aria-label":L(Ve),onClick:Tt=>{Tt.stopPropagation(),sn(Ve)},children:l.jsx(Dc,{size:10})})]},Ve.value)),Fe>0&&l.jsxs("span",{className:"select__tag select__tag--more",children:["+",Fe]})]})}else{const K=jo;return K?l.jsxs("span",{className:"select__value",children:[K.icon&&l.jsx("span",{className:"select__value-icon",children:K.icon}),l.jsx("span",{className:"select__value-label",children:K.label})]}):Z&&Pe&&Pe!==""?l.jsx("span",{className:"select__value",children:l.jsx("span",{className:"select__value-label select__value-label--custom",children:String(Pe)})}):l.jsx("span",{className:"select__placeholder",children:ie})}},Lo=(K,ve)=>{const Fe=Mo(K.value),Ve=ve===qe;return l.jsxs("div",{id:`${G}-option-${ve}`,className:`select__option ${Fe?"select__option--selected":""} ${K.disabled?"select__option--disabled":""} ${Ve?"select__option--highlighted":""}`,onClick:()=>sn(K),onMouseEnter:()=>ce(ve),role:"option","aria-selected":Fe,"aria-disabled":K.disabled,children:[y&&l.jsx("span",{className:`select__checkbox ${Fe?"select__checkbox--checked":""}`,children:Fe&&l.jsx(Cg,{})}),B?B(K):l.jsxs("div",{className:"select__option-content",children:[K.icon&&l.jsx("span",{className:"select__option-icon",children:K.icon}),l.jsxs("div",{className:"select__option-text",children:[l.jsx("div",{className:"select__option-label",children:K.label}),K.description&&l.jsx("div",{className:"select__option-description",children:K.description})]})]})]},K.value)};return l.jsxs("div",{className:ao,ref:It,children:[f&&l.jsx("label",{id:C,className:"select__label",htmlFor:G,children:f}),l.jsxs("div",{id:G,className:"select__trigger",onClick:()=>!c&&xe(!me),onKeyDown:io,tabIndex:c?-1:0,role:"combobox","aria-expanded":me,"aria-haspopup":"listbox","aria-disabled":c,"aria-controls":me?N:void 0,"aria-activedescendant":Do,"aria-labelledby":f?C:void 0,"aria-describedby":F&&_?X:void 0,"aria-invalid":F||void 0,children:[Ar(),l.jsxs("div",{className:"select__suffix",children:[A&&l.jsx("span",{className:"select__loading",children:l.jsx(Pi,{size:"tiny",className:"select__loading-spinner"})}),b&&!A&&(y?Pe.length>0:Pe)&&l.jsx("button",{className:"select__clear",onClick:Eo,type:"button","aria-label":fe,children:l.jsx(Dc,{})}),l.jsx("span",{className:`select__arrow ${me?"select__arrow--open":""}`,children:l.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:l.jsx("path",{d:"M2 4L6 8L10 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]}),me&&l.jsxs("div",{className:`select__dropdown select__dropdown--${O}`,ref:so,style:I?{width:I,left:ee==="end"?"auto":0,right:ee==="end"?0:"auto"}:void 0,children:[v&&l.jsxs("div",{className:"select__search",children:[l.jsx("input",{ref:wn,type:"text",className:"select__search-input",placeholder:ne,value:je,role:"combobox","aria-expanded":me,"aria-haspopup":"listbox","aria-controls":N,"aria-activedescendant":Do,"aria-labelledby":f?C:void 0,"aria-describedby":F&&_?X:void 0,"aria-invalid":F||void 0,onChange:K=>tt(K.target.value),onClick:K=>K.stopPropagation(),onKeyDown:K=>{K.key==="Enter"?(K.preventDefault(),qe>=0&&qeveve>0?ve-1:0))}}),je&&l.jsx("button",{className:"select__search-clear",type:"button","aria-label":we,onClick:K=>{K.stopPropagation(),tt(""),ce(-1),wn.current?.focus()},children:l.jsx(Dc,{})})]}),y&&S&&Le.length>0&&l.jsxs("button",{className:"select__select-all",onClick:As,type:"button",children:[l.jsx("span",{className:`select__checkbox ${Le.filter(K=>!K.disabled).every(K=>Mo(K.value))?"select__checkbox--checked":""}`,children:Le.filter(K=>!K.disabled).every(K=>Mo(K.value))&&l.jsx(Cg,{})}),l.jsx("span",{children:se})]}),l.jsx("div",{id:N,className:"select__options",role:"listbox","aria-labelledby":f?C:void 0,children:Le.length===0?A?l.jsxs("div",{className:"select__empty select__empty--loading",children:[l.jsx(Pi,{size:"tiny",className:"select__loading-spinner"}),l.jsx("span",{children:pe})]}):Z&&!y&&je.trim()?l.jsxs("button",{className:"select__custom-value-hint",type:"button",role:"option","aria-selected":"false",onClick:()=>vn(),children:[l.jsxs("span",{className:"select__custom-value-text",children:['"',je.trim(),'"']}),l.jsx("span",{className:"select__custom-value-action",children:Se})]}):l.jsx("div",{className:"select__empty",children:ue}):Io.hasGroups?(()=>{let K=0;return l.jsxs(l.Fragment,{children:[Io.ungrouped.map(ve=>Lo(ve,K++)),Object.entries(Io.groups).map(([ve,Fe])=>l.jsxs("div",{className:"select__group",children:[l.jsx("div",{className:"select__group-label",children:ve}),Fe.map(Ve=>Lo(Ve,K++))]},ve))]})})():l.jsxs(l.Fragment,{children:[Le.map((K,ve)=>Lo(K,ve)),Z&&!y&&je.trim()&&!Le.some(K=>K.label.toLowerCase()===je.trim().toLowerCase())&&l.jsxs("button",{className:"select__custom-value-hint",type:"button",role:"option","aria-selected":"false",onClick:()=>vn(),children:[l.jsxs("span",{className:"select__custom-value-text",children:['"',je.trim(),'"']}),l.jsx("span",{className:"select__custom-value-action",children:Se})]})]})})]}),F&&_&&l.jsx("div",{id:X,className:"select__error-message",children:_})]})},yh=k.forwardRef(({label:i,description:e,size:n="medium",indeterminate:s=!1,error:r=!1,disabled:c=!1,className:u="",children:m,...h},f)=>{const y=De.useRef(null);De.useImperativeHandle(f,()=>y.current),De.useEffect(()=>{y.current&&(y.current.indeterminate=s)},[s]);const v=["ds-checkbox",`ds-checkbox--${n}`,r&&"ds-checkbox--error",c&&"ds-checkbox--disabled",u].filter(Boolean).join(" ");return l.jsxs("label",{className:v,children:[l.jsxs("div",{className:"ds-checkbox__wrapper",children:[l.jsx("input",{ref:y,type:"checkbox",className:"ds-checkbox__input",disabled:c,...h}),l.jsx("span",{className:"ds-checkbox__box",children:l.jsx("svg",{className:"ds-checkbox__icon",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s?l.jsx("line",{x1:"4",y1:"8",x2:"12",y2:"8",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"}):l.jsx("path",{d:"M3 8L6.5 11.5L13 4.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),(i||e||m)&&l.jsxs("div",{className:"ds-checkbox__content",children:[i&&l.jsx("span",{className:"ds-checkbox__label",children:i}),e&&l.jsx("span",{className:"ds-checkbox__description",children:e}),m]})]})});yh.displayName="Checkbox";const wh=k.forwardRef(({label:i,description:e,size:n="medium",error:s=!1,disabled:r=!1,className:c="",children:u,...m},h)=>{const f=["ds-radio",`ds-radio--${n}`,s&&"ds-radio--error",r&&"ds-radio--disabled",c].filter(Boolean).join(" ");return l.jsxs("label",{className:f,children:[l.jsxs("span",{className:"ds-radio__wrapper",children:[l.jsx("input",{ref:h,type:"radio",className:"ds-radio__input",disabled:r,...m}),l.jsx("span",{className:"ds-radio__mark"})]}),(i||e||u)&&l.jsxs("span",{className:"ds-radio__content",children:[i&&l.jsx("span",{className:"ds-radio__label",children:i}),e&&l.jsx("span",{className:"ds-radio__description",children:e}),u]})]})});wh.displayName="Radio";const wr=k.forwardRef(({label:i,description:e,size:n="medium",loading:s=!1,checkedText:r,uncheckedText:c,disabled:u=!1,className:m="",checked:h,children:f,...y},v)=>{const b=u||s,S=["ds-switch",`ds-switch--${n}`,b&&"ds-switch--disabled",s&&"ds-switch--loading",m].filter(Boolean).join(" "),A=["ds-switch__track",h&&"ds-switch__track--checked"].filter(Boolean).join(" ");return l.jsxs("label",{className:S,children:[l.jsxs("div",{className:"ds-switch__wrapper",children:[l.jsx("input",{ref:v,type:"checkbox",className:"ds-switch__input",disabled:b,checked:h,...y}),l.jsxs("span",{className:A,children:[(r||c)&&l.jsx("span",{className:"ds-switch__text",children:h?r:c}),l.jsx("span",{className:"ds-switch__thumb",children:s&&l.jsx("svg",{className:"ds-switch__loading",viewBox:"0 0 16 16",children:l.jsx("circle",{cx:"8",cy:"8",r:"6",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeDasharray:"31.4",strokeDashoffset:"10"})})})]})]}),(i||e||f)&&l.jsxs("div",{className:"ds-switch__content",children:[i&&l.jsx("span",{className:"ds-switch__label",children:i}),e&&l.jsx("span",{className:"ds-switch__description",children:e}),f]})]})});wr.displayName="Switch";const vh=k.forwardRef(({label:i,error:e=!1,errorMessage:n,hint:s,autoResize:r=!1,showCount:c=!1,maxLength:u,variant:m="default",className:h="",value:f,onChange:y,style:v,...b},S)=>{const A=k.useId(),F=b.id??`textarea-${A}`,_=`${F}-hint`,E=`${F}-error`,j=`${F}-count`,z=[b["aria-describedby"],e&&n?E:void 0,!e&&s?_:void 0,c?j:void 0].filter(Boolean).join(" ")||void 0,B=k.useRef(null),[W,I]=De.useState(0);k.useImperativeHandle(S,()=>B.current);const ee=k.useCallback(()=>{r&&B.current&&(B.current.style.height="auto",B.current.style.height=`${B.current.scrollHeight}px`)},[r]);De.useEffect(()=>{ee()},[f,ee]),De.useEffect(()=>{const U=typeof f=="string"?f.length:0;I(U)},[f]);const oe=U=>{const Z=U.target.value;I(Z.length),ee(),y?.(U)},O=["ds-textarea",`ds-textarea--${m}`,e&&"ds-textarea--error",b.disabled&&"ds-textarea--disabled",h].filter(Boolean).join(" ");return l.jsxs("div",{className:O,children:[i&&l.jsxs("label",{className:"ds-textarea__label",htmlFor:F,children:[i,b.required&&l.jsx("span",{className:"ds-textarea__required",children:"*"})]}),l.jsx("div",{className:"ds-textarea__wrapper",children:l.jsx("textarea",{ref:B,id:F,className:"ds-textarea__field",value:f,onChange:oe,maxLength:u,style:v,"aria-describedby":z,"aria-invalid":e||void 0,...b})}),(s||n||c)&&l.jsxs("div",{className:"ds-textarea__footer",children:[l.jsxs("div",{className:"ds-textarea__hint-wrapper",children:[e&&n&&l.jsx("span",{id:E,className:"ds-textarea__error-message",children:n}),!e&&s&&l.jsx("span",{id:_,className:"ds-textarea__hint",children:s})]}),c&&l.jsxs("span",{id:j,className:"ds-textarea__count",children:[W,u&&` / ${u}`]})]})]})});vh.displayName="Textarea";function qee(...i){return i.filter(Boolean).join(" ")}const vd=k.forwardRef(({className:i,padding:e="compact",role:n="menu",...s},r)=>l.jsx("div",{ref:r,className:qee("ds-popup-menu",`ds-popup-menu--padding-${e}`,i),role:n,...s}));vd.displayName="PopupMenu";const bh=({entry:i,onClose:e,isSubmenuOpen:n,onSubmenuTrigger:s})=>{const r=!!i.submenu?.length,c=()=>{r?s?.():i.disabled||(i.onClick?.(),e())};return l.jsxs("button",{type:"button",role:"menuitem",className:`cl-dropdown-menu__item${n?" is-open":""}${i.checked?" is-checked":""}`,disabled:!r&&i.disabled,"aria-haspopup":r||void 0,"aria-expanded":r?n:void 0,"aria-checked":i.checked,onClick:c,children:[l.jsx("span",{className:"cl-dropdown-menu__item-label",children:i.label}),i.checked?l.jsx(xs,{size:13,className:"cl-dropdown-menu__check-icon","aria-hidden":"true"}):null,r?l.jsx(oo,{size:13,className:`cl-dropdown-menu__submenu-icon${n?" is-open":""}`,"aria-hidden":"true"}):null]})},Vee=({items:i,direction:e,onClose:n})=>{const s=k.useRef(null),[r,c]=k.useState(0);return k.useLayoutEffect(()=>{const u=s.current;if(!u)return;const m=u.getBoundingClientRect(),h=m.bottom-(window.innerHeight-8);h>0&&c(-Math.min(h,m.top-8))},[]),l.jsx(vd,{ref:s,className:`cl-dropdown-menu__submenu is-${e}`,style:r?{top:r}:void 0,onMouseDown:u=>u.stopPropagation(),children:i.map(u=>{if(u.type==="separator")return l.jsx("div",{className:"cl-dropdown-menu__separator",role:"separator","aria-orientation":"horizontal"},u.id);if(u.type==="label"){const m=Array.isArray(u.content)?u.content:[u.content];return l.jsx("div",{className:"cl-dropdown-menu__label",role:"presentation",children:m.map((h,f)=>l.jsx("span",{children:h},f))},u.id)}return l.jsx(bh,{entry:u,onClose:n},u.id)})})},Gee=({items:i,onClose:e,openSubmenuId:n,submenuDirection:s,onSubmenuTrigger:r})=>l.jsx(l.Fragment,{children:i.map(c=>{if(c.type==="separator")return l.jsx("div",{className:"cl-dropdown-menu__separator",role:"separator","aria-orientation":"horizontal"},c.id);if(c.type==="label"){const h=Array.isArray(c.content)?c.content:[c.content];return l.jsx("div",{className:"cl-dropdown-menu__label",role:"presentation",children:h.map((f,y)=>l.jsx("span",{children:f},y))},c.id)}const u=!!c.submenu?.length,m=n===c.id;return l.jsxs("div",{className:"cl-dropdown-menu__submenu-wrap",children:[l.jsx(bh,{entry:c,onClose:e,isSubmenuOpen:m,onSubmenuTrigger:u?()=>r(c.id):void 0}),u&&m&&c.submenu?l.jsx(Vee,{items:c.submenu,direction:s,onClose:e}):null]},c.id)})}),Kee=({open:i,anchorRef:e,items:n,onClose:s,align:r="left",minWidth:c=160})=>{const[u,m]=k.useState(null),[h,f]=k.useState(null),[y,v]=k.useState("right"),b=k.useRef(null),S=k.useCallback(()=>{const F=e.current;if(!F)return;const _=F.getBoundingClientRect(),E=8,j=_.bottom+4;let z;r==="right"?z=_.right-c:z=_.left,z=Math.min(z,window.innerWidth-c-E),z=Math.max(z,E),m({top:j,left:z})},[r,e,c]);if(k.useLayoutEffect(()=>{if(!i){m(null),f(null);return}S()},[i,S]),k.useEffect(()=>{if(!i)return;const F=()=>S();return window.addEventListener("resize",F),window.addEventListener("scroll",F,!0),()=>{window.removeEventListener("resize",F),window.removeEventListener("scroll",F,!0)}},[i,S]),k.useEffect(()=>{if(!i)return;const F=_=>{_.key==="Escape"&&(_.preventDefault(),h?f(null):s())};return document.addEventListener("keydown",F),()=>document.removeEventListener("keydown",F)},[i,s,h]),!i||!u||typeof document>"u")return null;const A=F=>{const _=b.current;if(_){const E=_.getBoundingClientRect();v(window.innerWidth-E.right>=180?"right":"left")}f(E=>E===F?null:F)};return fr.createPortal(l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"cl-dropdown-menu__backdrop","aria-hidden":"true",onMouseDown:F=>F.stopPropagation(),onClick:s}),l.jsx(vd,{ref:b,className:"cl-dropdown-menu",style:{top:u.top,left:u.left,minWidth:c},onMouseDown:F=>F.stopPropagation(),children:l.jsx(Gee,{items:n,onClose:s,openSubmenuId:h,submenuDirection:y,onSubmenuTrigger:A})})]}),document.body)},nn=({children:i,variant:e="neutral",className:n=""})=>{const s=["badge",`badge--${e}`,n].filter(Boolean).join(" ");return l.jsx("span",{className:s,children:i})},Qee="Close alert",bd=k.forwardRef(({type:i="info",title:e,message:n,description:s,closable:r=!1,onClose:c,showIcon:u=!0,className:m="",style:h,closeAriaLabel:f=Qee},y)=>{const[v,b]=k.useState(!0),S=()=>{b(!1),c?.()};if(!v)return null;const A={success:l.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",children:l.jsx("path",{d:"M13.5 4L6 11.5L2.5 8",strokeLinecap:"round",strokeLinejoin:"round"})}),error:l.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[l.jsx("circle",{cx:"8",cy:"8",r:"6"}),l.jsx("path",{d:"M8 4.5V8.5M8 11H8.01",strokeLinecap:"round"})]}),warning:l.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[l.jsx("path",{d:"M8 1.5L14.5 13H1.5L8 1.5Z",strokeLinejoin:"round"}),l.jsx("path",{d:"M8 6V9M8 11H8.01",strokeLinecap:"round"})]}),info:l.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[l.jsx("circle",{cx:"8",cy:"8",r:"6"}),l.jsx("path",{d:"M8 11V8M8 5H8.01",strokeLinecap:"round"})]})},F=["alert",`alert--${i}`,m].filter(Boolean).join(" ");return l.jsxs("div",{ref:y,className:F,style:h,role:"alert","aria-live":i==="error"?"assertive":"polite",children:[u&&l.jsx("div",{className:"alert__icon",children:A[i]}),l.jsxs("div",{className:"alert__content",children:[e&&l.jsx("div",{className:"alert__title",children:e}),l.jsx("div",{className:"alert__message",children:n}),s&&l.jsx("div",{className:"alert__description",children:s})]}),r&&l.jsx("button",{className:"alert__close",type:"button",onClick:S,"aria-label":f,children:l.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5","aria-hidden":"true",children:l.jsx("path",{d:"M1 1L11 11M11 1L1 11",strokeLinecap:"round"})})})]})});bd.displayName="Alert";const Jee=k.forwardRef(({children:i,variant:e="default",interactive:n=!1,padding:s="medium",radius:r="medium",fullWidth:c=!1,className:u="",...m},h)=>{const f=["v-card",`v-card--${e}`,`v-card--padding-${s}`,`v-card--radius-${r}`,n&&"v-card--interactive",c&&"v-card--full-width",u].filter(Boolean).join(" ");return l.jsx("div",{ref:h,className:f,...m,children:i})});Jee.displayName="Card";const Yee=k.forwardRef(({title:i,subtitle:e,extra:n,children:s,className:r="",...c},u)=>l.jsxs("div",{ref:u,className:`v-card-header ${r}`,...c,children:[l.jsxs("div",{className:"v-card-header__content",children:[i&&l.jsx("div",{className:"v-card-header__title",children:i}),e&&l.jsx("div",{className:"v-card-header__subtitle",children:e}),s]}),n&&l.jsx("div",{className:"v-card-header__extra",children:n})]}));Yee.displayName="CardHeader";const Zee=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:`v-card-body ${e}`,...n,children:i}));Zee.displayName="CardBody";const Xee=k.forwardRef(({children:i,align:e="right",className:n="",...s},r)=>l.jsx("div",{ref:r,className:`v-card-footer v-card-footer--${e} ${n}`,...s,children:i}));Xee.displayName="CardFooter";const ete={small:"small",medium:"medium",large:"large"},kh=({size:i="medium",text:e,className:n=""})=>l.jsxs("div",{className:`cube-loading cube-loading--${i} ${n}`,children:[l.jsx(Pi,{size:ete[i],className:"cube-loading__matrix",ariaHidden:!0}),e&&l.jsx("div",{className:"cube-loading__text",children:e})]});kh.displayName="CubeLoading";const tte=({size:i})=>l.jsxs("svg",{width:i,height:i,viewBox:"0 0 120 120",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[l.jsx("circle",{cx:"60",cy:"60",r:"50",fill:"rgba(96, 165, 250, 0.1)"}),l.jsx("path",{d:"M40 50C40 44.4772 44.4772 40 50 40H70C75.5228 40 80 44.4772 80 50V70C80 75.5228 75.5228 80 70 80H50C44.4772 80 40 75.5228 40 70V50Z",fill:"rgba(96, 165, 250, 0.2)"}),l.jsx("circle",{cx:"52",cy:"55",r:"4",fill:"rgba(96, 165, 250, 0.4)"}),l.jsx("circle",{cx:"68",cy:"55",r:"4",fill:"rgba(96, 165, 250, 0.4)"}),l.jsx("path",{d:"M52 68C52 65.7909 53.7909 64 56 64H64C66.2091 64 68 65.7909 68 68",stroke:"rgba(96, 165, 250, 0.4)",strokeWidth:"3",strokeLinecap:"round"})]});function nte(i){return typeof i=="number"?i:{small:80,medium:120,large:160}[i??"medium"]}const kd=({title:i,description:e,actions:n,image:s,imageSize:r="medium",children:c,className:u="",style:m})=>{const h=nte(r),f=e??(i?void 0:"No data");return l.jsxs("div",{className:["ds-empty-state",u].filter(Boolean).join(" "),style:m,children:[l.jsx("div",{className:"ds-empty-state__image",children:s||l.jsx(tte,{size:h})}),(i||f)&&l.jsxs("div",{className:"ds-empty-state__description",children:[i&&l.jsx("strong",{children:i}),f&&l.jsx("span",{children:f})]}),(n||c)&&l.jsx("div",{className:"ds-empty-state__footer",children:n??c})]})};kd.displayName="EmptyState";function Sh(...i){return i.filter(Boolean).join(" ")}const xh=k.forwardRef(({className:i,size:e="xs",shape:n="circle",variant:s="ghost",...r},c)=>l.jsx(ze,{ref:c,className:Sh("ds-floating-card__action",i),size:e,shape:n,variant:s,...r}));xh.displayName="FloatingCardAction";const Ch=k.forwardRef(({children:i,className:e,padding:n="default",onDismiss:s,dismissLabel:r="Dismiss floating card",dismissTooltip:c,...u},m)=>l.jsxs("div",{ref:m,className:Sh("ds-floating-card",`ds-floating-card--padding-${n}`,!!s&&"ds-floating-card--dismissible",e),...u,children:[i,s&&l.jsx(xh,{className:"ds-floating-card__dismiss",type:"button",size:"xs",shape:"circle",variant:"ghost","aria-label":r,tooltip:c,onClick:s,children:l.jsx(Cs,{"aria-hidden":"true",size:14,strokeWidth:2})})]}));Ch.displayName="FloatingCard";const Ah=k.forwardRef(({variant:i="default",shape:e="default",focusTone:n="default",inputSize:s="medium",size:r,error:c=!1,errorMessage:u,prefix:m,suffix:h,label:f,hint:y,description:v,className:b="",disabled:S,...A},F)=>{const _=k.useId(),E=A.id??`input-${_}`,j=`${E}-hint`,z=`${E}-error`,B=[A["aria-describedby"],!c&&(y??v)?j:void 0,c&&u?z:void 0].filter(Boolean).join(" ")||void 0,W=r??s,I=["ds-input-wrapper",`ds-input-wrapper--${i}`,e==="pill"&&"ds-input-wrapper--pill",n==="danger"&&"ds-input-wrapper--focus-danger",`ds-input-wrapper--${W}`,c&&"ds-input-wrapper--error",S&&"ds-input-wrapper--disabled",b].filter(Boolean).join(" ");return l.jsxs("div",{className:I,children:[f&&l.jsx("label",{className:"ds-input-label",htmlFor:E,children:f}),l.jsxs("div",{className:"ds-input-container",children:[m&&l.jsx("span",{className:"ds-input-prefix",children:m}),l.jsx("input",{ref:F,id:E,className:"ds-input",disabled:S,"aria-describedby":B,"aria-invalid":c||void 0,...A}),h&&l.jsx("span",{className:"ds-input-suffix",children:h})]}),!c&&(y??v)&&l.jsx("span",{id:j,className:"ds-input-error-message",children:y??v}),c&&u&&l.jsx("span",{id:z,className:"ds-input-error-message",children:u})]})});Ah.displayName="Input";const Fi=Ah,bs=k.forwardRef(({options:i,value:e,defaultValue:n,onChange:s,size:r="medium",variant:c="default",stretch:u=!1,disabled:m=!1,ariaLabel:h,className:f="",...y},v)=>{const b=k.useId(),S=k.useMemo(()=>i.find(B=>!B.disabled)?.value??i[0]?.value??"",[i]),[A,F]=k.useState(n??S),_=e??A;k.useEffect(()=>{!_&&S&&e===void 0&&F(S)},[S,_,e]);const E=(B,W)=>{m||W||(e===void 0&&F(B),s?.(B))},j=B=>{document.getElementById(`${b}-${B}`)?.focus()},z=(B,W)=>{const I=i.map((O,U)=>({option:O,index:U})).filter(({option:O})=>!O.disabled),ee=I.findIndex(({index:O})=>O===W);if(ee===-1)return;let oe;B.key==="ArrowRight"||B.key==="ArrowDown"?oe=I[(ee+1)%I.length]:B.key==="ArrowLeft"||B.key==="ArrowUp"?oe=I[(ee-1+I.length)%I.length]:B.key==="Home"?oe=I[0]:B.key==="End"&&(oe=I[I.length-1]),oe&&(B.preventDefault(),E(oe.option.value,oe.option.disabled),j(oe.option.value))};return l.jsx("div",{ref:v,className:["ds-segmented-control",`ds-segmented-control--${r}`,`ds-segmented-control--${c}`,u&&"ds-segmented-control--stretch",m&&"ds-segmented-control--disabled",f].filter(Boolean).join(" "),role:"radiogroup","aria-label":h,"aria-disabled":m||void 0,...y,children:i.map((B,W)=>{const I=_===B.value;return l.jsxs("button",{id:`${b}-${B.value}`,className:["ds-segmented-control__item",I&&"ds-segmented-control__item--selected"].filter(Boolean).join(" "),type:"button",role:"radio","aria-checked":I,disabled:m||B.disabled,tabIndex:I?0:-1,onClick:()=>E(B.value,B.disabled),onKeyDown:ee=>z(ee,W),children:[B.icon&&l.jsx("span",{className:"ds-segmented-control__icon",children:B.icon}),l.jsx("span",{className:"ds-segmented-control__label",children:B.label})]},B.value)})})});bs.displayName="SegmentedControl";const Zc=k.forwardRef(({ariaLabel:i,className:e="",disabled:n=!1,onChange:s,options:r,size:c="small",stretch:u=!1,value:m,...h},f)=>l.jsx(bs,{ref:f,ariaLabel:i,className:["ds-divider-switch",c==="medium"&&"ds-divider-switch--medium",e].filter(Boolean).join(" "),disabled:n,onChange:s,options:r,size:c==="medium"?"medium":"small",stretch:u,value:m,...h}));Zc.displayName="DividerSwitch";const Sd=k.forwardRef(({appearance:i="divider",ariaLabel:e,className:n="",disabled:s=!1,onChange:r,options:c,style:u,value:m,...h},f)=>{const y=Math.max(0,c.findIndex(S=>S.value===m)),v=Math.max(1,c.length),b=i==="slider"?{...u,"--ds-mode-switch-active-offset":`${y*100}%`,"--ds-mode-switch-indicator-width":`calc(${100/v}% - ${4/v}px)`,"--ds-mode-switch-option-count":v}:u??{};return l.jsx(bs,{ref:f,ariaLabel:e,className:["ds-mode-switch",`ds-mode-switch--${i}`,n].filter(Boolean).join(" "),disabled:s,onChange:r,options:c,size:"small",style:b,value:m,...h})});Sd.displayName="ModeSwitch";const Ag={increase:"Increase value",decrease:"Decrease value"},xd=k.forwardRef((i,e)=>{const{value:n,onChange:s,min:r=-1/0,max:c=1/0,step:u=1,unit:m,disabled:h=!1,size:f="medium",variant:y="default",showButtons:v=!0,precision:b=0,className:S="",label:A,id:F,error:_=!1,errorMessage:E,hint:j,draggable:z=!1,disableWheel:B=!1,increaseAriaLabel:W=Ag.increase,decreaseAriaLabel:I=Ag.decrease,placeholder:ee,nullable:oe=!1}=i,O=k.useId(),U=F??`number-field-${O}`,Z=`${U}-hint`,re=`${U}-error`,se=[_&&E?re:void 0,!_&&j?Z:void 0].filter(Boolean).join(" ")||void 0,[pe,fe]=k.useState(!1),[we,L]=k.useState(n===null?"":String(n)),[$,te]=k.useState(!1),[G,C]=k.useState(!1),N=k.useRef(null),X=k.useRef(null),ie=k.useCallback(ce=>ce===null?"":b>0?ce.toFixed(b):String(Math.round(ce)),[b]),ne=k.useCallback(ce=>{if(ce===null){oe&&s(null);return}s(ce)},[oe,s]);k.useEffect(()=>{pe||L(ie(n))},[ie,pe,n]);const ue=k.useCallback(ce=>Math.min(c,Math.max(r,ce)),[c,r]),Se=k.useCallback(ce=>{if(h)return;const at=ue(n===null?0:n+ce*u);ne(at),L(ie(at))},[ue,h,ne,ie,u,n]),me=k.useCallback(()=>Se(1),[Se]),xe=k.useCallback(()=>Se(-1),[Se]),Pe=k.useCallback(()=>{fe(!1);const ce=we.trim();if(ce===""){if(oe){n!==null&&ne(null),L("");return}L(ie(n));return}const at=Number(ce);if(Number.isNaN(at)){L(ie(n));return}const It=ue(at);ne(It),L(ie(It))},[ue,ne,ie,we,oe,n]),Ye=k.useCallback(ce=>{ce.key==="Enter"?X.current?.blur():ce.key==="Escape"?(fe(!1),L(ie(n)),X.current?.blur()):ce.key==="ArrowUp"?(ce.preventDefault(),me()):ce.key==="ArrowDown"&&(ce.preventDefault(),xe())},[xe,ie,me,n]),je=k.useCallback(ce=>{!z||h||n===null||(ce.preventDefault(),te(!0),N.current={y:ce.clientY,value:n},document.body.style.cursor="ns-resize")},[h,z,n]);k.useEffect(()=>{if(!$)return;const ce=It=>{if(!N.current)return;const wn=N.current.y-It.clientY,so=Math.round(wn/5);ne(ue(N.current.value+so*u))},at=()=>{te(!1),N.current=null,document.body.style.cursor=""};return document.addEventListener("mousemove",ce),document.addEventListener("mouseup",at),()=>{document.removeEventListener("mousemove",ce),document.removeEventListener("mouseup",at),document.body.style.cursor=""}},[ue,ne,$,u]);const tt=k.useCallback(ce=>{h||B||!G||(ce.preventDefault(),ce.deltaY<0?me():xe())},[xe,h,B,me,G]),qe=["ds-number-field",`ds-number-field--${f}`,`ds-number-field--${y}`,h&&"ds-number-field--disabled",_&&"ds-number-field--error",$&&"ds-number-field--dragging",pe&&"ds-number-field--editing",S].filter(Boolean).join(" ");return l.jsxs("div",{className:qe,children:[A&&l.jsx("label",{className:"ds-number-field__label",htmlFor:U,children:A}),l.jsxs("div",{className:"ds-number-field__container",onMouseEnter:()=>C(!0),onMouseLeave:()=>C(!1),onWheel:tt,children:[l.jsxs("div",{className:"ds-number-field__value-area",onMouseDown:z&&n!==null?je:void 0,style:{cursor:z&&!h&&n!==null?"ns-resize":"text"},children:[l.jsx("input",{ref:ce=>{typeof e=="function"?e(ce):e&&(e.current=ce),X.current=ce},type:"text",id:U,inputMode:"decimal",role:"spinbutton",className:"ds-number-field__input",value:we,placeholder:ee,onChange:ce=>L(ce.target.value),onFocus:()=>fe(!0),onBlur:Pe,onKeyDown:Ye,disabled:h,"aria-invalid":_||void 0,"aria-describedby":se,"aria-valuemin":Number.isFinite(r)?r:void 0,"aria-valuemax":Number.isFinite(c)?c:void 0,"aria-valuenow":n??void 0,"aria-valuetext":n===null&&ee?ee:void 0}),m&&we.trim()!==""&&l.jsx("span",{className:"ds-number-field__unit",children:m})]}),v&&y!=="compact"&&l.jsx("div",{className:"ds-number-field__buttons",children:y==="stepper"?l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"ds-number-field__btn ds-number-field__btn--minus",onClick:xe,disabled:h||n!==null&&n<=r,tabIndex:-1,"aria-label":I,children:l.jsx(nh,{size:12,strokeWidth:2.5})}),l.jsx("button",{type:"button",className:"ds-number-field__btn ds-number-field__btn--plus",onClick:me,disabled:h||n!==null&&n>=c,tabIndex:-1,"aria-label":W,children:l.jsx(oh,{size:12,strokeWidth:2.5})})]}):l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"ds-number-field__btn ds-number-field__btn--up",onClick:me,disabled:h||n!==null&&n>=c,tabIndex:-1,"aria-label":W,children:l.jsx(tZ,{size:14,strokeWidth:2.5})}),l.jsx("button",{type:"button",className:"ds-number-field__btn ds-number-field__btn--down",onClick:xe,disabled:h||n!==null&&n<=r,tabIndex:-1,"aria-label":I,children:l.jsx(no,{size:14,strokeWidth:2.5})})]})}),n!==null&&r!==-1/0&&c!==1/0&&c>r&&l.jsx("div",{className:"ds-number-field__progress",children:l.jsx("div",{className:"ds-number-field__progress-bar",style:{width:`${(n-r)/(c-r)*100}%`}})})]}),(j||E)&&l.jsx("div",{className:"ds-number-field__message",children:_&&E?l.jsx("span",{id:re,className:"ds-number-field__error-message",children:E}):j?l.jsx("span",{id:Z,className:"ds-number-field__hint",children:j}):null})]})});xd.displayName="NumberField";const Ic={placeholder:"Search",button:"Search",clearAriaLabel:"Clear search"};function ote(){return l.jsxs("svg",{className:"search__icon",width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[l.jsx("circle",{cx:"11",cy:"11",r:"7",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"}),l.jsx("path",{d:"M20 20L16.5 16.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}function ste(){return l.jsxs("svg",{className:"search__loading-icon",width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[l.jsx("circle",{className:"search__loading-track",cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"3"}),l.jsx("path",{className:"search__loading-arc",d:"M12 3A9 9 0 0 1 21 12",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]})}const Ri=k.forwardRef(({value:i,defaultValue:e="",placeholder:n,disabled:s=!1,onChange:r,onSearch:c,onClear:u,onKeyDown:m,onFocus:h,onBlur:f,size:y="medium",clearable:v=!0,loading:b=!1,error:S=!1,errorMessage:A,autoFocus:F=!1,maxLength:_,className:E="",expandOnFocus:j=!1,enterToSearch:z=!0,prefixIcon:B,searchButtonText:W,showSearchButton:I=!1,suffixContent:ee,showPrefixIcon:oe=!0,shape:O="default",inputAriaLabel:U,clearAriaLabel:Z=Ic.clearAriaLabel,searchButtonAriaLabel:re,ariaControls:se,ariaExpanded:pe},fe)=>{const we=n??Ic.placeholder,L=W??Ic.button,$=U??we,te=re??L,[G,C]=k.useState(i!==void 0?i:e),[N,X]=k.useState(!1),[ie,ne]=k.useState(!1),ue=k.useRef(null),Se=k.useCallback(ce=>{if(typeof fe=="function"){fe(ce);return}fe&&(fe.current=ce)},[fe]);k.useEffect(()=>{i!==void 0&&C(i)},[i]),k.useEffect(()=>{F&&ue.current&&ue.current.focus()},[F]);const me=k.useCallback(ce=>{const at=ce.target.value;C(at),r?.(at)},[r]),xe=k.useCallback(()=>{!s&&!b&&c?.(G)},[G,c,s,b]),Pe=k.useCallback(ce=>{ce?.stopPropagation(),C(""),r?.(""),u?.(),ue.current?.focus()},[r,u]),Ye=k.useCallback(ce=>{m?.(ce),!ce.defaultPrevented&&(ce.key==="Enter"&&z?(ce.preventDefault(),xe()):ce.key==="Escape"&&(ce.preventDefault(),G?Pe(ce):ue.current?.blur()))},[G,z,xe,Pe,m]),je=k.useCallback(()=>{X(!0),h?.()},[h]),tt=k.useCallback(()=>{X(!1),f?.()},[f]),qe=["search",`search--${y}`,N&&"search--focused",ie&&"search--hovered",s&&"search--disabled",S&&"search--error",b&&"search--loading",j&&"search--expandable",I&&"search--with-button",O==="pill"&&"search--pill",E].filter(Boolean).join(" ");return l.jsxs("div",{className:qe,children:[l.jsxs("div",{className:"search__wrapper",onMouseEnter:()=>ne(!0),onMouseLeave:()=>ne(!1),children:[(oe||b)&&l.jsx("div",{className:"search__prefix",children:b?l.jsx(ste,{}):B||l.jsx(ote,{})}),l.jsx("input",{ref:ce=>{ue.current=ce,Se(ce)},type:"text",className:"search__input",value:G,placeholder:we,disabled:s,maxLength:_,onChange:me,onKeyDown:Ye,onFocus:je,onBlur:tt,"aria-label":$,"aria-controls":se,"aria-expanded":pe}),v&&G&&!b&&!s&&l.jsx("button",{type:"button",className:"search__clear",onClick:Pe,"aria-label":Z,tabIndex:-1,children:l.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:l.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})}),ee&&l.jsx("div",{className:"search__suffix-content",children:ee}),I&&l.jsx("button",{type:"button",className:"search__button",onClick:xe,disabled:s||b,"aria-label":te,children:L})]}),S&&A&&l.jsx("div",{className:"search__error-message",children:A})]})});Ri.displayName="Search";const _h=k.forwardRef(({options:i,value:e,onChange:n,onOptionClick:s,size:r="small",disabled:c=!1,ariaLabel:u,className:m="",...h},f)=>{const y=v=>{c||v.disabled||(v.value!==e&&n?.(v.value),s?.(v.value))};return l.jsx("div",{ref:f,className:["ds-squeeze-segmented-control",`ds-squeeze-segmented-control--${r}`,c&&"ds-squeeze-segmented-control--disabled",m].filter(Boolean).join(" "),role:"radiogroup","aria-label":u,"aria-disabled":c||void 0,...h,children:i.map(v=>{const b=v.value===e;return l.jsxs("button",{ref:v.buttonRef,type:"button",role:"radio","aria-checked":b,"aria-haspopup":b?v.ariaHasPopup:void 0,"aria-expanded":b?v.ariaExpanded:void 0,className:["ds-squeeze-segmented-control__option",b&&"ds-squeeze-segmented-control__option--selected",v.trailing&&b&&"ds-squeeze-segmented-control__option--with-trailing"].filter(Boolean).join(" "),disabled:c||v.disabled,onClick:()=>y(v),children:[l.jsxs("span",{className:"ds-squeeze-segmented-control__content",children:[l.jsx("span",{className:"ds-squeeze-segmented-control__label",children:v.label}),b&&v.detail&&l.jsx("span",{className:"ds-squeeze-segmented-control__detail",title:v.title,children:v.detail})]}),b&&v.trailing&&l.jsx("span",{className:"ds-squeeze-segmented-control__trailing","aria-hidden":"true",children:v.trailing})]},v.value)})})});_h.displayName="SqueezeSegmentedControl";const rr=k.forwardRef(({variant:i="block",width:e,height:n,animated:s=!0,className:r="",style:c,...u},m)=>l.jsx("span",{ref:m,className:["ds-skeleton",`ds-skeleton--${i}`,s&&"ds-skeleton--animated",r].filter(Boolean).join(" "),style:{width:e,height:n,...c},"aria-hidden":"true",...u}));rr.displayName="Skeleton";const lr=k.forwardRef(({lines:i=3,compact:e=!1,avatar:n=!1,className:s="",...r},c)=>l.jsxs("div",{ref:c,className:["ds-loading-skeleton",e&&"ds-loading-skeleton--compact",s].filter(Boolean).join(" "),"aria-busy":"true","aria-label":"Loading",role:"status",...r,children:[n&&l.jsx(rr,{variant:"circle",className:"ds-loading-skeleton__avatar"}),l.jsx("div",{className:"ds-loading-skeleton__content",children:Array.from({length:Math.max(1,i)},(u,m)=>l.jsx(rr,{variant:"text",className:"ds-loading-skeleton__line",style:{"--ds-skeleton-line-scale":m===i-1?"72%":"100%"}},m))})]}));lr.displayName="LoadingSkeleton";const ite=({text:i,effect:e="smooth",speed:n=30,delay:s=0,showCursor:r=!0,cursorStyle:c="line",onComplete:u,onProgress:m,className:h="",autoStart:f=!0,paused:y=!1,charAnimation:v=!1,colorTheme:b="blue"})=>{const[S,A]=k.useState(""),[F,_]=k.useState(0),[E,j]=k.useState(!1),[z,B]=k.useState(!1),W=k.useRef(null),I=k.useRef(0),ee=k.useRef(!1),oe=k.useRef(i),O=k.useCallback(se=>{if(sewe+i[se]),_(se+1);const pe=(se+1)/i.length*100;m?.(pe);let fe=n;e==="glitch"&&Math.random()>.7?fe=n*(Math.random()*2+.5):e==="wave"&&(fe=n+Math.sin(se*.5)*20),W.current=setTimeout(()=>{O(se+1)},Math.max(10,fe))}else B(!0),j(!1),u?.()},[e,u,m,n,i]),U=k.useCallback(()=>{A(""),_(0),B(!1),j(!0),W.current=setTimeout(()=>{O(0)},s)},[s,O]);k.useEffect(()=>{const se=oe.current!==i;let pe=!1;return se&&(oe.current=i,I.current=0,W.current&&clearTimeout(W.current),z?(A(i),_(i.length),B(!0),j(!1),ee.current=!0,pe=!0):(ee.current=!1,A(""),_(0),B(!1),j(!1))),f&&!y&&!ee.current&&!pe&&(ee.current=!0,U()),()=>{W.current&&clearTimeout(W.current)}},[i,f,y,z,U]),k.useEffect(()=>{y&&E?(I.current=F,W.current&&clearTimeout(W.current),j(!1)):!y&&I.current>0&&O(I.current)},[y,F,E,O]);const Z=()=>v?S.split("").map((se,pe)=>{const fe=v?`${pe*.05}s`:"0s",we=pe===S.length-1&&E;return l.jsx("span",{className:`stream-text__char stream-text__char--${e} ${we?"stream-text__char--new":""}`,style:{animationDelay:fe,"--char-index":pe},children:se},`char-${pe}`)}):l.jsx("span",{className:`stream-text__content stream-text__content--${e}`,children:S}),re=()=>["stream-text",`stream-text--${e}`,`stream-text--theme-${b}`,E?"stream-text--streaming":"",z?"stream-text--complete":"",h].filter(Boolean).join(" ");return l.jsxs("span",{className:re(),children:[Z(),r&&!z&&l.jsx("span",{className:`stream-cursor stream-cursor--${c} ${E?"stream-cursor--active":""}`})]})};De.memo(ite,(i,e)=>i.text===e.text&&i.effect===e.effect&&i.speed===e.speed&&i.showCursor===e.showCursor&&i.className===e.className);const Th=k.createContext(void 0),cr=({tabKey:i,children:e,className:n=""})=>{const s=k.useContext(Th);return s?l.jsx("div",{id:s.getPanelId(i),className:`ds-tab-pane ${n}`.trim(),role:"tabpanel","aria-labelledby":s.getTabId(i),tabIndex:0,children:e}):null};cr.displayName="TabPane";const Ph=({activeKey:i,defaultActiveKey:e,onChange:n,onTabClose:s,type:r="line",size:c="medium",stretch:u=!1,children:m,className:h="",style:f})=>{const y=k.useId(),[v,b]=k.useState(e||""),{tabs:S,panes:A}=k.useMemo(()=>{const O=[],U={};return De.Children.forEach(m,Z=>{if(De.isValidElement(Z)&&Z.type===cr){const{tabKey:re,label:se,icon:pe,disabled:fe,closable:we}=Z.props;O.push({key:re,label:se,icon:pe,disabled:fe,closable:we}),U[re]=Z}}),{tabs:O,panes:U}},[m]),F=S.find(O=>!O.disabled)?.key??S[0]?.key??"",_=i!==void 0?i:v||F;De.useEffect(()=>{!v&&F&&i===void 0&&b(F)},[i,F,v]);const E=O=>`${y}-tab-${O}`,j=O=>`${y}-panel-${O}`,z=(O,U)=>{U||(i===void 0&&b(O),n?.(O))},B=(O,U)=>{O.stopPropagation(),s?.(U)},W=O=>{document.getElementById(E(O))?.focus()},I=(O,U)=>{const Z=S.map((pe,fe)=>({tab:pe,index:fe})).filter(({tab:pe})=>!pe.disabled),re=Z.findIndex(({index:pe})=>pe===U);if(re===-1)return;let se;O.key==="ArrowRight"||O.key==="ArrowDown"?se=Z[(re+1)%Z.length]:O.key==="ArrowLeft"||O.key==="ArrowUp"?se=Z[(re-1+Z.length)%Z.length]:O.key==="Home"?se=Z[0]:O.key==="End"&&(se=Z[Z.length-1]),se&&(O.preventDefault(),z(se.tab.key,se.tab.disabled),W(se.tab.key))},ee=["ds-tabs",`ds-tabs--${r}`,`ds-tabs--${c}`,u&&"ds-tabs--stretch",h].filter(Boolean).join(" "),oe={getTabId:E,getPanelId:j};return l.jsx(Th.Provider,{value:oe,children:l.jsxs("div",{className:ee,style:f,children:[l.jsxs("div",{className:"ds-tabs__nav",children:[l.jsx("div",{className:"ds-tabs__nav-list",role:"tablist",children:S.map((O,U)=>l.jsxs("button",{id:E(O.key),className:["ds-tabs__tab",_===O.key&&"ds-tabs__tab--active",O.disabled&&"ds-tabs__tab--disabled"].filter(Boolean).join(" "),type:"button",role:"tab","aria-selected":_===O.key,"aria-controls":j(O.key),tabIndex:_===O.key?0:-1,disabled:O.disabled,onClick:()=>z(O.key,O.disabled),onKeyDown:Z=>I(Z,U),children:[O.icon&&l.jsx("span",{className:"ds-tabs__tab-icon",children:O.icon}),l.jsx("span",{className:"ds-tabs__tab-label",children:O.label}),O.closable&&l.jsx("span",{className:"ds-tabs__tab-close",role:"button",tabIndex:-1,"aria-label":`Close ${String(O.label)}`,onClick:Z=>B(Z,O.key),children:"x"})]},O.key))}),r==="line"&&l.jsx("div",{className:"ds-tabs__ink-bar"})]}),l.jsx("div",{className:"ds-tabs__content",children:A[_]})]})})};Ph.displayName="Tabs";const Xc=k.forwardRef(({page:i,pageCount:e,onChange:n,disabled:s=!1,loading:r=!1,compact:c=!1,label:u="Pagination",className:m="",...h},f)=>{const y=Math.max(1,e),v=Math.min(Math.max(1,i),y),b=k.useMemo(()=>{const F=new Set([1,y,v-1,v,v+1]);return Array.from(F).filter(_=>_>=1&&_<=y).sort((_,E)=>_-E)},[v,y]),S=F=>{s||r||F===v||n?.(Math.min(Math.max(1,F),y))},A=()=>{const F=[];return b.forEach((_,E)=>{const j=b[E-1];j&&_-j>1&&F.push(l.jsx("span",{className:"ds-pagination__gap","aria-hidden":"true",children:"..."},`gap-${_}`)),F.push(l.jsx("button",{className:["ds-pagination__button",v===_&&"ds-pagination__button--current"].filter(Boolean).join(" "),type:"button","aria-current":v===_?"page":void 0,"aria-label":`Go to page ${_}`,disabled:s||r||v===_,onClick:()=>S(_),children:_},_))}),F};return l.jsxs("nav",{ref:f,className:["ds-pagination",c&&"ds-pagination--compact",r&&"ds-pagination--loading",m].filter(Boolean).join(" "),"aria-label":u,"aria-busy":r||void 0,...h,children:[l.jsx("button",{className:"ds-pagination__button ds-pagination__button--icon",type:"button","aria-label":"Previous page",disabled:s||r||v<=1,onClick:()=>S(v-1),children:l.jsx(gd,{size:14,"aria-hidden":"true"})}),!c&&l.jsx("div",{className:"ds-pagination__pages",children:A()}),l.jsxs("span",{className:"ds-pagination__summary",children:[v," / ",y]}),l.jsx("button",{className:"ds-pagination__button ds-pagination__button--icon",type:"button","aria-label":"Next page",disabled:s||r||v>=y,onClick:()=>S(v+1),children:l.jsx(oo,{size:14,"aria-hidden":"true"})})]})});Xc.displayName="Pagination";const dr=k.forwardRef(({tone:i="neutral",size:e="medium",label:n,pulse:s=!1,className:r="",...c},u)=>l.jsx("span",{ref:u,className:["ds-status-dot",`ds-status-dot--${i}`,`ds-status-dot--${e}`,s&&"ds-status-dot--pulse",r].filter(Boolean).join(" "),"aria-label":n,"aria-hidden":n?void 0:!0,role:n?"img":void 0,...c}));dr.displayName="StatusDot";const _t=k.forwardRef(({tone:i="neutral",size:e="medium",leadingDot:n=!0,children:s,className:r="",...c},u)=>l.jsxs("span",{ref:u,className:["ds-status-pill",`ds-status-pill--${i}`,`ds-status-pill--${e}`,r].filter(Boolean).join(" "),...c,children:[n&&l.jsx(dr,{tone:i,size:"small"}),l.jsx("span",{className:"ds-status-pill__label",children:s})]}));_t.displayName="StatusPill";const ed=k.forwardRef(({selected:i=!1,selectedIndicator:e="none",leading:n,title:s,description:r,meta:c,error:u,className:m="",type:h="button",disabled:f,...y},v)=>l.jsxs("button",{ref:v,type:h,className:["ds-action-list-row",!r&&!u&&"ds-action-list-row--single-line","ds-action-list-row--selectable",i&&"ds-action-list-row--selected",u&&"ds-action-list-row--error",m].filter(Boolean).join(" "),"aria-pressed":i,disabled:f,...y,children:[n&&l.jsx("span",{className:"ds-action-list-row__leading",children:n}),l.jsxs("span",{className:"ds-action-list-row__content",children:[l.jsx("span",{className:"ds-action-list-row__title",children:s}),r&&l.jsx("span",{className:"ds-action-list-row__description",children:r}),u&&l.jsx("span",{className:"ds-action-list-row__error",children:u})]}),c&&l.jsx("span",{className:"ds-action-list-row__meta",children:c}),i&&e==="check"&&l.jsx("span",{className:"ds-action-list-row__selected-icon","aria-hidden":"true",children:l.jsx(xs,{size:14})})]}));ed.displayName="SelectableRow";const us=k.forwardRef(({leading:i,title:e,description:n,meta:s,actions:r,disabled:c=!1,error:u,loading:m=!1,className:h="",...f},y)=>l.jsxs("div",{ref:y,className:["ds-action-list-row",!n&&!u&&"ds-action-list-row--single-line",c&&"ds-action-list-row--disabled",u&&"ds-action-list-row--error",m&&"ds-action-list-row--loading",h].filter(Boolean).join(" "),"aria-disabled":c||void 0,"aria-busy":m||void 0,...f,children:[i&&l.jsx("span",{className:"ds-action-list-row__leading",children:i}),l.jsxs("span",{className:"ds-action-list-row__content",children:[l.jsx("span",{className:"ds-action-list-row__title",children:e}),n&&l.jsx("span",{className:"ds-action-list-row__description",children:n}),u&&l.jsx("span",{className:"ds-action-list-row__error",children:u})]}),s&&l.jsx("span",{className:"ds-action-list-row__meta",children:s}),r&&l.jsx("span",{className:"ds-action-list-row__actions",children:r})]}));us.displayName="ActionListRow";function ks(...i){return i.filter(Boolean).join(" ")}function ate(i){return De.Children.toArray(i).some(e=>{if(!De.isValidElement(e))return!1;const n=e.type;return n.displayName==="AppWindowHeader"||n.displayName==="AppWindowBody"||n.displayName==="AppWindowFooter"})}const Fh=k.forwardRef(({title:i,titleExtra:e,className:n,children:s,...r},c)=>l.jsxs("div",{ref:c,className:ks("ds-app-window__header",n),...r,children:[(i||e)&&l.jsxs("div",{className:"ds-app-window__title-group",children:[i&&l.jsx("h2",{className:"ds-app-window__title",children:i}),e&&l.jsx("span",{className:"ds-app-window__title-extra",children:e})]}),s]}));Fh.displayName="AppWindowHeader";const Cd=k.forwardRef(({className:i,...e},n)=>l.jsx("div",{ref:n,className:ks("ds-app-window__body",i),...e}));Cd.displayName="AppWindowBody";const Rh=k.forwardRef(({className:i,...e},n)=>l.jsx("div",{ref:n,className:ks("ds-app-window__footer",i),...e}));Rh.displayName="AppWindowFooter";function rte({open:i,onOpenChange:e,title:n,titleExtra:s,children:r,size:c="wide",contentInset:u=!1,contentClassName:m,className:h,showCloseButton:f=!0,closeOnEscape:y=!0,restoreFocus:v=!0,initialFocusRef:b,labelledBy:S,describedBy:A,ariaLabel:F,closeLabel:_="Close application window",role:E="dialog"}){const j=k.useRef(null),z=k.useRef(null),B=k.useId(),W=S??(n?B:void 0),I=k.useCallback(()=>{e?.(!1)},[e]);if(k.useEffect(()=>{if(!i)return;z.current=document.activeElement instanceof HTMLElement?document.activeElement:null;const oe=window.requestAnimationFrame(()=>{(b?.current??j.current)?.focus()}),O=U=>{if(y&&U.key==="Escape"){const Z=document.querySelector('[aria-modal="true"]');if(Z&&!j.current?.contains(Z))return;U.preventDefault(),I()}};return document.addEventListener("keydown",O),()=>{window.cancelAnimationFrame(oe),document.removeEventListener("keydown",O),v&&z.current?.focus()}},[y,I,b,i,v]),!i)return null;const ee=ate(r);return fr.createPortal(l.jsxs("section",{ref:j,className:ks("ds-app-window",`ds-app-window--${c}`,f&&"ds-app-window--with-close",h),role:E,"aria-label":F,"aria-labelledby":W,"aria-describedby":A,tabIndex:-1,children:[(n||s||f)&&l.jsxs("div",{className:ks("ds-app-window__header-shell",!n&&f&&"ds-app-window__header-shell--close-only"),children:[(n||s)&&l.jsx(Fh,{id:W,title:n,titleExtra:s}),f&&l.jsx(ze,{className:"ds-app-window__close",type:"button",size:"xs",shape:"circle",variant:"ghost","aria-label":_,onClick:I,children:l.jsx(Cs,{"aria-hidden":"true",size:14,strokeWidth:2})})]}),ee?r:l.jsx(Cd,{className:ks(u&&"ds-app-window__body--inset",m),children:r})]}),document.body)}const Ni=k.forwardRef(({children:i,className:e="",role:n="list",...s},r)=>l.jsx("div",{ref:r,className:["ds-data-list",e].filter(Boolean).join(" "),role:n,...s,children:i}));Ni.displayName="DataList";const hn=k.forwardRef(({children:i,selected:e=!1,interactive:n,className:s="",onClick:r,onKeyDown:c,role:u,tabIndex:m,...h},f)=>{const y=n??!!r,v=b=>{c?.(b),!(b.defaultPrevented||!y)&&(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),b.currentTarget.click())};return l.jsx("div",{ref:f,className:["ds-data-list-item",e&&"ds-data-list-item--selected",y&&"ds-data-list-item--interactive",s].filter(Boolean).join(" "),role:u??(y?"button":"listitem"),tabIndex:m??(y?0:void 0),"aria-selected":e||void 0,onClick:r,onKeyDown:v,...h,children:i})});hn.displayName="DataListItem";const Nh=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:["ds-data-list-empty",e].filter(Boolean).join(" "),...n,children:i}));Nh.displayName="DataListEmpty";const Ad=k.forwardRef(({children:i,density:e="normal",className:n="",...s},r)=>l.jsx("div",{ref:r,className:["ds-toolbar",`ds-toolbar--${e}`,n].filter(Boolean).join(" "),...s,children:i}));Ad.displayName="Toolbar";const Di=k.forwardRef(({children:i,align:e="start",className:n="",...s},r)=>l.jsx("div",{ref:r,className:["ds-toolbar-group",`ds-toolbar-group--${e}`,n].filter(Boolean).join(" "),...s,children:i}));Di.displayName="ToolbarGroup";const _d=k.forwardRef(({search:i,filters:e,actions:n,children:s,className:r="",...c},u)=>l.jsxs(Ad,{ref:u,className:["ds-search-toolbar",r].filter(Boolean).join(" "),...c,children:[l.jsxs(Di,{className:"ds-search-toolbar__query",children:[l.jsx(Ri,{...i,className:["ds-search-toolbar__search",i.className].filter(Boolean).join(" ")}),e,s]}),n&&l.jsx(Di,{align:"end",children:n})]}));_d.displayName="SearchToolbar";const lte=k.forwardRef(({label:i,actions:e,children:n,className:s="",...r},c)=>l.jsxs("div",{ref:c,className:["ds-filter-bar",s].filter(Boolean).join(" "),...r,children:[i&&l.jsx("div",{className:"ds-filter-bar__label",children:i}),l.jsx("div",{className:"ds-filter-bar__items",children:n}),e&&l.jsx("div",{className:"ds-filter-bar__actions",children:e})]}));lte.displayName="FilterBar";const Td=k.forwardRef(({primary:i,secondary:e,meta:n,children:s,className:r="",...c},u)=>l.jsxs(Ad,{ref:u,className:["ds-command-bar",r].filter(Boolean).join(" "),...c,children:[l.jsxs(Di,{children:[i,s]}),(e||n)&&l.jsxs(Di,{align:"end",children:[n&&l.jsx("div",{className:"ds-command-bar__meta",children:n}),e]})]}));Td.displayName="CommandBar";const vr=k.forwardRef(({tone:i="neutral",leading:e,trailing:n,children:s,className:r="",...c},u)=>l.jsxs("div",{ref:u,className:["ds-status-bar",`ds-status-bar--${i}`,r].filter(Boolean).join(" "),...c,children:[e&&l.jsx("span",{className:"ds-status-bar__leading",children:e}),l.jsx("div",{className:"ds-status-bar__content",children:s}),n&&l.jsx("span",{className:"ds-status-bar__trailing",children:n})]}));vr.displayName="StatusBar";const br=k.forwardRef(({list:i,detail:e,listLabel:n,detailLabel:s,ratio:r="balanced",className:c="",...u},m)=>l.jsxs("div",{ref:m,className:["ds-list-detail",`ds-list-detail--${r}`,c].filter(Boolean).join(" "),...u,children:[l.jsxs("aside",{className:"ds-list-detail__list","aria-label":typeof n=="string"?n:void 0,children:[n&&l.jsx("div",{className:"ds-list-detail__label",children:n}),i]}),l.jsxs("section",{className:"ds-list-detail__detail","aria-label":typeof s=="string"?s:void 0,children:[s&&l.jsx("div",{className:"ds-list-detail__label",children:s}),e]})]}));br.displayName="ListDetail";const Fn=k.forwardRef(({children:i,variant:e="default",className:n="",...s},r)=>l.jsx("section",{ref:r,className:["ds-panel",`ds-panel--${e}`,n].filter(Boolean).join(" "),...s,children:i}));Fn.displayName="Panel";const Rn=k.forwardRef(({title:i,description:e,actions:n,children:s,className:r="",...c},u)=>l.jsxs("header",{ref:u,className:["ds-panel-header",r].filter(Boolean).join(" "),...c,children:[l.jsxs("div",{className:"ds-panel-header__copy",children:[i&&l.jsx("h2",{className:"ds-panel-header__title",children:i}),e&&l.jsx("p",{className:"ds-panel-header__description",children:e}),s]}),n&&l.jsx("div",{className:"ds-panel-header__actions",children:n})]}));Rn.displayName="PanelHeader";const Nn=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:["ds-panel-body",e].filter(Boolean).join(" "),...n,children:i}));Nn.displayName="PanelBody";const cte=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("footer",{ref:s,className:["ds-panel-footer",e].filter(Boolean).join(" "),...n,children:i}));cte.displayName="PanelFooter";const Pd=k.forwardRef(({title:i,description:e,actions:n,footer:s,children:r,className:c="",...u},m)=>l.jsxs(Fn,{ref:m,className:["ds-inspector-panel",c].filter(Boolean).join(" "),...u,children:[(i||e||n)&&l.jsx(Rn,{title:i,description:e,actions:n}),l.jsx(Nn,{className:"ds-inspector-panel__body",children:r}),s&&l.jsx("div",{className:"ds-inspector-panel__footer",children:s})]}));Pd.displayName="InspectorPanel";const Dh=k.forwardRef(({title:i,description:e,actions:n,emptyState:s,className:r="",...c},u)=>l.jsxs(Fn,{ref:u,className:["ds-empty-state-panel",r].filter(Boolean).join(" "),...c,children:[(i||e||n)&&l.jsx(Rn,{title:i,description:e,actions:n}),l.jsx(Nn,{className:"ds-empty-state-panel__body",children:l.jsx(kd,{...s})})]}));Dh.displayName="EmptyStatePanel";const td=k.forwardRef(({status:i="idle",interactive:e=!0,highlighted:n=!1,onActivate:s,onDelete:r,className:c="",children:u,tabIndex:m,role:h,onClick:f,onKeyDown:y,...v},b)=>{const S=e||!!s;return l.jsx("div",{ref:b,className:["ds-item-card",`ds-item-card--${i}`,S&&"ds-item-card--interactive",n&&"is-highlighted",c].filter(Boolean).join(" "),role:h??(S?"button":void 0),tabIndex:m??(S?0:void 0),"aria-current":n?"true":void 0,onClick:A=>{f?.(A),A.defaultPrevented||s?.()},onKeyDown:A=>{y?.(A),!A.defaultPrevented&&((A.key==="Enter"||A.key===" ")&&s&&(A.preventDefault(),s()),A.key==="Delete"&&r&&(A.preventDefault(),r()))},...v,children:u})});td.displayName="ItemCard";const nd=k.forwardRef(({className:i="",children:e,...n},s)=>l.jsx("div",{ref:s,className:["ds-item-card__top",i].filter(Boolean).join(" "),...n,children:e}));nd.displayName="ItemCardTop";const od=k.forwardRef(({className:i="",children:e,...n},s)=>l.jsx("span",{ref:s,className:["ds-item-card__title",i].filter(Boolean).join(" "),...n,children:e}));od.displayName="ItemCardTitle";const sd=k.forwardRef(({className:i="",children:e,...n},s)=>l.jsx("div",{ref:s,className:["ds-item-card__meta",i].filter(Boolean).join(" "),...n,children:e}));sd.displayName="ItemCardMeta";const id=k.forwardRef(({className:i="",children:e,...n},s)=>l.jsx("span",{ref:s,className:["ds-item-card__meta-item",i].filter(Boolean).join(" "),...n,children:e}));id.displayName="ItemCardMetaItem";const dte=({className:i="",children:e="·",...n})=>l.jsx("span",{className:["ds-item-card__meta-separator",i].filter(Boolean).join(" "),...n,children:e}),Ih=k.forwardRef(({className:i="",composing:e=!1,children:n,...s},r)=>l.jsx("div",{ref:r,className:["ds-item-card__actions",e&&"ds-item-card__actions--composing",i].filter(Boolean).join(" "),...s,children:n}));Ih.displayName="ItemCardActions";const ur=k.forwardRef(({children:i,className:e="",variant:n="default",...s},r)=>l.jsx("nav",{ref:r,className:["ds-navigation-list",n!=="default"&&`ds-navigation-list--${n}`,e].filter(Boolean).join(" "),...s,children:i}));ur.displayName="NavigationList";const gn=k.forwardRef(({active:i=!1,icon:e,meta:n,children:s,className:r="",type:c="button",...u},m)=>l.jsxs("button",{ref:m,type:c,className:["ds-navigation-list-item",i&&"ds-navigation-list-item--active",r].filter(Boolean).join(" "),"aria-current":i?"page":void 0,...u,children:[e&&l.jsx("span",{className:"ds-navigation-list-item__icon",children:e}),l.jsx("span",{className:"ds-navigation-list-item__label",children:s}),n&&l.jsx("span",{className:"ds-navigation-list-item__meta",children:n})]}));gn.displayName="NavigationListItem";const ute=k.forwardRef(({title:i,subtitle:e,eyebrow:n,meta:s,actions:r,className:c="",...u},m)=>l.jsxs("header",{ref:m,className:["ds-detail-header",c].filter(Boolean).join(" "),...u,children:[l.jsxs("div",{className:"ds-detail-header__copy",children:[n&&l.jsx("div",{className:"ds-detail-header__eyebrow",children:n}),l.jsx("h1",{className:"ds-detail-header__title",children:i}),e&&l.jsx("p",{className:"ds-detail-header__subtitle",children:e}),s&&l.jsx("div",{className:"ds-detail-header__meta",children:s})]}),r&&l.jsx("div",{className:"ds-detail-header__actions",children:r})]}));ute.displayName="DetailHeader";const gs=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("section",{ref:s,className:["ds-form-section",e].filter(Boolean).join(" "),...n,children:i}));gs.displayName="FormSection";const en=k.forwardRef(({label:i,description:e,error:n,required:s=!1,controlId:r,orientation:c="vertical",controlWidth:u="compact",children:m,className:h="",...f},y)=>{const v=k.useId(),b=r??v,S=e?`${b}-description`:void 0,A=n?`${b}-error`:void 0,F=[S,A].filter(Boolean).join(" ")||void 0,_=De.isValidElement(m)&&typeof m.type!="string"?De.cloneElement(m,{id:m.props.id??b,"aria-describedby":[m.props["aria-describedby"],F].filter(Boolean).join(" ")||void 0,"aria-invalid":n?!0:m.props["aria-invalid"]}):m;return l.jsxs("div",{ref:y,className:["ds-form-field",`ds-form-field--${c}`,`ds-form-field--control-${u}`,n&&"ds-form-field--error",h].filter(Boolean).join(" "),...f,children:[(i||e)&&l.jsxs("div",{className:"ds-form-field__copy",children:[i&&l.jsxs("label",{className:"ds-form-field__label",htmlFor:b,children:[i,s&&l.jsx("span",{className:"ds-form-field__required",children:"*"})]}),e&&l.jsx("div",{id:S,className:"ds-form-field__description",children:e})]}),l.jsx("div",{className:"ds-form-field__control",children:_}),n&&l.jsx("div",{id:A,className:"ds-form-field__error",children:n})]})});en.displayName="FormField";const Fd=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:["ds-form-actions",e].filter(Boolean).join(" "),...n,children:i}));Fd.displayName="FormActions";const kr=k.forwardRef(({children:i,density:e="normal",className:n="",...s},r)=>l.jsx("section",{ref:r,className:["ds-scene",`ds-scene--${e}`,n].filter(Boolean).join(" "),...s,children:i}));kr.displayName="Scene";const Sr=k.forwardRef(({title:i,description:e,eyebrow:n,actions:s,children:r,className:c="",...u},m)=>l.jsxs("header",{ref:m,className:["ds-scene-header",c].filter(Boolean).join(" "),...u,children:[l.jsxs("div",{className:"ds-scene-header__copy",children:[n&&l.jsx("div",{className:"ds-scene-header__eyebrow",children:n}),l.jsx("h1",{className:"ds-scene-header__title",children:i}),e&&l.jsx("p",{className:"ds-scene-header__description",children:e}),r]}),s&&l.jsx("div",{className:"ds-scene-header__actions",children:s})]}));Sr.displayName="SceneHeader";const xr=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:["ds-scene-body",e].filter(Boolean).join(" "),...n,children:i}));xr.displayName="SceneBody";const pte=k.forwardRef(({children:i,side:e="left",className:n="",...s},r)=>l.jsx("aside",{ref:r,className:["ds-scene-rail",`ds-scene-rail--${e}`,n].filter(Boolean).join(" "),...s,children:i}));pte.displayName="SceneRail";const hs=k.forwardRef(({children:i,width:e="default",className:n="",...s},r)=>l.jsx("div",{ref:r,className:["ds-settings-page",`ds-settings-page--width-${e}`,n].filter(Boolean).join(" "),...s,children:i}));hs.displayName="SettingsPage";const To=k.forwardRef(({title:i,description:e,actions:n,children:s,className:r="",...c},u)=>l.jsxs(Fn,{ref:u,className:["ds-settings-section",r].filter(Boolean).join(" "),...c,children:[(i||e||n)&&l.jsx(Rn,{title:i,description:e,actions:n}),l.jsx(Nn,{children:s})]}));To.displayName="SettingsSection";const Si=k.forwardRef(({children:i,status:e="pending",tone:n="neutral",className:s="",...r},c)=>l.jsx("article",{ref:c,className:["ds-tool-card",`ds-tool-card--${e}`,`ds-tool-card--${n}`,s].filter(Boolean).join(" "),...r,children:i}));Si.displayName="ToolCard";const xi=k.forwardRef(({icon:i,title:e,meta:n,actions:s,className:r="",...c},u)=>l.jsxs("header",{ref:u,className:["ds-tool-card-header",r].filter(Boolean).join(" "),...c,children:[i&&l.jsx("div",{className:"ds-tool-card-header__icon",children:i}),l.jsxs("div",{className:"ds-tool-card-header__copy",children:[l.jsx("div",{className:"ds-tool-card-header__title",children:e}),n&&l.jsx("div",{className:"ds-tool-card-header__meta",children:n})]}),s&&l.jsx("div",{className:"ds-tool-card-header__actions",children:s})]}));xi.displayName="ToolCardHeader";const Ci=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("div",{ref:s,className:["ds-tool-card-body",e].filter(Boolean).join(" "),...n,children:i}));Ci.displayName="ToolCardBody";const pr=k.forwardRef(({children:i,className:e="",...n},s)=>l.jsx("footer",{ref:s,className:["ds-tool-card-footer",e].filter(Boolean).join(" "),...n,children:i}));pr.displayName="ToolCardFooter";const mte=k.forwardRef(({icon:i,title:e,meta:n,actions:s,footer:r,children:c,...u},m)=>l.jsxs(Si,{ref:m,...u,children:[l.jsx(xi,{icon:i,title:e,meta:n,actions:s}),c&&l.jsx(Ci,{children:c}),r&&l.jsx(pr,{children:r})]}));mte.displayName="ToolCardShell";const gte={id:"dark",name:"Dark",type:"dark",description:"Default Sparo OS dark theme — restrained surfaces with ink-red accent",version:"2.2.0",colors:{background:{primary:"#0e0e10",secondary:"#1c1c1f",tertiary:"#0e0e10",quaternary:"#252528",elevated:"#1c1c1f",workbench:"#0e0e10",scene:"#1c1c1f",tooltip:"rgba(28, 28, 31, 0.96)"},text:{primary:"#e8e8e8",secondary:"#b0b0b0",muted:"#858585",disabled:"#555555"},accent:{50:"rgba(183, 55, 47, 0.05)",100:"rgba(183, 55, 47, 0.09)",200:"rgba(183, 55, 47, 0.14)",300:"rgba(183, 55, 47, 0.24)",400:"rgba(183, 55, 47, 0.42)",500:"#B7372F",600:"#9E2F29",700:"rgba(158, 47, 41, 0.88)",800:"rgba(128, 36, 32, 0.94)"},purple:{50:"rgba(139, 92, 246, 0.04)",100:"rgba(139, 92, 246, 0.08)",200:"rgba(139, 92, 246, 0.15)",300:"rgba(139, 92, 246, 0.25)",400:"rgba(139, 92, 246, 0.4)",500:"#8b5cf6",600:"#7c3aed",700:"rgba(124, 58, 237, 0.8)",800:"rgba(124, 58, 237, 0.9)"},semantic:{success:"#34d399",successBg:"rgba(52, 211, 153, 0.1)",successBorder:"rgba(52, 211, 153, 0.3)",warning:"#f59e0b",warningBg:"rgba(245, 158, 11, 0.1)",warningBorder:"rgba(245, 158, 11, 0.3)",error:"#B7372F",errorBg:"rgba(183, 55, 47, 0.12)",errorBorder:"rgba(183, 55, 47, 0.35)",info:"#a1a1aa",infoBg:"rgba(255, 255, 255, 0.08)",infoBorder:"rgba(255, 255, 255, 0.22)",highlight:"#B7372F",highlightBg:"rgba(183, 55, 47, 0.14)"},border:{subtle:"rgba(255, 255, 255, 0.12)",base:"rgba(255, 255, 255, 0.18)",medium:"rgba(255, 255, 255, 0.24)",strong:"rgba(255, 255, 255, 0.32)",prominent:"rgba(255, 255, 255, 0.4)"},element:{subtle:"rgba(255, 255, 255, 0.05)",soft:"rgba(255, 255, 255, 0.07)",base:"rgba(255, 255, 255, 0.095)",medium:"rgba(255, 255, 255, 0.125)",strong:"rgba(255, 255, 255, 0.155)",elevated:"rgba(255, 255, 255, 0.19)"},git:{branch:"#a1a1aa",branchBg:"rgba(255, 255, 255, 0.06)",changes:"rgb(245, 158, 11)",changesBg:"rgba(245, 158, 11, 0.1)",added:"rgb(34, 197, 94)",addedBg:"rgba(34, 197, 94, 0.1)",deleted:"rgb(239, 68, 68)",deletedBg:"rgba(239, 68, 68, 0.1)",staged:"rgb(34, 197, 94)",stagedBg:"rgba(34, 197, 94, 0.1)"},scrollbar:{thumb:"rgba(255, 255, 255, 0.15)",thumbHover:"rgba(255, 255, 255, 0.28)"}},effects:{shadow:{xs:"0 1px 2px rgba(0, 0, 0, 0.9)",sm:"0 2px 4px rgba(0, 0, 0, 0.8)",base:"0 4px 8px rgba(0, 0, 0, 0.7)",lg:"0 8px 16px rgba(0, 0, 0, 0.6)",xl:"0 12px 24px rgba(0, 0, 0, 0.5)","2xl":"0 16px 32px rgba(0, 0, 0, 0.4)"},glow:{blue:"0 12px 32px rgba(183, 55, 47, 0.18), 0 6px 16px rgba(183, 55, 47, 0.1), 0 3px 8px rgba(0, 0, 0, 0.12)",purple:"0 12px 32px rgba(139, 92, 246, 0.22), 0 6px 16px rgba(124, 58, 237, 0.14), 0 3px 8px rgba(0, 0, 0, 0.12)",mixed:"0 12px 32px rgba(255, 255, 255, 0.06), 0 6px 16px rgba(183, 55, 47, 0.1), 0 3px 8px rgba(0, 0, 0, 0.12)"},blur:{subtle:"blur(4px) saturate(1.05)",base:"blur(8px) saturate(1.1)",medium:"blur(12px) saturate(1.2)",strong:"blur(16px) saturate(1.3) brightness(1.1)",intense:"blur(20px) saturate(1.4) brightness(1.15)"},radius:{sm:"6px",base:"8px",lg:"12px",xl:"16px","2xl":"20px",full:"9999px"},spacing:{1:"4px",2:"8px",3:"12px",4:"16px",5:"20px",6:"24px",8:"32px",10:"40px",12:"48px",16:"64px"},opacity:{disabled:.6,hover:.8,focus:.9,overlay:.4}},motion:{duration:{instant:"0.1s",fast:"0.15s",base:"0.3s",slow:"0.6s",lazy:"1s"},easing:{standard:"cubic-bezier(0.4, 0, 0.2, 1)",decelerate:"cubic-bezier(0, 0, 0.2, 1)",accelerate:"cubic-bezier(0.4, 0, 1, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)",smooth:"cubic-bezier(0.4, 0, 0.2, 1)"}},typography:{font:{sans:"'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'SF Pro Display', Roboto, sans-serif",mono:"'FiraCode', 'JetBrains Mono', 'SF Mono', 'Consolas', 'Liberation Mono', monospace"},weight:{normal:400,medium:500,semibold:600,bold:700},size:{xs:"12px",sm:"13px",base:"14px",lg:"15px",xl:"16px","2xl":"18px","3xl":"22px","4xl":"26px","5xl":"32px"},lineHeight:{tight:1.2,base:1.5,relaxed:1.6}},components:{windowControls:{minimize:{dot:"rgba(255, 255, 255, 0.38)",dotShadow:"0 0 4px rgba(0, 0, 0, 0.35)",hoverBg:"rgba(255, 255, 255, 0.1)",hoverColor:"#e4e4e4",hoverBorder:"rgba(255, 255, 255, 0.16)",hoverShadow:"0 2px 8px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.08)"},maximize:{dot:"rgba(255, 255, 255, 0.38)",dotShadow:"0 0 4px rgba(0, 0, 0, 0.35)",hoverBg:"rgba(255, 255, 255, 0.1)",hoverColor:"#e4e4e4",hoverBorder:"rgba(255, 255, 255, 0.16)",hoverShadow:"0 2px 8px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.08)"},close:{dot:"rgba(239, 68, 68, 0.45)",dotShadow:"0 0 4px rgba(239, 68, 68, 0.2)",hoverBg:"rgba(239, 68, 68, 0.12)",hoverColor:"#ef4444",hoverBorder:"rgba(239, 68, 68, 0.2)",hoverShadow:"0 2px 8px rgba(239, 68, 68, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1)"},common:{defaultColor:"rgba(232, 232, 232, 0.9)",defaultDot:"rgba(255, 255, 255, 0.2)",disabledDot:"rgba(255, 255, 255, 0.1)",flowGradient:"linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.04), rgba(183, 55, 47, 0.1), rgba(255, 255, 255, 0.04), transparent)"}},button:{default:{background:"rgba(255, 255, 255, 0.08)",color:"#9a9a9a",border:"transparent",shadow:"none"},hover:{background:"rgba(255, 255, 255, 0.14)",color:"#c8c8c8",border:"transparent",shadow:"none",transform:"none"},active:{background:"rgba(255, 255, 255, 0.10)",color:"#c8c8c8",border:"transparent",shadow:"none",transform:"none"},primary:{default:{background:"#B7372F",color:"#FFFFFF",border:"transparent",shadow:"0 2px 8px rgba(183, 55, 47, 0.22)"},hover:{background:"#9E2F29",color:"#FFFFFF",border:"transparent",shadow:"0 4px 14px rgba(183, 55, 47, 0.28)",transform:"none"},active:{background:"#802420",color:"#FFFFFF",border:"transparent",shadow:"0 2px 8px rgba(183, 55, 47, 0.22)",transform:"none"}},ghost:{default:{background:"transparent",color:"#9a9a9a",border:"transparent",shadow:"none"},hover:{background:"rgba(255, 255, 255, 0.10)",color:"#c8c8c8",border:"transparent",shadow:"none",transform:"none"},active:{background:"rgba(255, 255, 255, 0.07)",color:"#c8c8c8",border:"transparent",shadow:"none",transform:"none"}}}},monaco:{base:"vs-dark",inherit:!0,rules:[],colors:{background:"#121214",foreground:"#e8e8e8",lineHighlight:"#18181a",selection:"rgba(183, 55, 47, 0.28)",cursor:"#B7372F"}}},ad={id:"light",name:"Light",type:"light",description:"Light theme — calm surfaces, ink text, and restrained accent",version:"1.0.0",layout:{sceneViewportBorder:!1},colors:{background:{primary:"#F8FAFC",secondary:"#FFFFFF",tertiary:"#F1F5F9",quaternary:"#E7ECF3",elevated:"#FFFFFF",workbench:"#F3F6FA",scene:"#FFFFFF",tooltip:"rgba(255, 255, 255, 0.98)"},text:{primary:"#0F172A",secondary:"#253044",muted:"#5B6B8C",disabled:"rgba(91, 107, 140, 0.56)"},accent:{50:"rgba(183, 55, 47, 0.045)",100:"rgba(183, 55, 47, 0.08)",200:"rgba(183, 55, 47, 0.13)",300:"rgba(183, 55, 47, 0.22)",400:"rgba(183, 55, 47, 0.42)",500:"#B7372F",600:"#9E2F29",700:"rgba(158, 47, 41, 0.88)",800:"rgba(128, 36, 32, 0.94)"},purple:{50:"rgba(91, 107, 140, 0.045)",100:"rgba(91, 107, 140, 0.08)",200:"rgba(91, 107, 140, 0.13)",300:"rgba(91, 107, 140, 0.2)",400:"rgba(91, 107, 140, 0.34)",500:"#5B6B8C",600:"#253044",700:"rgba(37, 48, 68, 0.82)",800:"rgba(15, 23, 42, 0.9)"},semantic:{success:"#12B76A",successBg:"rgba(18, 183, 106, 0.12)",successBorder:"rgba(18, 183, 106, 0.28)",warning:"#B8842B",warningBg:"rgba(184, 132, 43, 0.1)",warningBorder:"rgba(184, 132, 43, 0.28)",error:"#B7372F",errorBg:"rgba(183, 55, 47, 0.09)",errorBorder:"rgba(183, 55, 47, 0.28)",info:"#5B6B8C",infoBg:"rgba(91, 107, 140, 0.1)",infoBorder:"rgba(91, 107, 140, 0.25)",highlight:"#B7372F",highlightBg:"rgba(183, 55, 47, 0.11)"},border:{subtle:"rgba(15, 23, 42, 0.08)",base:"rgba(15, 23, 42, 0.12)",medium:"rgba(15, 23, 42, 0.18)",strong:"rgba(15, 23, 42, 0.28)",prominent:"rgba(15, 23, 42, 0.38)"},element:{subtle:"rgba(15, 23, 42, 0.035)",soft:"rgba(15, 23, 42, 0.055)",base:"rgba(15, 23, 42, 0.075)",medium:"rgba(15, 23, 42, 0.105)",strong:"rgba(15, 23, 42, 0.145)",elevated:"rgba(255, 255, 255, 0.94)"},git:{branch:"#5B6B8C",branchBg:"rgba(91, 107, 140, 0.1)",changes:"#B8842B",changesBg:"rgba(184, 132, 43, 0.09)",added:"#12B76A",addedBg:"rgba(18, 183, 106, 0.12)",deleted:"#B7372F",deletedBg:"rgba(183, 55, 47, 0.09)",staged:"#12B76A",stagedBg:"rgba(18, 183, 106, 0.12)"},scrollbar:{thumb:"rgba(15, 23, 42, 0.14)",thumbHover:"rgba(15, 23, 42, 0.28)"}},effects:{shadow:{xs:"0 1px 2px rgba(15, 23, 42, 0.04)",sm:"0 2px 5px rgba(15, 23, 42, 0.06)",base:"0 5px 12px rgba(15, 23, 42, 0.08)",lg:"0 10px 22px rgba(15, 23, 42, 0.1)",xl:"0 16px 34px rgba(15, 23, 42, 0.12)","2xl":"0 22px 48px rgba(15, 23, 42, 0.14)"},glow:{blue:"0 10px 28px rgba(15, 23, 42, 0.06), 0 4px 14px rgba(91, 107, 140, 0.06)",purple:"0 10px 28px rgba(91, 107, 140, 0.08), 0 4px 14px rgba(15, 23, 42, 0.05)",mixed:"0 10px 28px rgba(183, 55, 47, 0.08), 0 4px 14px rgba(15, 23, 42, 0.05)"},blur:{subtle:"blur(4px) saturate(1.02)",base:"blur(8px) saturate(1.04)",medium:"blur(12px) saturate(1.06)",strong:"blur(16px) saturate(1.08) brightness(1.02)",intense:"blur(20px) saturate(1.1) brightness(1.03)"},radius:{sm:"4px",base:"6px",lg:"8px",xl:"12px","2xl":"16px",full:"9999px"},spacing:{1:"4px",2:"8px",3:"12px",4:"16px",5:"20px",6:"24px",8:"32px",10:"40px",12:"48px",16:"64px"},opacity:{disabled:.55,hover:.75,focus:.9,overlay:.32}},motion:{duration:{instant:"0.1s",fast:"0.15s",base:"0.28s",slow:"0.55s",lazy:"0.9s"},easing:{standard:"cubic-bezier(0.4, 0, 0.2, 1)",decelerate:"cubic-bezier(0, 0, 0.2, 1)",accelerate:"cubic-bezier(0.4, 0, 1, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)",smooth:"cubic-bezier(0.4, 0, 0.2, 1)"}},typography:{font:{sans:"'Inter', 'Geist', 'Noto Sans SC', 'HarmonyOS Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",mono:"'FiraCode', 'JetBrains Mono', 'SF Mono', 'Consolas', 'Liberation Mono', monospace"},weight:{normal:400,medium:500,semibold:600,bold:700},size:{xs:"12px",sm:"13px",base:"14px",lg:"15px",xl:"16px","2xl":"18px","3xl":"22px","4xl":"26px","5xl":"32px"},lineHeight:{tight:1.2,base:1.5,relaxed:1.6}},components:{windowControls:{minimize:{dot:"rgba(91, 107, 140, 0.5)",dotShadow:"0 0 4px rgba(15, 23, 42, 0.1)",hoverBg:"rgba(15, 23, 42, 0.07)",hoverColor:"#253044",hoverBorder:"rgba(15, 23, 42, 0.14)",hoverShadow:"0 2px 8px rgba(15, 23, 42, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.9)"},maximize:{dot:"rgba(91, 107, 140, 0.5)",dotShadow:"0 0 4px rgba(15, 23, 42, 0.1)",hoverBg:"rgba(15, 23, 42, 0.07)",hoverColor:"#253044",hoverBorder:"rgba(15, 23, 42, 0.14)",hoverShadow:"0 2px 8px rgba(15, 23, 42, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.9)"},close:{dot:"rgba(183, 55, 47, 0.55)",dotShadow:"0 0 4px rgba(183, 55, 47, 0.18)",hoverBg:"rgba(183, 55, 47, 0.12)",hoverColor:"#B7372F",hoverBorder:"rgba(183, 55, 47, 0.24)",hoverShadow:"0 2px 8px rgba(183, 55, 47, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.85)"},common:{defaultColor:"rgba(15, 23, 42, 0.92)",defaultDot:"rgba(91, 107, 140, 0.28)",disabledDot:"rgba(91, 107, 140, 0.16)",flowGradient:"linear-gradient(90deg, transparent, rgba(91, 107, 140, 0.05), rgba(183, 55, 47, 0.08), rgba(91, 107, 140, 0.05), transparent)"}},button:{default:{background:"rgba(15, 23, 42, 0.06)",color:"#253044",border:"transparent",shadow:"none"},hover:{background:"rgba(15, 23, 42, 0.1)",color:"#0F172A",border:"transparent",shadow:"none",transform:"none"},active:{background:"rgba(15, 23, 42, 0.08)",color:"#0F172A",border:"transparent",shadow:"none",transform:"none"},primary:{default:{background:"#B7372F",color:"#FFFFFF",border:"transparent",shadow:"0 2px 8px rgba(183, 55, 47, 0.18)"},hover:{background:"#9E2F29",color:"#FFFFFF",border:"transparent",shadow:"0 4px 14px rgba(183, 55, 47, 0.22)",transform:"none"},active:{background:"#802420",color:"#FFFFFF",border:"transparent",shadow:"0 2px 8px rgba(183, 55, 47, 0.18)",transform:"none"}},ghost:{default:{background:"transparent",color:"#253044",border:"transparent",shadow:"none"},hover:{background:"rgba(15, 23, 42, 0.07)",color:"#0F172A",border:"transparent",shadow:"none",transform:"none"},active:{background:"rgba(15, 23, 42, 0.05)",color:"#0F172A",border:"transparent",shadow:"none",transform:"none"}}}},monaco:{base:"vs",inherit:!0,rules:[{token:"comment",foreground:"6B7890",fontStyle:"italic"},{token:"keyword",foreground:"9E2F29"},{token:"string",foreground:"4F8F67"},{token:"number",foreground:"B8842B"},{token:"type",foreground:"253044"},{token:"class",foreground:"253044"},{token:"function",foreground:"B7372F"},{token:"variable",foreground:"253044"},{token:"constant",foreground:"B8842B"},{token:"operator",foreground:"5B6B8C"},{token:"tag",foreground:"9E2F29"},{token:"attribute.name",foreground:"5B6B8C"},{token:"attribute.value",foreground:"4F8F67"}],colors:{background:"#F8FAFC",foreground:"#0F172A",lineHighlight:"#F1F5F9",selection:"rgba(183, 55, 47, 0.16)",cursor:"#B7372F","editor.selectionBackground":"rgba(183, 55, 47, 0.16)","editor.selectionForeground":"#0F172A","editor.inactiveSelectionBackground":"rgba(15, 23, 42, 0.08)","editor.selectionHighlightBackground":"rgba(183, 55, 47, 0.1)","editor.selectionHighlightBorder":"rgba(183, 55, 47, 0.22)","editorCursor.foreground":"#B7372F","editor.wordHighlightBackground":"rgba(15, 23, 42, 0.06)","editor.wordHighlightStrongBackground":"rgba(183, 55, 47, 0.1)"}}},hte=[ad,gte];function Cr(i){const e=md(i),n=ms(e.lifecycle),s=e.lifecycle==="waiting_confirmation"&&e.confirmation==="required",r=s,c=i.toolName||"Tool",u=typeof e.error=="string"?e.error:void 0;return i.interruptionReason==="app_restart"&&e.lifecycle==="cancelled"?{phase:"interrupted",canConfirm:!1,canReject:!1,isLive:!1,isTerminal:!0,title:c,detail:u}:e.lifecycle==="completed"?{phase:"result",canConfirm:s,canReject:r,isLive:!1,isTerminal:!0,title:c,detail:u}:e.lifecycle==="cancelled"?{phase:"cancelled",canConfirm:s,canReject:r,isLive:!1,isTerminal:!0,title:c,detail:u}:e.lifecycle==="error"?{phase:"error",canConfirm:s,canReject:r,isLive:!1,isTerminal:!0,title:c,detail:u}:e.lifecycle==="waiting_confirmation"?{phase:"confirming",canConfirm:s,canReject:r,isLive:!0,isTerminal:n,title:c,detail:u}:e.lifecycle==="running"?{phase:"running",canConfirm:s,canReject:r,isLive:!0,isTerminal:n,title:c,detail:u}:e.inputPhase==="streaming"?{phase:"receiving_input",canConfirm:s,canReject:r,isLive:!0,isTerminal:n,title:c,detail:u}:e.lifecycle==="ready"?{phase:"ready",canConfirm:s,canReject:r,isLive:!0,isTerminal:n,title:c,detail:u}:{phase:"preparing",canConfirm:s,canReject:r,isLive:!0,isTerminal:n,title:c,detail:u}}const fte=({icon:i,iconClassName:e,expandable:n=!1,affordanceKind:s="expand",isExpanded:r=!1,onAffordanceClick:c,affordanceLabel:u,affordanceControlsId:m,showDivider:h=!0,className:f})=>{const y=s==="open-panel-right";return l.jsxs("div",{className:`tool-card-icon-slot${n?" tool-card-icon-slot--expandable":""}${n&&y?" tool-card-icon-slot--affordance-panel":""}${h?"":" tool-card-icon-slot--no-divider"}${f?` ${f}`:""}`,children:[l.jsxs("div",{className:"tool-card-icon-marks",children:[l.jsx("div",{className:`tool-card-icon tool-identifier-icon tool-card-icon-main ${e||""}`,children:i}),n&&l.jsx("span",{className:`tool-card-icon-expand-hint${!y&&r?" tool-card-icon-expand-hint--open":""}`,"aria-hidden":!0,children:y?l.jsx(oo,{size:16,strokeWidth:2,absoluteStrokeWidth:!0}):l.jsx(no,{size:16,strokeWidth:2,absoluteStrokeWidth:!0})})]}),n&&c&&l.jsx(ze,{className:"tool-card-icon-affordance-hit",onClick:v=>{v.stopPropagation(),c(v)},"aria-label":u??(y?"Open details":"Expand details"),"aria-expanded":y?void 0:r,"aria-controls":y?void 0:m})]})},Mh=({label:i,onClick:e,icon:n,className:s=""})=>l.jsx(yr,{content:i,placement:"top",children:l.jsx(Ce,{type:"button",variant:"ghost",size:"small",className:["tool-right-rail",s].filter(Boolean).join(" "),onClick:r=>{r.stopPropagation(),e(r)},"aria-label":i,title:i,children:l.jsx("div",{className:"tool-right-rail__visual","aria-hidden":!0,children:n??l.jsx(oo,{size:18,strokeWidth:2,absoluteStrokeWidth:!0})})})});function yte(i){switch(i.phase){case"receiving_input":return"receiving";case"confirming":return"pending_confirmation";case"running":return"running";case"ready":return"confirmed";case"result":return"completed";case"cancelled":case"interrupted":return"cancelled";case"error":return"error";default:return"preparing"}}function Rd(i){return i==="preparing"||i==="streaming"||i==="receiving"||i==="running"||i==="analyzing"}function wte(i){return i==="completed"||i==="cancelled"||i==="error"||i==="confirmed"}function vte(i){return i==="error"}function bte(i){return i==="completed"||i==="confirmed"}function kte(i){return i==="error"||i==="cancelled"}const Ste=({status:i,isExpanded:e=!1,onClick:n,className:s="",clickable:r=!1,header:c,headerRail:u,expandedContent:m,expandedContentId:h})=>{const f=b=>{n&&n(b)},y=Rd(i),v=!!m;return l.jsxs("div",{className:["compact-tool-card-wrapper",y?"compact-tool-card-wrapper--loading-shimmer":"",v?"compact-tool-card-wrapper--has-expanded-content":"",e&&v?"compact-tool-card-wrapper--expanded":"",s].filter(Boolean).join(" "),children:[l.jsxs("div",{className:`compact-tool-card status-${i} ${r?"clickable":""} ${e?"expanded":""}`,onClick:f,style:{cursor:r?"pointer":"default"},children:[c,u&&l.jsx(Mh,{...u})]}),e&&m&&l.jsx("div",{id:h,className:"compact-tool-card-expanded",children:m})]})},xte=({statusIcon:i,icon:e,expandable:n=!1,isExpanded:s=!1,onAffordanceClick:r,affordanceLabel:c,affordanceControlsId:u,showDivider:m=!0,action:h,content:f,extra:y,rightIcon:v})=>{const b=`compact-card-status-icon${n?" compact-card-status-icon--expandable":""}`,S=i?l.jsxs(l.Fragment,{children:[l.jsx("span",{className:"compact-card-status-icon__main",children:i}),n&&l.jsx("span",{className:`compact-card-status-icon__expand-hint${s?" compact-card-status-icon__expand-hint--open":""}`,"aria-hidden":!0,children:l.jsx(no,{size:12,strokeWidth:1.75})})]}):null;return l.jsxs(l.Fragment,{children:[e?l.jsx(fte,{icon:e,expandable:n,isExpanded:s,onAffordanceClick:r,affordanceLabel:c,affordanceControlsId:u,showDivider:m}):i?n&&r?l.jsx("button",{type:"button",className:b,onClick:A=>{A.preventDefault(),A.stopPropagation(),r(A)},"aria-label":c??"Expand details","aria-expanded":s,"aria-controls":u,children:S}):l.jsx("span",{className:b,children:S}):null,h&&l.jsx("span",{className:"compact-card-action",children:h}),f&&l.jsx("span",{className:"compact-card-content",children:f}),y&&l.jsx("div",{className:"compact-card-extra",children:y}),v&&l.jsx("span",{className:"compact-card-right-icon",children:v})]})},Nd=({status:i,size:e=12,className:n=""})=>{const s=["tool-status-indicator",`tool-status-indicator--${i}`,n].filter(Boolean).join(" ");return Rd(i)?l.jsx("span",{className:s,children:l.jsx(kh,{size:"small"})}):bte(i)?l.jsx("span",{className:s,children:l.jsx(xs,{size:e,className:"icon-check-done"})}):kte(i)?l.jsx("span",{className:s,children:l.jsx(nh,{size:e})}):l.jsx("span",{className:s,children:l.jsx(eh,{size:e})})},jh=k.createContext({headerExpandAffordance:!1,headerAffordanceKind:"expand",isExpanded:!1});function Cte(){return k.useContext(jh)}const Ate=({status:i,isExpanded:e=!1,onClick:n,className:s="",header:r,headerRail:c,expandedContent:u,expandedContentId:m,errorContent:h,isFailed:f=!1,requiresConfirmation:y=!1,allowExpandedContentWhenFailed:v=!1,headerExpandAffordance:b,headerAffordanceKind:S="expand"})=>{const A=!!(e&&u)&&(!f||v),F=y&&!wte(i),_=b!==void 0?b:!!n&&!f&&!!u,E={headerExpandAffordance:_,headerAffordanceKind:S,isExpanded:e},j=Rd(i);return l.jsxs("div",{className:`base-tool-card-wrapper ${F?"requires-confirmation":""} ${j?"base-tool-card-wrapper--loading-shimmer":""} ${s}`.trim(),children:[l.jsx("div",{className:`base-tool-card status-${i} ${e?"expanded":""} ${_?"base-tool-card--header-expandable":""}`.trim(),onClick:n,children:l.jsx(jh.Provider,{value:E,children:l.jsxs("div",{className:"base-tool-card-header",children:[r,c&&l.jsx(Mh,{...c})]})})}),A&&l.jsx("div",{id:m,className:"base-tool-card-expanded",children:u}),f&&h&&l.jsx("div",{id:A?void 0:m,className:"base-tool-card-error",children:h})]})},_te=({icon:i,iconClassName:e,expandAffordance:n,affordanceKind:s,headerExpanded:r,onAffordanceClick:c,affordanceLabel:u,affordanceControlsId:m,action:h,content:f,extra:y,statusIcon:v})=>{const b=Cte(),S=n!==void 0?n:b.headerExpandAffordance,A=s!==void 0?s:b.headerAffordanceKind,F=r!==void 0?r:b.isExpanded,_=A==="open-panel-right";return l.jsxs(l.Fragment,{children:[i!=null&&i!==!1&&i!==""&&l.jsxs("div",{className:`tool-card-icon-slot${S?" tool-card-icon-slot--expandable":""}${S&&_?" tool-card-icon-slot--affordance-panel":""}`,children:[l.jsxs("div",{className:"tool-card-icon-marks",children:[l.jsx("div",{className:`tool-card-icon tool-identifier-icon tool-card-icon-main ${e||""}`,children:i}),S&&l.jsx("span",{className:`tool-card-icon-expand-hint${!_&&F?" tool-card-icon-expand-hint--open":""}`,"aria-hidden":!0,children:_?l.jsx(oo,{size:16,strokeWidth:2,absoluteStrokeWidth:!0}):l.jsx(no,{size:16,strokeWidth:2,absoluteStrokeWidth:!0})})]}),S&&c&&l.jsx(ze,{type:"button",className:"tool-card-icon-affordance-hit",onClick:E=>{E.stopPropagation(),c(E)},"aria-label":u??(_?"Open details":"Expand details"),"aria-expanded":_?void 0:F,"aria-controls":_?void 0:m,size:"xs",variant:"ghost"})]}),h&&l.jsx("span",{className:"tool-card-action",children:h}),f&&l.jsx("div",{className:"tool-card-content",children:f}),y&&l.jsx("div",{className:"tool-card-extra",children:y}),v&&l.jsx("div",{className:`tool-card-status-icon ${y?"tool-card-status-icon--with-divider":""}`,children:v})]})},Tte=({status:i,statusIcon:e,...n})=>l.jsx(_te,{...n,statusIcon:e??(i?l.jsx(Nd,{status:i}):void 0)}),Pte=({status:i,statusIcon:e,...n})=>l.jsx(xte,{...n,statusIcon:e??(i?l.jsx(Nd,{status:i,size:12}):void 0)}),Fte="flowchat:layout-mutation",Rte="flowchat:layout-collapse-intent";function Eh(i={}){window.dispatchEvent(new CustomEvent(Fte,{detail:{priority:"normal",...i}}))}function Nte(i){window.dispatchEvent(new CustomEvent(Rte,{detail:i}))}function Dte({toolId:i,toolName:e,getCardHeight:n}){const s=k.useRef(null),r=k.useCallback((m,h)=>{const f=n?.()??s.current?.getBoundingClientRect().height??null;Nte({toolId:i??null,toolName:e,cardHeight:f,reason:m,...h})},[n,i,e]),c=k.useCallback((m={})=>{Eh({source:e,toolId:i??null,...m})},[i,e]),u=k.useCallback((m,h,f,y)=>{!h&&m&&r(y?.reason??"manual",y?.detail),h!==m&&(f(h),c({reason:h?"expand":"collapse",priority:"high"})),h&&y?.onExpand?.()},[r,c]);return{cardRootRef:s,invalidateLayout:c,dispatchFlowLayoutMutation:c,dispatchCollapseIntent:r,applyExpandedState:u}}function Lh({toolId:i,toolName:e,initialExpanded:n=!1,autoExpandStatuses:s,autoCollapseStatuses:r,status:c,onExpand:u}){const[m,h]=k.useState(n),f=k.useRef(c),{cardRootRef:y,applyExpandedState:v}=Dte({toolId:i,toolName:e}),b=k.useCallback((A,F="manual")=>{v(m,A,h,{reason:F,onExpand:u})},[v,m,u]),S=k.useCallback((A="manual")=>{b(!m,A)},[m,b]);return k.useEffect(()=>{if(!(!c||f.current===c)){if(f.current=c,s?.includes(c)){b(!0,"auto");return}r?.includes(c)&&b(!1,"auto")}},[r,s,b,c]),{cardRootRef:y,isExpanded:m,setExpanded:b,toggleExpanded:S}}const $h=k.createContext(null);$h.Provider;function Oh(){return k.useContext($h)}function Bh({note:i,subject:e}){return l.jsxs("span",{className:"tool-card-interruption-inline",children:[e&&l.jsx("span",{className:"tool-card-interruption-subject",children:e}),l.jsx("span",{className:"tool-card-interruption-note",title:i,children:i})]})}const Mi=({toolId:i,toolName:e,status:n,action:s,summary:r,extra:c,statusIcon:u,primaryAction:m,expandedContent:h,interruptionNote:f,className:y="",isExpanded:v,expandable:b,onToggle:S,onExpand:A,onClick:F})=>{const{t:_}=on("flow-chat"),E=De.useId(),j=Oh(),z=f??j,W=b??!!h,I=W||!!F,{cardRootRef:ee,isExpanded:oe,toggleExpanded:O}=Lh({toolId:i,toolName:e,status:n,initialExpanded:!1,onExpand:A}),U=v??oe,Z=L=>{if(!(!I||L.target.closest(".default-tool-card-template__action"))){if(W){S?S(!U,L):O("manual");return}F?.()}},re=L=>{W&&(S?S(!U,L):O("manual"))},se=m?l.jsx(yr,{content:m.label,placement:"top",children:l.jsx("button",{type:"button",className:["default-tool-card-template__action",m.visibility==="always"?"default-tool-card-template__action--always-visible":"",m.className??""].filter(Boolean).join(" "),onClick:L=>{L.preventDefault(),L.stopPropagation(),m.onClick(L)},"aria-label":m.label,disabled:m.disabled,children:m.icon})}):null,pe=l.jsxs(l.Fragment,{children:[z?l.jsx(Bh,{note:z,subject:r}):r,se]}),fe=c?l.jsx(l.Fragment,{children:c}):void 0,we=u??l.jsx(Nd,{status:n,size:12});return l.jsx("div",{ref:ee,"data-tool-card-id":i??"",children:l.jsx(Ste,{status:n,isExpanded:U,className:y,clickable:I,onClick:I?Z:void 0,expandedContentId:W?E:void 0,header:l.jsx(Pte,{statusIcon:we,expandable:W,isExpanded:U,onAffordanceClick:W?re:void 0,affordanceLabel:_(U?"toolCards.common.collapse":"toolCards.common.expand"),affordanceControlsId:W?E:void 0,action:s,content:pe,extra:fe}),expandedContent:U?h:void 0})})},Ite=({toolId:i,toolName:e,status:n,icon:s,iconClassName:r,action:c,subject:u,extra:m,headerRail:h,expandedContent:f,errorContent:y,isFailed:v,requiresConfirmation:b=!1,className:S="",onExpand:A,disclosureMode:F="inline",showStatusIcon:_=!0})=>{const{t:E}=on("flow-chat"),j=De.useId(),z=Oh(),B=v??vte(n),I=F==="inline"&&(!!f||!!y),{cardRootRef:ee,isExpanded:oe,toggleExpanded:O}=Lh({toolId:i,toolName:e,status:n,initialExpanded:!1,onExpand:A});return l.jsx("div",{ref:ee,"data-tool-card-id":i??"",children:l.jsx(Ate,{status:n,isExpanded:oe,onClick:I?()=>O("manual"):void 0,className:S,headerExpandAffordance:I,expandedContentId:I?j:void 0,headerRail:h,header:l.jsx(Tte,{icon:s,iconClassName:r,onAffordanceClick:I?()=>O("manual"):void 0,affordanceLabel:E(oe?"toolCards.common.collapse":"toolCards.common.expand"),affordanceControlsId:I?j:void 0,action:c,content:z?l.jsx(Bh,{note:z,subject:u}):u,extra:l.jsxs(l.Fragment,{children:[m,I&&l.jsx("span",{className:"detail-tool-template__chevron","aria-hidden":!0,children:oe?l.jsx(no,{size:12}):l.jsx(oo,{size:12})})]}),status:_?n:void 0}),expandedContent:I&&oe?f:void 0,errorContent:I&&oe?y:void 0,isFailed:B,requiresConfirmation:b})})},Mte=({actions:i,onConfirm:e,onReject:n,onInterrupt:s,confirmLabel:r,rejectLabel:c,interruptLabel:u,confirmDisabled:m,rejectDisabled:h,interruptDisabled:f,confirmIcon:y="check",className:v=""})=>{const b=(S="default")=>{switch(S){case"primary":case"success":return"success";case"danger":return"danger";case"ghost":return"ghost";default:return"secondary"}};return l.jsxs("div",{className:["tool-action-group",v].filter(Boolean).join(" "),onClick:S=>S.stopPropagation(),children:[i?.map(S=>l.jsxs(Ce,{type:"button",size:"small",variant:b(S.variant),className:["tool-action-group__text-button",`tool-action-group__text-button--${S.variant??"default"}`].join(" "),onClick:S.onClick,disabled:S.disabled,"aria-label":S.label,title:S.title??S.label,children:[S.icon,l.jsx("span",{children:S.label})]},S.key)),e&&l.jsx(ze,{className:"tool-action-group__button",variant:"success",size:"xs",onClick:e,disabled:m,tooltip:r,"aria-label":r,children:y==="play"?l.jsx(QZ,{size:12,fill:"currentColor"}):l.jsx(xs,{size:14})}),n&&l.jsx(ze,{className:"tool-action-group__button",variant:"danger",size:"xs",onClick:n,disabled:h,tooltip:c,"aria-label":c,children:l.jsx(Cs,{size:14})}),s&&l.jsx(ze,{className:"tool-action-group__button",variant:"warning",size:"xs",onClick:s,disabled:f,tooltip:u,"aria-label":u,children:l.jsx(sh,{size:12,fill:"currentColor"})})]})},_g=({title:i,message:e,details:n,className:s=""})=>!i&&!e&&!n?null:l.jsxs("div",{className:["tool-error-block",s].filter(Boolean).join(" "),children:[i&&l.jsxs("div",{className:"tool-error-block__title",children:[l.jsx(kX,{size:14}),l.jsx("span",{children:i})]}),e&&l.jsx("div",{className:"tool-error-block__message",children:e}),n&&l.jsx("div",{className:"tool-error-block__details",children:n})]}),jte=4e3,Ete=/(token|password|secret|api[_-]?key|authorization|credential)/i;function rd(i){return Array.isArray(i)?i.map(rd):i&&typeof i=="object"?Object.fromEntries(Object.entries(i).map(([e,n])=>[e,Ete.test(e)?"[redacted]":rd(n)])):i}function Lte(i){if(typeof i=="string")return i;try{return JSON.stringify(rd(i),null,2)}catch{return String(i)}}const Tg=({value:i,maxChars:e=jte,className:n=""})=>{const{t:s}=on("flow-chat"),[r,c]=k.useState(!1),u=k.useMemo(()=>Lte(i),[i]),m=u.length>e,h=k.useMemo(()=>{const y=u;return y.length<=e?y:`${y.slice(0,e)} +...`},[u,e]),f=k.useCallback(async()=>{try{await navigator.clipboard.writeText(u),c(!0),window.setTimeout(()=>c(!1),1200)}catch{c(!1)}},[u]);return l.jsxs("div",{className:["tool-json-preview-shell",n].filter(Boolean).join(" "),children:[l.jsxs("div",{className:"tool-json-preview-shell__toolbar",children:[m&&l.jsx("span",{className:"tool-json-preview-shell__truncated",children:s("toolCards.common.truncated",{defaultValue:"Truncated"})}),l.jsxs(Ce,{variant:"secondary",size:"small",onClick:f,"aria-label":s("toolCards.common.copyJson",{defaultValue:"Copy JSON"}),title:s("toolCards.common.copyJson",{defaultValue:"Copy JSON"}),children:[r?l.jsx(xs,{size:12}):l.jsx(th,{size:12}),l.jsx("span",{children:r?s("toolCards.common.copied",{defaultValue:"Copied"}):s("toolCards.common.copy",{defaultValue:"Copy"})})]})]}),l.jsx("pre",{className:"tool-json-preview",children:h})]})},$te=({rows:i=[],chips:e=[],children:n,emptyText:s,className:r=""})=>{const c=i.filter(m=>!m.hidden&&m.value!==void 0&&m.value!==null&&m.value!=="");return c.length>0||e.length>0||n?l.jsxs("div",{className:["tool-structured-details",r].filter(Boolean).join(" "),children:[e.length>0&&l.jsx("div",{className:"tool-structured-details__chips",children:e.map((m,h)=>l.jsx("span",{className:"tool-structured-details__chip",children:m},h))}),c.length>0&&l.jsx("div",{className:"tool-structured-details__rows",children:c.map((m,h)=>l.jsxs("div",{className:"tool-structured-details__row",children:[l.jsx("span",{className:"tool-structured-details__label",children:m.label}),l.jsx("span",{className:"tool-structured-details__value",children:m.value})]},h))}),n]}):s?l.jsx("div",{className:"tool-structured-details__empty",children:s}):null},Ote={BarChart:QY,Check:xs,Crosshair:cZ,Download:uZ,Eye:hZ,FilePlus:wZ,Film:SZ,FolderOpen:bi,History:DZ,Info:MZ,Layers:$Z,Palette:UZ,Presentation:ZZ,Redo2:eX,RefreshCw:hd,Save:oX,Smartphone:dX,Table:fX,Undo2:xX,X:Cs};function Pg(i){if(i==null||i==="")return{};try{return typeof i=="string"?JSON.parse(i):i}catch{return i}}function We(i,e){if(e?.length)return e.reduce((n,s)=>{if(n&&typeof n=="object"&&s in n)return n[s]},i)}function tn(i){if(!(i==null||i==="")){if(typeof i=="string")return i;if(typeof i=="number"||typeof i=="boolean")return String(i);try{return JSON.stringify(i)}catch{return String(i)}}}function Fg(i){return i==null||i===""?!1:Array.isArray(i)?i.length>0:typeof i=="object"?Object.keys(i).length>0:!0}function eo(i,e){if(i)return i.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g,(n,s)=>{const r=We(e,s.split("."));return tn(r)??""})}function Bte(i,e,n){return We(n,i.path)??We(n,i.resultPath)??We(e,i.inputPath)}function Wte(i,e){if(e)return e;const n=tn(We(i,["bridge","status"]));if(!(n!=="failed"&&n!=="cancelled"))return tn(We(i,["bridge","output","error","message"]))??tn(We(i,["bridge","output","error"]))??tn(We(i,["bridge","output","message"]))??tn(We(i,["bridge","output","reason"]))??tn(We(i,["bridge","stderr"]))}function Rg(i){return We(i,["bridge","output"])??We(i,["result"])??We(i,["output"])??i}function zte(i,e,n,s){const r=tn(We(n,["status"]));return r==="failed"?eo(i.summary?.failed,n)??s.failed:r==="cancelled"?eo(i.summary?.cancelled,n)??s.cancelled:e==="confirming"?eo(i.summary?.confirming,n)??s.confirming:e==="result"?tn(We(n,["output","summary"]))??eo(i.summary?.completed,n)??s.completed:e==="running"||e==="receiving_input"?eo(i.summary?.running,n)??s.running:e==="cancelled"?eo(i.summary?.cancelled,n)??s.cancelled:e==="error"||e==="interrupted"?eo(i.summary?.failed,n)??s.failed:eo(i.summary?.preparing,n)??s.preparing}function Ute(i){const e=i&&Ote[i]||ah;return l.jsx(e,{size:16,strokeWidth:1.8})}function Hte(i){if(!i)return;const e=i.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"");return e?`app-defined-tool-card--${e}`:void 0}function qte(i){const e=i?.trim();if(e)return e==="var(--ds-tool-family-agent-component-fg)"?"var(--ds-tool-family-agent-fg)":/^var\(--ds-[a-z0-9-]+\)$/i.test(e)?e:void 0}function Vte(i){const e=i?.trim().replace(/_/g,"-");if(!e)return[];const n=e.split("-")[0].toLowerCase(),s=n==="zh"?"zh-CN":n==="en"?"en-US":void 0;return Array.from(new Set([e,s,n].filter(Boolean)))}function Gte(i,e){const n=Object.entries(i.locales??{}),s=Vte(e).map(r=>n.find(([c])=>c.toLowerCase()===r.toLowerCase())?.[1]).find(Boolean);return s?{...i,...s,summary:s.summary?{...i.summary,...s.summary}:i.summary,fields:i.fields?.map((r,c)=>({...r,label:s.fields?.[c]?.label?.trim()||r.label})),locales:i.locales}:i}const Kte=De.memo(({toolItem:i,config:e,onConfirm:n,onReject:s})=>{const{t:r,i18n:c}=on("flow-chat"),{toolCall:u,toolResult:m,status:h}=i,f=k.useMemo(()=>Gte(e.extensionCard??{},c.language),[e.extensionCard,c.language]),y=k.useMemo(()=>Cr(i),[i]),v=k.useMemo(()=>Pg(u?.input),[u?.input]),b=k.useMemo(()=>Pg(m?.result),[m?.result]),S=Rg(b),A=k.useMemo(()=>({input:v,result:b,output:Rg(b),action:We(b,["action"])??We(b,["bridge","action"])??We(v,["action"]),status:We(b,["status"])??We(b,["bridge","status"]),runId:We(b,["run_id"])??We(b,["bridge","run_id"])??We(v,["runId"])}),[v,b]),F=tn(We(A,["status"])),_=y.phase==="confirming",E=y.phase==="cancelled"||F==="cancelled"||h==="cancelled",j=!E&&(y.phase==="error"||F==="failed"||m?.success===!1||h==="error"),z=Wte(b,m?.error)??(j?r("toolCards.default.failed"):void 0),B=E?"cancelled":j?"error":y.phase,W=E?"cancelled":j?"error":h,I=(f.fields??[]).map(X=>({field:X,value:Bte(X,v,b)})).filter(({value:X})=>Fg(X)),ee=I.filter(({field:X})=>X.format!=="json"),oe=I.filter(({field:X})=>X.format==="json"),O=I.length===0&&Fg(S)?S:void 0,U=I.length>0||O!==void 0||!!z,Z=zte(f,B,A,{preparing:r("toolCards.default.preparing"),running:r("toolCards.default.executing"),confirming:r("toolCards.default.waitingConfirm"),completed:r("toolCards.default.completed"),failed:r("toolCards.default.failed"),cancelled:r("toolCards.default.cancelled")}),re=_&&(n||s)?l.jsx(Mte,{className:"app-defined-tool-card__actions",onConfirm:n?()=>n(u?.input):void 0,onReject:s?()=>s():void 0,confirmLabel:r("toolCards.mcp.confirmExecute"),rejectLabel:r("toolCards.mcp.cancel"),confirmDisabled:!y.canConfirm,rejectDisabled:!y.canReject}):null,se=U?l.jsxs($te,{rows:ee.map(({field:X,value:ie})=>({label:`${X.label}:`,value:tn(ie)})),className:"app-defined-tool-card__details",children:[oe.map(({field:X,value:ie})=>l.jsxs("div",{className:"app-defined-tool-card__json-field",children:[l.jsx("div",{className:"app-defined-tool-card__json-label",children:X.label}),l.jsx(Tg,{value:ie,maxChars:3200})]},`${X.label}-${X.resultPath?.join(".")??X.inputPath?.join(".")??""}`)),O!==void 0&&l.jsx(Tg,{value:O,maxChars:3200}),z&&l.jsx(_g,{message:z})]}):void 0,pe=z?l.jsx(_g,{message:z}):void 0,fe=F&&!["completed","failed","cancelled"].includes(F)?F:void 0,we=fe||re?l.jsxs(l.Fragment,{children:[fe&&l.jsx("span",{className:"app-defined-tool-card__bridge-status",children:fe}),re]}):void 0,L=["app-defined-tool-card",Hte(f.family),_?"requires-confirmation":""].filter(Boolean).join(" "),$=qte(e.primaryColor),te=$?{"--app-defined-tool-accent":$}:void 0,G=f.title??f.displayName??e.displayName,C=Ute(f.icon??e.icon),N=f.family!=="excel-live"&&(f.template==="detail"||e.displayMode==="detailed");return l.jsx("div",{className:L,style:te,children:N?l.jsx(Ite,{toolId:i.id??u?.id,toolName:i.toolName,status:W,icon:C,action:G,subject:Z,extra:we,expandedContent:se,errorContent:pe,isFailed:W==="error",requiresConfirmation:_,className:"app-defined-tool-card__template"}):l.jsx(Mi,{toolId:i.id??u?.id,toolName:i.toolName,status:W,action:`${G}:`,summary:Z,extra:we,expandedContent:se,className:"app-defined-tool-card__template"})})}),Ng=50,Qte=({toolItem:i,onExpand:e})=>{const{t:n}=on("flow-chat"),{toolCall:s,toolResult:r,status:c}=i,[u,m]=k.useState(!1),h=k.useMemo(()=>Cr(i),[i]),f=h.phase==="result",y=i.id??s?.id,v=()=>{const I=s?.input?.path;if(!I){const ee=s?.input?._early_detection===!0,oe=s?.input?._partial_params===!0;return n("toolCards.ls.parsingPath")}return I},b=k.useMemo(()=>{if(!r?.result)return[];const I=r.result;return I.entries&&Array.isArray(I.entries)?I.entries:[]},[r]);k.useEffect(()=>{m(!1)},[b]);const S=k.useMemo(()=>{if(b.length===0)return{files:0,directories:0,total:0};let I=0,ee=0;return b.forEach(oe=>{oe.is_dir?ee++:I++}),{files:I,directories:ee,total:b.length}},[b]),A=v(),F=f&&b.length>0,_=r?.result!==void 0&&r?.result!==null,E=u?b:b.slice(0,Ng),j=Math.max(0,b.length-Ng),z=S.directories>0?n("toolCards.ls.filesAndDirs",{files:S.files,directories:S.directories}):n("toolCards.ls.filesCount",{count:S.files});k.useEffect(()=>{if(!F)return;const I=window.requestAnimationFrame(()=>{Eh({source:i.toolName,toolId:y??null,reason:u?"ls-show-all":"ls-results-layout",priority:"high"})});return()=>window.cancelAnimationFrame(I)},[F,u,y,i.toolName,E.length]);const B=()=>f?`${n("toolCards.ls.listDirectory")}: ${A}${_?` (${z})`:""}`:h.phase==="running"||h.phase==="receiving_input"?`${n("toolCards.ls.listingDirectory")} ${A}...`:h.phase==="preparing"||h.phase==="ready"?`${n("toolCards.ls.preparingList")} ${A}`:A,W=()=>l.jsx("div",{className:"ls-display-card__table-wrap",children:l.jsx("table",{className:"ls-display-card__table",children:l.jsxs("tbody",{children:[E.map((I,ee)=>{const oe=I.name||I.path,O=I.path||I.name;return l.jsx("tr",{children:l.jsx("td",{children:l.jsxs("span",{className:"ls-display-card__entry-result",children:[I.is_dir?l.jsx(AZ,{size:13,className:"ls-display-card__entry-icon"}):l.jsx(bZ,{size:13,className:"ls-display-card__entry-icon"}),l.jsx("span",{className:"ls-display-card__entry-name",title:O,children:oe})]})})},`${O}-${ee}`)}),!u&&j>0&&l.jsx("tr",{children:l.jsx("td",{className:"ls-display-card__more",children:l.jsxs(Ce,{type:"button",size:"small",variant:"ghost",onClick:I=>{I.preventDefault(),I.stopPropagation(),m(!0)},children:[l.jsx(no,{size:13}),n("toolCards.ls.moreEntries",{count:j})]})})})]})})});return h.phase==="error"?null:l.jsx(Mi,{toolId:y,toolName:i.toolName,status:c,className:"ls-display-card",summary:B(),expandedContent:F?W():void 0,onExpand:e})};function yn(i){return i!==null&&typeof i=="object"&&!Array.isArray(i)?i:null}function mr(i){if(typeof i!="string")return i;try{return JSON.parse(i)}catch{return null}}function Jte(i){const e=mr(i),n=yn(e);return n&&Object.prototype.hasOwnProperty.call(n,"result")?mr(n.result):e}function Yte(i){const e=yn(mr(i))?.action;return e==="query"||e==="get"?e:"unknown"}function Mc(i){return typeof i!="string"?"":(i.split(".").filter(Boolean).at(-1)??i).replace(/[_-]+/g," ").replace(/\s+/g," ").trim()}function Zte(i){const e=yn(Jte(i));return e?(Array.isArray(e.settings)?e.settings:e.descriptor?[{descriptor:e.descriptor,current:e.current}]:[]).flatMap((s,r)=>{const c=yn(s),u=yn(c?.descriptor);return!c||!u?[]:[{id:typeof u.id=="string"?u.id:`setting-${r}`,descriptor:u,current:c.current}]}):[]}function Xte(i,e){if(typeof e!="string"&&typeof e!="number"||!Array.isArray(i.resolvedOptions))return null;for(const n of i.resolvedOptions){const s=yn(n);if(s?.value===String(e)&&typeof s.label=="string")return s.label}return null}const Wh=({toolItem:i})=>{const{t:e,i18n:n}=on("flow-chat"),s=k.useMemo(()=>Cr(i),[i]),r=k.useMemo(()=>Yte(i.toolCall?.input),[i.toolCall?.input]),c=k.useMemo(()=>Zte(i.toolResult?.result),[i.toolResult?.result]),u=yn(mr(i.toolCall?.input)),m=_=>{const E=Mc(_.descriptor.id)||e("toolCards.settingsCatalog.results.unnamed"),j=yn(_.descriptor.presentation);return typeof j?.titleKey=="string"?String(n.t(j.titleKey,{defaultValue:E})):E},h=_=>{const E=yn(_.descriptor.presentation),j=typeof E?.tabId=="string"?E.tabId:"";return j?String(n.t(`settings/config-center:tabs.${j}`,{defaultValue:Mc(j)})):e("toolCards.settingsCatalog.results.otherLocation")},f=_=>{const E=yn(_.current);if(!E)return e("toolCards.settingsCatalog.results.notSet");if(E.kind==="secret")return E.configured===!0?e("toolCards.settingsCatalog.results.configured"):e("toolCards.settingsCatalog.results.notConfigured");if(E.kind!=="value")return e("toolCards.settingsCatalog.results.defaultValue");const j=E.value,z=Xte(_.descriptor,j);return z||(j==null||j===""?e("toolCards.settingsCatalog.results.notSet"):typeof j=="boolean"?e(j?"toolCards.settingsCatalog.results.enabled":"toolCards.settingsCatalog.results.disabled"):Array.isArray(j)?e("toolCards.settingsCatalog.results.itemCount",{count:j.length}):typeof j=="object"?e("toolCards.settingsCatalog.results.itemCount",{count:Object.keys(j).length}):String(j))},y=Mc(u?.settingId),v=c[0]?m(c[0]):y,b=s.phase==="error"?e("toolCards.settingsCatalog.status.failed"):s.phase==="cancelled"||s.phase==="interrupted"?e("toolCards.settingsCatalog.status.cancelled"):s.phase!=="result"?e(r==="get"?"toolCards.settingsCatalog.status.reading":"toolCards.settingsCatalog.status.searching"):r==="get"?v?e("toolCards.settingsCatalog.status.readOneNamed",{name:v}):e("toolCards.settingsCatalog.status.readOne"):e("toolCards.settingsCatalog.status.matched",{count:c.length}),S=e(`toolCards.settingsCatalog.actions.${r}`),A=e("toolCards.settingsCatalog.summaryLine",{action:S,summary:b}),F=s.phase==="result"&&c.length>0?l.jsx("ul",{className:"settings-catalog-card__results","aria-label":e("toolCards.settingsCatalog.results.listLabel"),children:c.map(_=>l.jsxs("li",{className:"settings-catalog-card__result",children:[l.jsxs("span",{className:"settings-catalog-card__result-copy",children:[l.jsx("strong",{className:"settings-catalog-card__result-title",children:m(_)}),l.jsx("span",{className:"settings-catalog-card__result-location",children:h(_)})]}),l.jsxs("span",{className:"settings-catalog-card__result-value",children:[l.jsx("span",{className:"settings-catalog-card__result-value-label",children:e("toolCards.settingsCatalog.results.currentValue")}),l.jsx("strong",{children:f(_)})]})]},_.id))}):void 0;return l.jsx(Mi,{toolId:i.id,toolName:i.toolName,status:yte(s),summary:A,expandedContent:F})};Wh.displayName="SettingsCatalogCard";const ene=Array.from({length:10},(i,e)=>({name:`setting-${e+1}.json`,path:`D:/workspace/settings/setting-${e+1}.json`,is_dir:!1,modified_time:"2026-07-16T10:24:00Z"})),tne={id:"qa-ls",type:"tool",toolName:"LS",status:"completed",timestamp:Date.now(),runtime:{lifecycle:"completed",inputPhase:"parsed",confirmation:"none",input:{path:"D:/workspace/settings"}},toolCall:{id:"qa-ls",input:{path:"D:/workspace/settings"}},toolResult:{success:!0,result:{entries:ene}}},nne=[["core.font.ui_size.level","settings/appearance:appearance.fontSize.uiSizeLabel","appearance","medium"],["core.font.ui_size.custom_px","settings/appearance:appearance.fontSize.customPxLabel","appearance",null],["core.font.flow_chat.mode","settings/appearance:appearance.fontSize.flowChatLabel","appearance","sync"],["core.font.flow_chat.base_px","settings/appearance:appearance.fontSize.flowChatLabel","appearance",15],["core.font.markdown_editor.mode","settings/appearance:appearance.fontSize.markdownEditorLabel","appearance","custom"],["core.font.markdown_editor.base_px","settings/appearance:appearance.fontSize.markdownEditorLabel","appearance",16],["core.editor.font_size","settings/editor:appearance.fontSize","editor",14],["core.editor.font_family","settings/editor:appearance.font","editor","JetBrains Mono"],["core.editor.line_height","settings/editor:appearance.lineHeight","editor",1.6],["core.editor.minimap.enabled","settings/editor:display.minimap","editor",!0]].map(([i,e,n,s])=>({descriptor:{id:i,presentation:{titleKey:e,tabId:n}},current:{kind:"value",value:s}})),one={id:"qa-catalog",type:"tool",toolName:"LS",status:"completed",timestamp:Date.now(),runtime:{lifecycle:"completed",inputPhase:"parsed",confirmation:"none",input:{action:"query",query:"字体"}},toolCall:{id:"qa-catalog",input:{action:"query",query:"字体"}},toolResult:{success:!0,result:{revision:7,catalogVersion:"qa-private-version",settings:nne}}},sne={toolName:"agentcomponent__excel-live-agent__read_table",displayName:"读取表格",icon:"Table",requiresConfirmation:!1,resultDisplayType:"detailed",displayMode:"compact",extensionCard:{kind:"appDefined",family:"excel-live",template:"compact",title:"读取表格",icon:"Table",summary:{preparing:"正在准备读取…",running:"正在读取工作表数据…",completed:"已读取 12 行数据",failed:"读取表格失败"},fields:[]}},ine={id:"qa-table",type:"tool",toolName:"agentcomponent__excel-live-agent__read_table",status:"completed",timestamp:Date.now(),runtime:{lifecycle:"completed",inputPhase:"parsed",confirmation:"none",input:{sheet:"Sheet1",range:"A1:D12"}},toolCall:{id:"qa-table",input:{sheet:"Sheet1",range:"A1:D12"}},toolResult:{success:!0,result:{bridge:{status:"completed",output:{summary:"已读取 12 行数据",rows:12,range:"A1:D12"}}}}},Dg={toolName:"LS",displayName:"LS",icon:"",requiresConfirmation:!1,resultDisplayType:"summary"},ane=()=>{const i=new URLSearchParams(window.location.search).get("sample");return k.useEffect(()=>{const e=document.documentElement,n=ad;vs(e,uh(n)),vs(e,ph(n)),vs(e,dh(n)),e.dataset.theme=ad.id,e.dataset.themeType="light"},[]),l.jsx(zg,{i18n:ar.getI18nInstance(),children:l.jsxs("main",{className:"compact-tool-card-quick-preview",children:[(!i||i==="ls")&&l.jsx("div",{className:"compact-tool-card-quick-preview__sample","data-qa":"ls",children:l.jsx(Qte,{config:Dg,toolItem:tne})}),(!i||i==="settings")&&l.jsx("div",{className:"compact-tool-card-quick-preview__sample","data-qa":"settings",children:l.jsx(Wh,{config:Dg,toolItem:one})}),(!i||i==="table")&&l.jsx("div",{className:"compact-tool-card-quick-preview__sample","data-qa":"table",children:l.jsx(Kte,{config:sne,toolItem:ine})})]})})},rne=[{label:"Codex",value:"codex",description:"Default coding agent"},{label:"Explorer",value:"explorer",description:"Codebase exploration"},{label:"Worker",value:"worker",description:"Implementation task"}];function lne(){const[i,e]=k.useState(null);return l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsxs("div",{style:{display:"flex",gap:"var(--ds-space-2)",flexWrap:"wrap"},children:[l.jsx(Ce,{size:"small",onClick:()=>e("default"),children:"Open dialog"}),l.jsx(Ce,{size:"small",variant:"secondary",onClick:()=>e("without-dividers"),children:"Open undivided dialog"})]}),l.jsxs(hh,{open:i!==null,onOpenChange:n=>{n||e(null)},title:"Confirm workspace action",size:"small",showDividers:i!=="without-dividers",children:[l.jsx(yd,{children:"This dialog traps focus, supports Escape, restores focus, and exposes a labelled dialog surface."}),l.jsxs(gh,{children:[l.jsx(Ce,{variant:"secondary",size:"small",onClick:()=>e(null),children:"Cancel"}),l.jsx(Ce,{variant:"primary",size:"small",onClick:()=>e(null),children:"Confirm"})]})]})]})}function cne(){const[i,e]=k.useState(!0);return i?l.jsx("div",{style:{width:"min(320px, 100%)"},children:l.jsx(Ch,{padding:"compact",onDismiss:()=>e(!1),dismissLabel:"Dismiss notification",dismissTooltip:"Dismiss notification",children:l.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"var(--ds-space-2)"},children:[l.jsx(Jc,{size:18,style:{flexShrink:0,color:"var(--ds-color-accent-500)"}}),l.jsxs("div",{style:{minWidth:0},children:[l.jsx("strong",{style:{display:"block",color:"var(--ds-color-text-primary)",fontSize:"var(--ds-font-size-sm)"},children:"Workspace summary is ready"}),l.jsx("span",{style:{display:"block",marginTop:3,color:"var(--ds-color-text-secondary)",fontSize:"var(--ds-font-size-xs)",lineHeight:1.45},children:"通知内容可以自然换行;浮卡的圆角、阴影与关闭按钮都由设计系统负责。"})]})]})})}):l.jsx(Ce,{size:"small",variant:"secondary",onClick:()=>e(!0),children:"Restore card"})}function dne(){const[i,e]=k.useState(!1),n=k.useRef(null);return l.jsxs("div",{style:{minHeight:180},children:[l.jsxs(Ce,{ref:n,size:"small",variant:"secondary","aria-haspopup":"menu","aria-expanded":i,onClick:()=>e(s=>!s),children:["Session options ",l.jsx(no,{size:14})]}),l.jsx(Kee,{open:i,anchorRef:n,align:"left",minWidth:200,onClose:()=>e(!1),items:[{type:"item",id:"rename",label:"Rename session",onClick:()=>{}},{type:"item",id:"duplicate",label:"Duplicate session",onClick:()=>{}},{type:"separator",id:"separator"},{type:"item",id:"disabled",label:"Unavailable action",disabled:!0}]})]})}function une(){const[i,e]=k.useState(!1),[n,s]=k.useState({startDate:new Date(2026,6,1),endDate:new Date(2026,6,8)}),r=`${n.startDate.toLocaleDateString("en-US")} - ${n.endDate.toLocaleDateString("en-US")}`;return l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsx(Ce,{size:"small",variant:"secondary",onClick:()=>e(!0),children:"Open date range"}),l.jsx("small",{children:r}),l.jsx(fh,{open:i,onOpenChange:e,onApply:s,title:"Review date range",initialRange:n,maxDate:new Date(2026,6,8),locale:"en-US",labels:{hint:"Click a start date, then an end date.",summary:(c,u)=>`${c} - ${u}`,pickEndHint:c=>`Now choose an end date (start: ${c}).`,pickEndError:"Select an end date to complete the range.",previousMonth:"Previous month",nextMonth:"Next month",cancel:"Cancel",apply:"Apply"}})]})}function pne(){const[i,e]=k.useState(42);return l.jsx(xd,{id:"preview-number-field",label:"Execution limit",value:i,min:0,max:100,unit:"%",hint:"Arrow keys adjust the value.",onChange:e})}function mne(){const[i,e]=k.useState(null);return l.jsx(xd,{id:"preview-nullable-number-field",label:"空闲超时",value:i,nullable:!0,min:0,unit:"秒",placeholder:"未设置",hint:"留空表示使用系统默认值。",increaseAriaLabel:"增加空闲超时",decreaseAriaLabel:"减少空闲超时",onChange:e})}function gne(){const[i,e]=k.useState("custom");return l.jsx(_h,{ariaLabel:"Model assignment",value:i,onChange:e,options:[{value:"flagship",label:"旗舰",detail:"gpt-5-codex"},{value:"fast",label:"快速",detail:"gpt-5-mini"},{value:"custom",label:"其他",detail:"deepseek-v4-flash",trailing:l.jsx(no,{size:12})}]})}function hne(){const[i,e]=k.useState("manual");return l.jsx(Sd,{appearance:"slider",ariaLabel:"Settings mode",value:i,onChange:e,options:[{value:"manual",label:"Manual"},{value:"ai",label:"AI"}]})}const fne=[{id:"ds-primitives",name:"Primitives",description:"Stable low-level controls. Use them inside patterns, not as feature-local UI frameworks.",layoutType:"grid-3",tier:"primitive",aiRole:"Primitives are leaf controls. Reach for them after a recipe and pattern already define the page structure.",decisionRules:["Use Button for text commands and IconButton for icon-only commands with accessible labels.","Use Select for option sets, Switch or Checkbox only for binary settings.","Use Badge and EmptyState for state communication; never rely on color alone."],examples:[{id:"ds-sparo-logo-mark",name:"Sparo logo mark",description:"Vector brand mark with configurable size, stroke width, and currentColor inheritance.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(ki,{size:18,"aria-label":"Sparo OS",role:"img"}),l.jsx(ki,{size:24,"aria-label":"Sparo OS",role:"img"}),l.jsx(ki,{size:32,strokeWidth:5.5,"aria-label":"Sparo OS brand color",role:"img",style:{color:"var(--ds-color-accent-500)"}})]}),ai:{useWhen:["A first-party Sparo OS surface needs the official brand mark"],composeWith:["IconButton","Toolbar","DialogHeader","EmptyState"],avoid:["Generic actions or objects that already have a Lucide icon","Raster copies of the brand mark"],states:["default","theme","narrow"]}},{id:"ds-sparo-system-icons",name:"Sparo semantic icon families",description:"First-party system, work-type, navigation, search/filter, file-transfer, and edit/manage icons sourced from the standalone @sparo/icons package.",category:"ds-primitives",render:()=>l.jsx("div",{className:"recipe-preview-inline",style:{flexWrap:"wrap"},children:lh.map(i=>l.jsx(ch,{name:i,size:28,strokeWidth:1.8,absoluteStrokeWidth:!0,title:i},i))}),ai:{useWhen:["A first-party Sparo OS destination, work type, navigation surface, or large-format semantic action needs a recognizable icon"],composeWith:["Button","IconButton","DataList","Navigation"],avoid:["Generic actions that already have a Lucide icon","Feature-local copies of the SVG geometry"],states:["default","theme","narrow"]}},{id:"ds-button-semantics",name:"Button command semantics",description:"Variant, size, loading, disabled, and icon-only command rules.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(Ce,{variant:"primary",children:"Save"}),l.jsx(Ce,{variant:"secondary",children:"Cancel"}),l.jsx(Ce,{variant:"danger",children:"Delete"}),l.jsx(Ce,{variant:"ai",children:"Ask AI"})]}),l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(Ce,{size:"small",children:"Small"}),l.jsx(Ce,{size:"medium",children:"Medium"}),l.jsx(Ce,{size:"large",children:"Large"}),l.jsx(Ce,{isLoading:!0,children:"Loading"}),l.jsx(Ce,{disabled:!0,children:"Disabled"})]}),l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(ze,{"aria-label":"Copy result",tooltip:"Copy result",size:"small",children:l.jsx(th,{size:14})}),l.jsx(ze,{"aria-label":"Refresh",tooltip:"Refresh",size:"small",children:l.jsx(hd,{size:14})}),l.jsx(ze,{"aria-label":"Open full reading",tooltip:"Open full reading",size:"small",shape:"circle",variant:"primary",children:l.jsx(Jc,{size:14})}),l.jsx(ze,{"aria-label":"Advance intent",tooltip:"Advance intent",size:"small",shape:"circle",variant:"brand",children:l.jsx(Jc,{size:14})}),l.jsx(ze,{"aria-label":"Create task",tooltip:"Create task",size:"small",shape:"circle",variant:"accent",children:l.jsx(oh,{size:14})}),l.jsx(ze,{"aria-label":"Delete",tooltip:"Delete",size:"small",variant:"danger",children:l.jsx(vX,{size:14})})]})]}),ai:{useWhen:["The action is a command, confirmation, or toolbar affordance"],composeWith:["Toolbar","CommandBar","PanelHeader","ToolCardFooter"],avoid:["Custom button classes in feature SCSS","Text inside icon-only controls","Ad hoc product accent colors outside IconButton variants"],states:["default","disabled","loading","focus","long text","theme","i18n"]}},{id:"ds-floating-card",name:"Floating card",description:"Large-radius non-modal surface with a pronounced two-stage elevation shadow and a standard circular dismiss command.",category:"ds-primitives",render:()=>l.jsx(cne,{}),ai:{useWhen:["A transient notification, anchored helper, or compact popup needs a lightweight surface"],composeWith:["FloatingCardAction","Button","StatusDot","Badge"],avoid:["Modal workflows","Feature-local radius, shadow, background, or close-button styling"],states:["default","focused","long text","narrow","theme","i18n"]}},{id:"ds-popup-menu",name:"Popup menu",description:"Anchored menu baseline with the shared floating shadow and an intermediate xl corner radius.",category:"ds-primitives",render:()=>l.jsx(dne,{}),ai:{useWhen:["A command trigger opens a compact anchored menu or a richer composed menu surface"],composeWith:["DropdownMenu","PopupMenu","Button","IconButton","SelectableRow"],avoid:["Feature-local popup backgrounds, borders, radii, shadows, or entry motion"],states:["default","open","disabled","focused","long text","narrow","theme","i18n"]}},{id:"ds-form-controls",name:"Form controls",description:"Text, select, switch, and checkbox primitives in realistic settings copy.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:260},children:[l.jsx(Fi,{label:"Workspace name",description:"Human-readable project label.",placeholder:"Sparo Agentic OS"}),l.jsx(to,{options:rne,placeholder:"Choose an agent",searchable:!0,shape:"pill",dropdownWidth:"min(320px, calc(100vw - 32px))"}),l.jsx(wr,{label:"Enable proactive assistance",description:"Suggest the next action after a tool batch."}),l.jsx(wh,{name:"preview-default-agent",label:"Use default agent",description:"Radio covers mutually exclusive single-choice rows.",defaultChecked:!0}),l.jsx(yh,{label:"Allow workspace file edits"})]}),ai:{useWhen:["A pattern needs a compact, accessible form control"],composeWith:["FormField","FormSection","SettingsSection","SearchToolbar"],avoid:["Unlabeled controls","Multiple switches for one option set"],states:["default","disabled","loading","error","long text","narrow","i18n"]}},{id:"ds-feedback",name:"Feedback primitives",description:"Status badges and empty states for desktop workflow surfaces.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(nn,{variant:"neutral",children:"Default"}),l.jsx(nn,{variant:"success",children:"Ready"}),l.jsx(nn,{variant:"warning",children:"Needs review"}),l.jsx(nn,{variant:"error",children:"Blocked"})]}),l.jsx(kd,{description:"No matching sessions",imageSize:"small",children:l.jsx(Ce,{variant:"secondary",size:"small",children:"Create one"})})]}),ai:{useWhen:["A list, panel, or tool surface has no data or has a concise status"],composeWith:["PanelBody","DataListEmpty","EmptyStatePanel","StatusBar"],avoid:["Color-only status","Blank panels for empty data"],states:["default","empty","error","long text","theme","i18n"]}},{id:"ds-search-and-filters",name:"Search affordances",description:"Search iconography and filter commands for compact desktop surfaces.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:280},children:[l.jsx(Fi,{prefix:l.jsx(fd,{size:14}),placeholder:"Search sessions, paths, or tools"}),l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(ze,{"aria-label":"Tune filters",tooltip:"Tune filters",size:"small",children:l.jsx(aX,{size:14})}),l.jsx(Ce,{size:"small",variant:"secondary",children:"Active filters"})]})]}),ai:{useWhen:["A local surface needs a small search or filter entry point"],composeWith:["SearchToolbar","FilterBar","ToolbarGroup"],avoid:["Search inputs without labels or aria-labels","Filter chips that resize the toolbar unpredictably"],states:["default","focused","empty","long text","narrow"]}},{id:"ds-dialog-tabs-alerts",name:"Dialogs, tabs, and alerts",description:"Keyboard-focused primitives with explicit roles, labels, and recovery states.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:300},children:[l.jsx(bd,{type:"warning",title:"Pending review",message:"A permission decision needs attention.",closable:!0}),l.jsxs(Ph,{defaultActiveKey:"summary",children:[l.jsx(cr,{tabKey:"summary",label:"Summary",children:"Focusable tab panel content."}),l.jsx(cr,{tabKey:"details",label:"Details",children:"Arrow keys move between tabs."})]}),l.jsx(lne,{}),l.jsx(une,{})]}),ai:{useWhen:["A surface needs modal focus, tabbed content, or persistent status feedback"],composeWith:["Dialog","Tabs","Alert","Button","IconButton"],avoid:["Clickable div tabs","Dialogs without labelled titles","Closable alerts without button labels"],states:["default","focused","error","long text","narrow","keyboard"]}},{id:"ds-input-variants",name:"Input variants",description:"Textarea, search, and number field states with labelled controls and descriptions.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:300},children:[l.jsx(Ri,{inputAriaLabel:"Search preview examples",placeholder:"Search preview examples"}),l.jsx(Ri,{shape:"pill",inputAriaLabel:"Search preview examples pill",placeholder:"Search preview examples"}),l.jsx(vh,{label:"Release note",hint:"Keep it short and actionable.",showCount:!0,maxLength:140}),l.jsx(pne,{}),l.jsx(mne,{})]}),ai:{useWhen:["A workflow needs text entry, numeric tuning, or local search"],composeWith:["FormField","SettingsSection","SearchToolbar"],avoid:["Unlabelled inputs","Hint text not connected with aria-describedby"],states:["default","empty","error","disabled","long text","narrow","i18n"]}},{id:"ds-segmented-pagination",name:"Segmented control and pagination",description:"Middle-layer navigation controls with selected, disabled, focused, narrow, and long-label states.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:300},children:[l.jsx(bs,{ariaLabel:"Preview layout",defaultValue:"list",stretch:!0,options:[{value:"list",label:"List",icon:l.jsx(BZ,{size:14})},{value:"grid",label:"Grid",icon:l.jsx(RZ,{size:14})},{value:"timeline",label:"Timeline view with long label"},{value:"disabled",label:"Disabled",disabled:!0}]}),l.jsx(bs,{ariaLabel:"Disabled preview layout",defaultValue:"list",disabled:!0,options:[{value:"list",label:"列表"},{value:"grid",label:"网格视图"}]}),l.jsx(bs,{ariaLabel:"Accent mode switch",defaultValue:"direct",size:"small",variant:"accent",options:[{value:"direct",label:"I choose"},{value:"delegate",label:"Delegate to OS"}]}),l.jsx(Zc,{ariaLabel:"Primary tabs",size:"medium",stretch:!0,value:"network",options:[{value:"network",label:"Network"},{value:"bot",label:"Bot"}]}),l.jsx(Zc,{ariaLabel:"Secondary tabs",value:"lan",options:[{value:"lan",label:"LAN"},{value:"ngrok",label:"Ngrok"},{value:"custom",label:"Custom server with long label"}]}),l.jsx(Sd,{ariaLabel:"Scene mode",value:"discover",options:[{value:"discover",label:"Discover"},{value:"manage",label:"Manage"}]}),l.jsx(hne,{}),l.jsx(gne,{}),l.jsx(Xc,{page:4,pageCount:12}),l.jsx("div",{style:{maxWidth:190},children:l.jsx(Xc,{page:2,pageCount:8,compact:!0,label:"Compact pagination"})})]}),ai:{useWhen:["A surface switches between small mutually exclusive modes or pages through local data"],composeWith:["Toolbar","PanelHeader","DataList","ActionListRow"],avoid:["Tabs for tiny view-mode switches","Pagination without a current page summary"],states:["default","disabled","selected","focused","long text","narrow","i18n"]}},{id:"ds-loading-status",name:"Loading and status primitives",description:"Stable loading placeholders plus text-backed state indicators.",category:"ds-primitives",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:280},children:[l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(_t,{tone:"success",children:"Ready"}),l.jsx(_t,{tone:"warning",children:"Needs review"}),l.jsx(_t,{tone:"error",children:"Blocked"}),l.jsx(_t,{tone:"info",children:"同步中"})]}),l.jsxs("div",{className:"recipe-preview-inline",children:[l.jsx(dr,{tone:"accent",pulse:!0,label:"Running"}),l.jsx(dr,{tone:"neutral",label:"Idle"}),l.jsx(_t,{tone:"accent",children:"Extremely-long-status-token-without-natural-breaks"})]}),l.jsx(lr,{avatar:!0,lines:3}),l.jsx("div",{style:{maxWidth:180},children:l.jsx(lr,{compact:!0,lines:2})}),l.jsx(rr,{variant:"block",height:40})]}),ai:{useWhen:["A panel waits for data or needs compact state communication"],composeWith:["ActionListRow","ToolCard","StatusBar","PanelBody"],avoid:["Color-only state","Skeletons that change layout size when content loads"],states:["default","loading","error","long text","narrow","theme","i18n"]}}]}],yne=De.memo(({toolItem:i,onOpenInEditor:e})=>{const{t:n}=on("flow-chat"),{toolCall:s,toolResult:r,status:c}=i,u=k.useMemo(()=>Cr(i),[i]),m=u.phase==="result",h=k.useMemo(()=>{const _=s?.input?.file_path||s?.input?.target_file||s?.input?.path;if(!_){const E=s?.input?._early_detection===!0,j=s?.input?._partial_params===!0;return n("toolCards.readFile.parsingParams")}return _},[n,s?.input]),f=()=>{h!==n("toolCards.readFile.noFileSpecified")&&h!==n("toolCards.readFile.parsingParams")&&e?.(h)},y=k.useMemo(()=>!h||h===n("toolCards.readFile.noFileSpecified")||h===n("toolCards.readFile.parsingParams")?h||n("toolCards.readFile.noFileSpecified"):h.split(/[\\/]/).pop()||h,[h,n]),v=k.useMemo(()=>{const _=s?.input?.start_line,E=s?.input?.limit;if(_!==void 0||E!==void 0){const j=_||1,z=E?j+E-1:void 0;if(z)return`L${j}~L${z}`;if(j>1)return`L${j}~EOF`}return null},[s?.input?.start_line,s?.input?.limit]),b=k.useMemo(()=>{if(!r?.result)return null;const _=r.result.content||r.result;if(typeof _=="string"){const E=new TextEncoder().encode(_).length;return E<1024?`${E}B`:E<1024*1024?`${(E/1024).toFixed(1)}KB`:`${(E/(1024*1024)).toFixed(1)}MB`}return null},[r?.result]),S=m&&h!==n("toolCards.readFile.noFileSpecified")&&h!==n("toolCards.readFile.parsingParams");if(u.phase==="error")return null;const A=()=>S?l.jsx("button",{type:"button",className:"read-file-name read-file-name--openable",onClick:_=>{_.preventDefault(),_.stopPropagation(),f()},title:h,children:y}):l.jsx("span",{className:"read-file-name",children:y}),F=()=>m?l.jsxs(l.Fragment,{children:[n("toolCards.readFile.readFile"),": ",A(),v&&l.jsxs("span",{className:"read-file-meta",children:[" ",v]}),b&&l.jsxs("span",{className:"read-file-meta",children:[" (",b,")"]})]}):u.phase==="running"||u.phase==="receiving_input"?l.jsxs(l.Fragment,{children:[n("toolCards.readFile.readingFile")," ",A(),v&&l.jsxs("span",{className:"read-file-meta",children:[" ",v]}),"..."]}):u.phase==="preparing"||u.phase==="ready"?l.jsxs(l.Fragment,{children:[n("toolCards.readFile.preparingRead")," ",A(),v&&l.jsxs("span",{className:"read-file-meta",children:[" ",v]})]}):u.phase==="cancelled"||u.phase==="interrupted"?l.jsxs(l.Fragment,{children:[n("toolCards.readFile.readFile"),": ",A(),v&&l.jsxs("span",{className:"read-file-meta",children:[" ",v]})]}):null;return l.jsx(Mi,{toolId:i.id??s?.id,toolName:i.toolName,status:c,className:"read-file-card",summary:F()})}),wne={toolName:"Read",displayName:"Read file",icon:"",requiresConfirmation:!1,resultDisplayType:"summary",displayMode:"compact"},vne={id:"preview-read-file",type:"tool",toolName:"Read",timestamp:1,status:"completed",toolCall:{id:"preview-read-file",input:{file_path:"src/web-ui/src/design-system/patterns/ToolCard/ToolCard.tsx",start_line:1,limit:84}},toolResult:{success:!0,result:{content:"export const ToolCard = forwardRef(...)"}}};function bne(){const{t:i}=on("flow-chat"),[e,n]=k.useState(!1);return l.jsxs("div",{className:"production-tool-card-preview",children:[l.jsx(yne,{config:wne,toolItem:vne}),l.jsx(Mi,{toolId:"preview-terminal-command",toolName:"Bash",status:"completed",isExpanded:e,expandable:!0,onToggle:n,summary:l.jsxs(l.Fragment,{children:[i("toolCards.terminal.executeCommand")," ",l.jsx("code",{className:"production-tool-card-preview__command",children:"pnpm run check:design-system"})]}),extra:l.jsx("span",{className:"production-tool-card-preview__duration",children:"1.28s"}),expandedContent:l.jsxs("div",{className:"production-tool-card-preview__output",children:[l.jsx("code",{children:"Design system check: 0 blocking, 0 advisory."}),l.jsx("span",{children:"Sparo-Agentic-OS · exit 0"})]})})]})}function kne(){const[i,e]=k.useState(!1);return l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsx(Ce,{size:"small",variant:"secondary",onClick:()=>e(!0),children:"Open application window"}),l.jsxs(rte,{open:i,onOpenChange:e,title:"Device Network",titleExtra:l.jsx(nn,{variant:"success",children:"Local device online"}),size:"wide",closeLabel:"Close application window",children:[l.jsxs(Cd,{style:{padding:"var(--ds-space-5)",minHeight:320},children:[l.jsx("strong",{style:{color:"var(--ds-color-text-primary)"},children:"Large in-app content surface"}),l.jsx("p",{style:{maxWidth:620,color:"var(--ds-color-text-secondary)",lineHeight:1.6},children:"This non-modal window supports longer workflows without dimming or blocking the surrounding application. It receives focus on open, closes with Escape, and restores focus to its trigger."})]}),l.jsx(Rh,{children:l.jsx(Ce,{size:"small",variant:"secondary",onClick:()=>e(!1),children:"Close"})})]})]})}const Sne=[{label:"GPT-5.3 Codex",value:"gpt-5.3-codex"},{label:"Fast local model",value:"local-fast"}];function xne(){return l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsx(hs,{width:"default","aria-label":"Default settings page",children:l.jsx(To,{"data-setting-section":"models.defaults",title:"Model defaults",description:"Horizontal fields keep dense desktop settings scannable.",actions:l.jsx(_t,{tone:"success",children:"Synced"}),children:l.jsxs(gs,{children:[l.jsx(en,{"data-setting-id":"models.default",orientation:"horizontal",controlWidth:"wide",label:"Default model",description:"Used for new coding sessions.",children:l.jsx(to,{value:"gpt-5.3-codex",options:Sne})}),l.jsx(en,{"data-setting-id":"models.reasoningEffort",orientation:"horizontal",controlWidth:"balanced",label:"Reasoning effort",children:l.jsx(Fi,{value:"medium",readOnly:!0})}),l.jsx(en,{"data-setting-id":"agent.proactive",orientation:"horizontal",controlWidth:"compact",label:"Planner mode",children:l.jsx(wr,{label:"Ask before broad changes",checked:!0,readOnly:!0})}),l.jsxs(Fd,{children:[l.jsx(Ce,{variant:"ghost",children:"Reset"}),l.jsx(Ce,{variant:"primary",children:"Save"})]})]})})}),l.jsx(hs,{width:"wide",lang:"zh-CN","aria-label":"长文本和中文设置页",children:l.jsx(To,{"data-setting-section":"permissions.tool-execution",title:"智能能力与工具执行权限",description:"长标签、自然语言说明和没有自然断点的标识符都必须保持可读,不能挤压右侧控件。",actions:l.jsx(_t,{tone:"warning",children:"需要确认"}),children:l.jsx(gs,{children:l.jsx(en,{"data-setting-id":"permissions.workspace.longPolicyIdentifier",orientation:"horizontal",controlWidth:"wide",label:"涉及工作区文件写入与桌面自动化操作时始终要求明确确认",description:"workspace-write-confirmation-policy-with-an-extremely-long-unbroken-identifier",children:l.jsx(to,{value:"ask",options:[{label:"始终询问并显示具体影响范围",value:"ask"},{label:"仅在高风险操作时询问",value:"risky"}]})})})})}),l.jsx("div",{className:"recipe-preview-narrow","data-preview-state":"narrow",children:l.jsx(hs,{width:"full","aria-label":"Narrow settings page",children:l.jsx(To,{"data-setting-section":"appearance.interface",title:"Appearance",description:"Horizontal fields stack automatically when their form container becomes narrow.",children:l.jsx(gs,{children:l.jsx(en,{"data-setting-id":"appearance.interfaceScale",orientation:"horizontal",controlWidth:"balanced",label:"Interface scale",description:"Keeps controls reachable without horizontal overflow.",children:l.jsx(to,{value:"comfortable",options:[{label:"Comfortable",value:"comfortable"}]})})})})})}),l.jsxs(hs,{width:"narrow","aria-label":"Loading and error settings states",children:[l.jsx(To,{"data-setting-section":"catalog.loading",title:"Catalog-backed settings",actions:l.jsx(_t,{tone:"info",children:"Loading"}),children:l.jsx(lr,{lines:3,"aria-label":"Loading setting definitions"})}),l.jsx(To,{"data-setting-section":"provider.validation",title:"Provider validation",actions:l.jsx(_t,{tone:"error",children:"Error"}),children:l.jsxs(gs,{children:[l.jsx(bd,{type:"error",message:"The provider endpoint could not be validated."}),l.jsx(en,{"data-setting-id":"provider.baseUrl",orientation:"horizontal",controlWidth:"wide",label:"Base URL",error:"Enter a valid HTTPS endpoint before saving.",children:l.jsx(Fi,{value:"invalid-endpoint",error:!0,readOnly:!0})})]})})]})]})}const Cne=[{id:"ds-patterns",name:"Patterns",description:"Page and workflow structures that AI agents should prefer before reaching for primitives.",layoutType:"large-card",tier:"pattern",aiRole:"Patterns define the desktop product structure: scenes, panels, lists, settings sections, and tool execution shells.",decisionRules:["Use Scene for app pages and product scenes.","Use Panel for bounded functional areas; keep cards for repeated items, dialogs, or framed tools.","Use ListDetail when selection drives a focused detail surface.","Use ToolCard only for AI/tool execution output and preserve streaming behavior in product code."],examples:[{id:"ds-app-window",name:"Application window",description:"Non-modal in-app popup window for substantial content without a backdrop.",category:"ds-patterns",render:()=>l.jsx(kne,{}),ai:{recipe:"recipes/floating-surfaces.recipe.md",useWhen:["A substantial multi-section workflow must float above the app without blocking the background"],composeWith:["AppWindowHeader","AppWindowBody","AppWindowFooter","Toolbar","Tabs"],avoid:["Compact confirmations","Backdrop overlays","Feature-local window chrome"],states:["default","focused","long text","narrow","theme","i18n"]}},{id:"ds-scene-panel",name:"Scene + Panel",description:"Default desktop scene composition with command grouping and bounded work areas.",category:"ds-patterns",render:()=>l.jsxs(kr,{style:{minHeight:420},children:[l.jsx(Sr,{title:"Agent sessions",description:"Dense desktop layout with clear commands and scannable panels.",actions:l.jsx(Td,{density:"compact",primary:l.jsx(Ce,{variant:"primary",children:"New session"}),secondary:l.jsx(Ce,{variant:"secondary",children:"Filter"}),meta:"4 active"})}),l.jsx(xr,{children:l.jsxs(Fn,{children:[l.jsx(Rn,{title:"Recent activity",description:"PanelHeader holds title, summary, and local actions."}),l.jsx(Nn,{children:l.jsxs(Ni,{children:[l.jsx(hn,{selected:!0,children:"Refine task detail navigation"}),l.jsx(hn,{children:"Audit design-system imports"}),l.jsx(hn,{children:"Prepare desktop release checks"})]})})]})})]}),ai:{recipe:"recipes/scene-page.recipe.md",useWhen:["Building an app scene or durable product page"],composeWith:["SceneHeader","SceneBody","Panel","PanelHeader","CommandBar"],avoid:["Marketing hero layouts inside the desktop app","Page sections styled as floating cards"],states:["default","loading","error","long text","narrow","theme","i18n"]}},{id:"ds-list-detail",name:"List detail workflow",description:"Selectable master list plus focused detail or inspector surface.",category:"ds-patterns",render:()=>l.jsx(br,{ratio:"balanced",listLabel:"Agent runs",detailLabel:"Selected run",list:l.jsxs(Fn,{children:[l.jsx(Rn,{title:"Runs"}),l.jsxs(Nn,{children:[l.jsx(_d,{density:"compact",search:{value:"design",inputAriaLabel:"Search runs"}}),l.jsxs(Ni,{style:{marginTop:12},children:[l.jsx(hn,{selected:!0,children:"Design-system final pass"}),l.jsx(hn,{children:"Workspace file review"}),l.jsx(Nh,{children:"No archived sessions match the filter."})]})]})]}),detail:l.jsx(Pd,{title:"Design-system final pass",description:"InspectorPanel keeps selected-item facts and actions close to the content.",footer:l.jsx(vr,{tone:"info",children:"Selection state is explicit and keyboard reachable."}),children:l.jsxs("div",{className:"recipe-preview-meta",children:[l.jsx("span",{children:"Pattern stack: ListDetail + Panel + DataList + InspectorPanel."}),l.jsx("span",{className:"recipe-preview-code-path",children:"src/web-ui/src/design-system/preview/registries/patterns.tsx"})]})})}),ai:{recipe:"recipes/list-detail.recipe.md",useWhen:["Selection controls the main detail area","The user compares many items and acts on one"],composeWith:["SearchToolbar","DataList","InspectorPanel","StatusBar","EmptyStatePanel"],avoid:["Blank detail panes","Nested cards around list rows"],states:["default","empty","selected","loading","error","long text","narrow"]}},{id:"ds-settings-page",name:"Settings page",description:"Standard configuration layout for settings, preferences, and provider setup.",category:"ds-patterns",render:()=>l.jsx(xne,{}),ai:{recipe:"recipes/settings-page.recipe.md",useWhen:["The UI saves durable settings or provider configuration"],composeWith:["SettingsSection","FormSection","FormField","Select","Switch","FormActions"],avoid:["Feature-local form rows","Switches for multi-option policy choices"],states:["default","disabled","loading","error","long text","narrow","theme","i18n"]}},{id:"ds-item-card",name:"Item cards",description:"Reusable repeated-item card shell for tasks, apps, and other actionable catalog entries.",category:"ds-patterns",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:320},children:[l.jsxs(td,{status:"running",highlighted:!0,"aria-label":"Running coding task",children:[l.jsxs(nd,{children:[l.jsx(gg,{size:14}),l.jsx(od,{children:"Refactor session card shell"})]}),l.jsxs(sd,{children:[l.jsx(nn,{variant:"accent",children:"Coding"}),l.jsx(dte,{}),l.jsxs(id,{children:[l.jsx(eh,{size:10})," 2 min ago"]})]}),l.jsxs(Ih,{children:[l.jsxs(Ce,{size:"small",variant:"ghost",children:["Open ",l.jsx(BY,{size:12})]}),l.jsx(Ce,{size:"small",variant:"ghost",iconOnly:!0,"aria-label":"Stop",children:l.jsx(sh,{size:12})})]})]}),l.jsxs(td,{status:"idle","aria-label":"Long catalog entry",children:[l.jsxs(nd,{children:[l.jsx(bi,{size:14}),l.jsx(od,{children:"Extremely-long-application-name-without-breakpoints-for-overflow-checking"}),l.jsx(nn,{variant:"purple",children:"Agent Component"})]}),l.jsx(sd,{children:l.jsx(id,{children:"A compact card for repeated management grids and task boards."})})]})]}),ai:{useWhen:["A repeated card represents an app, task, session, or catalog item with actions"],composeWith:["Badge","StatusDot","Button","IconButton","Tooltip"],avoid:["Feature-local card shells","Status indicated only by color","Nested cards"],states:["default","running","active","error","long text","selected","theme","i18n"]}},{id:"ds-tool-card",name:"Production tool cards",description:"Actual compact and expandable flow-chat cards used by registered Read and Bash tools.",category:"ds-patterns",render:bne,ai:{useWhen:["Reviewing or extending the flow-chat cards used by registered product tools"],composeWith:["DefaultToolCardTemplate","CompactToolCard","BaseToolCard"],avoid:["Preview-only stand-ins","A second generic card shell","Status represented by color alone"],states:["compact","expanded","completed","error","long text","theme","i18n"]}},{id:"ds-navigation-empty-status",name:"Navigation, empty, and status",description:"Supporting patterns for workspace navigation and resilient empty states.",category:"ds-patterns",render:()=>l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsxs(ur,{"aria-label":"Design-system areas",children:[l.jsx(gn,{active:!0,icon:l.jsx(bi,{size:14}),meta:l.jsx(nn,{variant:"success",children:"Ready"}),children:"Preview"}),l.jsx(gn,{icon:l.jsx(Kc,{size:14}),meta:"4",children:"Recipes"}),l.jsx(gn,{icon:l.jsx(fd,{size:14}),meta:"8",children:"Status states"})]}),l.jsxs(ur,{variant:"plain","aria-label":"Plain workspace navigation",children:[l.jsx(gn,{active:!0,icon:l.jsx(bi,{size:14}),meta:"12",children:"Source files"}),l.jsx(gn,{icon:l.jsx(Kc,{size:14}),meta:"4",children:"Open editors"}),l.jsx(gn,{icon:l.jsx(Qc,{size:14}),meta:"dirty",children:"Git changes"})]}),l.jsx(Dh,{title:"No matching tools",description:"Use EmptyStatePanel when a bounded work area has no data.",emptyState:{title:"Nothing to show",description:"Adjust filters or create a new session.",actions:l.jsx(Ce,{size:"small",variant:"primary",children:"Create session"})}})]}),ai:{useWhen:["A sidebar, local nav, or bounded panel can be empty"],composeWith:["NavigationList","NavigationListItem","EmptyStatePanel","StatusBar","Badge"],avoid:["Silent empty surfaces","Navigation state represented only by color"],states:["default","empty","selected","long text","narrow","theme"]}},{id:"ds-action-list-row",name:"Action list rows",description:"Reusable row composition for selectable items, row metadata, status, actions, loading, and errors.",category:"ds-patterns",render:()=>l.jsxs("div",{className:"recipe-preview-stack",style:{minWidth:320},children:[l.jsx(us,{leading:l.jsx(Qc,{size:16}),title:"Prepare design-system migration",description:"Row content wraps naturally and keeps action controls aligned.",meta:l.jsx(_t,{tone:"success",children:"Ready"}),actions:l.jsx(Ce,{size:"small",variant:"secondary",children:"Open"})}),l.jsx(us,{leading:l.jsx(ih,{size:16}),title:"Extremely-long-action-row-title-without-natural-breakpoints-to-prove-overflow-resilience",description:"A natural long sentence can wrap across multiple lines in a narrow panel without covering metadata or actions.",meta:"12 minutes ago",actions:l.jsx(Ce,{size:"small",variant:"ghost",iconOnly:!0,"aria-label":"More actions",children:l.jsx(mZ,{size:14})})}),l.jsx(us,{title:"Workspace permission",description:"Disabled state preserves text contrast while blocking row-level affordances.",meta:l.jsx(_t,{tone:"warning",children:"Waiting"}),disabled:!0}),l.jsx(us,{title:"Load workspace sessions",description:"The row can mark async work without changing its dimensions.",loading:!0,meta:l.jsx(_t,{tone:"info",children:"Loading"})}),l.jsx(us,{title:"Provider health check",description:"Errors use text plus border treatment.",error:"Request failed. Check provider configuration.",meta:l.jsx(_t,{tone:"error",children:"Error"})}),l.jsx(ed,{selected:!0,leading:l.jsx(gg,{size:16}),title:"Selected coding agent",description:"SelectableRow exposes pressed state and keyboard activation through a real button.",meta:"Active"}),l.jsx(ed,{disabled:!0,title:"Unavailable agent profile",description:"Disabled selectable rows keep their layout stable.",meta:"Disabled"})]}),ai:{useWhen:["A list row combines title, metadata, status, and row-level commands"],composeWith:["DataList","PanelBody","StatusPill","Button","IconButton"],avoid:["Feature-local row shells","Rows that rely on color only for selected or error state"],states:["default","disabled","loading","error","long text","narrow","theme","i18n"]}}]}],Ane=[{label:"GPT-5.3 Codex",value:"gpt-5.3-codex",description:"Default coding agent model"},{label:"GPT-5.3 Mini",value:"gpt-5.3-mini",description:"Fast review and triage model"}],_ne=[{label:"Ask before write",value:"ask",description:"Recommended for shared workspaces"},{label:"Allow scoped writes",value:"scoped",description:"Only inside the open workspace"}];function Tne(){const i=l.jsxs(Fn,{children:[l.jsx(Rn,{title:"Session queue",description:"Use SearchToolbar above DataList when the primary job is finding work."}),l.jsxs(Nn,{children:[l.jsx(_d,{density:"compact",search:{value:"release checks",inputAriaLabel:"Search sessions"},filters:l.jsx(Ce,{size:"small",variant:"secondary",children:"Open"}),actions:l.jsx(ze,{"aria-label":"Filter sessions",tooltip:"Filter sessions",size:"small",children:l.jsx(TZ,{size:14})})}),l.jsxs(Ni,{style:{marginTop:12},children:[l.jsx(hn,{selected:!0,children:l.jsxs("div",{className:"recipe-preview-row",children:[l.jsxs("div",{className:"recipe-preview-row__copy",children:[l.jsx("p",{className:"recipe-preview-row__title",children:"Desktop release readiness"}),l.jsx("p",{className:"recipe-preview-row__meta",children:"3 active tool calls · review required"})]}),l.jsx(nn,{variant:"warning",children:"Review"})]})}),l.jsx(hn,{children:l.jsxs("div",{className:"recipe-preview-row",children:[l.jsxs("div",{className:"recipe-preview-row__copy",children:[l.jsx("p",{className:"recipe-preview-row__title",children:"Design-system import audit"}),l.jsx("p",{className:"recipe-preview-row__meta",children:"Waiting for design-system check"})]}),l.jsx(nn,{variant:"neutral",children:"Queued"})]})})]})]})]}),e=l.jsxs(Pd,{title:"Desktop release readiness",description:"Use InspectorPanel for selected item facts, status, and local commands.",actions:l.jsx(Ce,{size:"small",variant:"primary",children:"Resume"}),footer:l.jsx(vr,{tone:"warning",leading:l.jsx(lX,{size:14}),children:"One permission decision is pending."}),children:[l.jsxs("div",{className:"recipe-preview-metrics",children:[l.jsxs("div",{className:"recipe-preview-metric",children:[l.jsx("strong",{children:"8"}),l.jsx("span",{children:"files changed"})]}),l.jsxs("div",{className:"recipe-preview-metric",children:[l.jsx("strong",{children:"3"}),l.jsx("span",{children:"checks running"})]}),l.jsxs("div",{className:"recipe-preview-metric",children:[l.jsx("strong",{children:"1"}),l.jsx("span",{children:"blocked action"})]})]}),l.jsxs("div",{className:"recipe-preview-meta",style:{marginTop:14},children:[l.jsx("span",{children:"Pattern stack: Scene + ListDetail + DataList + InspectorPanel + StatusBar"}),l.jsx("span",{className:"recipe-preview-code-path",children:"Workspace: D:/workspace/Sparo-Agentic-OS"})]})]});return l.jsxs(kr,{density:"compact",className:"recipe-preview-stack",children:[l.jsx(Sr,{eyebrow:"Recipe",title:"Agent session workbench",description:"Default shell for session triage, task continuation, and current agent activity.",actions:l.jsx(Td,{density:"compact",primary:l.jsx(Ce,{variant:"primary",children:"New session"}),secondary:l.jsx(Ce,{variant:"ghost",children:"Refresh"}),meta:"Live workspace"})}),l.jsx(xr,{children:l.jsx(br,{listLabel:"Sessions",detailLabel:"Session detail",ratio:"balanced",list:i,detail:e})})]})}function Pne(){const i=l.jsxs(Fn,{children:[l.jsx(Rn,{title:"Workspace files",actions:l.jsx(ze,{"aria-label":"Refresh files",tooltip:"Refresh files",size:"small",children:l.jsx(hd,{size:14})})}),l.jsx(Nn,{children:l.jsxs(ur,{"aria-label":"Workspace file groups",children:[l.jsx(gn,{active:!0,icon:l.jsx(bi,{size:14}),meta:"12",children:"src/web-ui"}),l.jsx(gn,{icon:l.jsx(Kc,{size:14}),meta:"4",children:"design-system"}),l.jsx(gn,{icon:l.jsx(Qc,{size:14}),meta:"dirty",children:"git status"})]})})]}),e=l.jsxs(Fn,{children:[l.jsx(Rn,{title:"File operations",description:"Use Panel for bounded tools and keep file paths intentionally wrappable.",actions:l.jsx(Ce,{size:"small",variant:"secondary",children:"Open"})}),l.jsx(Nn,{children:l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsx(vr,{tone:"info",leading:l.jsx(fd,{size:14}),children:"Preview is deterministic: no workspace file reads or Tauri commands."}),l.jsxs(Ni,{children:[l.jsxs(hn,{selected:!0,children:[l.jsx("p",{className:"recipe-preview-row__title",children:"Edited recipe docs"}),l.jsx("p",{className:"recipe-preview-row__meta recipe-preview-code-path",children:"src/web-ui/src/design-system/recipes/agent-session-workbench.recipe.md"})]}),l.jsxs(hn,{children:[l.jsx("p",{className:"recipe-preview-row__title",children:"Updated preview registry"}),l.jsx("p",{className:"recipe-preview-row__meta recipe-preview-code-path",children:"src/web-ui/src/design-system/preview/registries/recipes.tsx"})]})]})]})})]});return l.jsx("div",{className:"recipe-preview-narrow",children:l.jsx(br,{listLabel:"Navigation",detailLabel:"File detail",ratio:"narrow",list:i,detail:e})})}function Fne(){return l.jsxs(kr,{density:"compact",className:"recipe-preview-stack",children:[l.jsx(Sr,{eyebrow:"Recipe",title:"AI model and permission settings",description:"Configuration screens should use SettingsPage, SettingsSection, FormSection, and FormField before primitives.",actions:l.jsx(Ce,{variant:"primary",children:"Save changes"})}),l.jsx(xr,{children:l.jsx(hs,{children:l.jsx(To,{title:"Model defaults",description:"Put related settings in one section and keep action placement stable.",actions:l.jsx(nn,{variant:"success",children:"Synced"}),children:l.jsxs(gs,{children:[l.jsx(en,{label:"Default coding model",description:"Used when a new agent session starts.",children:l.jsx(to,{options:Ane,value:"gpt-5.3-codex"})}),l.jsx(en,{label:"Workspace write permission",description:"Use Select for policy sets instead of multiple switches.",children:l.jsx(to,{options:_ne,value:"ask"})}),l.jsx(en,{label:"Proactive assistance",description:"Use Switch for immediate binary settings only.",children:l.jsx(wr,{checked:!0,label:"Suggest next actions after tool batches"})}),l.jsx(en,{label:"Reasoning budget label",description:"Long text must wrap without pushing actions out of reach.",error:"Use a short label that can fit compact settings navigation.",children:l.jsx(Fi,{value:"balanced-release-readiness-with-extra-long-local-policy-name",error:!0})}),l.jsxs(Fd,{children:[l.jsx(Ce,{variant:"ghost",children:"Reset"}),l.jsx(Ce,{variant:"primary",children:"Save"})]})]})})})})]})}function Rne(){return l.jsxs("div",{className:"recipe-preview-stack",children:[l.jsxs(Si,{status:"running",tone:"info",children:[l.jsx(xi,{icon:l.jsx(ih,{size:16}),title:"Run web build",meta:"Running · pnpm run check:design-system",actions:l.jsx(ze,{"aria-label":"Stop command",tooltip:"Stop command",size:"small",variant:"danger",children:l.jsx(iZ,{size:14})})}),l.jsx(Ci,{children:l.jsxs("div",{className:"recipe-preview-meta",children:[l.jsx("span",{children:"Show the operation, status text, and stable actions while output streams."}),l.jsx("span",{className:"recipe-preview-code-path",children:"src/web-ui/dist-preview/assets/index.js"})]})}),l.jsx(pr,{children:l.jsx(Ce,{size:"small",variant:"secondary",children:"Open log"})})]}),l.jsxs(Si,{status:"completed",tone:"success",children:[l.jsx(xi,{icon:l.jsx(oZ,{size:16}),title:"Design check",meta:"Completed"}),l.jsx(Ci,{children:"Use success tone only with explicit completed copy and a visible status icon."})]}),l.jsxs(Si,{status:"error",tone:"danger",children:[l.jsx(xi,{icon:l.jsx(ah,{size:16}),title:"Apply patch",meta:"Needs attention"}),l.jsx(Ci,{children:"Patch failed because the context no longer matched. Show a recovery path instead of a blank error."}),l.jsx(pr,{children:l.jsx(Ce,{size:"small",variant:"primary",children:"Review context"})})]})]})}const Nne=[{id:"ds-ai-entry",name:"AI Entry Rules",description:"Start here before composing any product UI with the design system.",layoutType:"large-card",tier:"recipe",aiRole:"This page is the decision layer: pick the closest recipe, then compose patterns, then place primitives inside those patterns.",decisionRules:["For scenes, start with Scene and choose ListDetail, SettingsPage, or Panel based on the user workflow.","For flow-chat tool output, start with ToolCard and keep tool-specific rendering in the product folder.","For configuration, use SettingsPage and FormField before reaching for individual inputs.","Do not create feature-local control APIs for buttons, inputs, selects, dialogs, tabs, badges, or tooltips."],examples:[{id:"recipe-agent-session-workbench",name:"Agent session workbench",description:"Real product scene for session triage, task continuation, and live agent activity.",category:"ds-ai-entry",render:Tne,ai:{recipe:"recipes/agent-session-workbench.recipe.md",useWhen:["Building session, task, or agent activity scenes","The user needs list selection plus a focused detail panel"],composeWith:["Scene","ListDetail","DataList","InspectorPanel","CommandBar","StatusBar"],avoid:["Unbounded page cards","Feature-local list containers","Color-only state"],states:["default","selected","loading","error","long text","narrow","theme","i18n"]}},{id:"recipe-workspace-file-operations",name:"Workspace file operations",description:"Compact navigation plus detail shell for file, diff, and workspace browsing tasks.",category:"ds-ai-entry",render:Pne,ai:{recipe:"recipes/workspace-file-operations.recipe.md",useWhen:["Building file browsers, diff summaries, or workspace operation panes","The UI has paths, counts, and selectable navigation"],composeWith:["ListDetail","NavigationList","Panel","DataList","StatusBar"],avoid:["Live file-system reads in preview","Truncation without tooltip or wrap strategy"],states:["default","empty","selected","long text","narrow","theme"]}},{id:"recipe-model-settings",name:"Model and permission settings",description:"Settings recipe for model defaults, workspace policies, and validation states.",category:"ds-ai-entry",render:Fne,ai:{recipe:"recipes/model-permission-settings.recipe.md",useWhen:["Building settings, preferences, provider setup, or policy pages","The surface saves durable configuration"],composeWith:["Scene","SettingsPage","SettingsSection","FormSection","FormField","Select","Switch"],avoid:["Multiple switches for one option set","Save buttons that move between states"],states:["default","disabled","loading","error","long text","narrow","theme","i18n"]}},{id:"recipe-tool-execution",name:"Tool execution cards",description:"Flow-chat execution shell for running, completed, and failed tool output.",category:"ds-ai-entry",render:Rne,ai:{recipe:"recipes/tool-execution-card.recipe.md",useWhen:["Rendering AI or tool execution results","The content streams, completes, or fails with recovery actions"],composeWith:["ToolCard","ToolCardHeader","ToolCardBody","ToolCardFooter","Button","IconButton"],avoid:["Status represented by color only","Action layout that shifts between running and completed states"],states:["pending","running","completed","error","long text","theme","i18n"]}}]}],Dne=[...fne,...Cne,...Nne];function Za({title:i,items:e}){return!e||e.length===0?null:l.jsxs("section",{className:"preview-usage-guide__section",children:[l.jsx("h4",{children:i}),l.jsx("ul",{children:e.map(n=>l.jsx("li",{children:n},n))})]})}const Ine=({guide:i,variant:e="disclosure"})=>{const{t:n}=on("design-system/preview");if(!i)return null;const s=[i.useWhen,i.composeWith,i.avoid,i.states].reduce((c,u)=>c+(u?.length??0),0),r=l.jsxs("div",{className:"preview-usage-guide__body",children:[i.recipe&&l.jsxs("div",{className:"preview-usage-guide__recipe",children:[n("guide.recipe")," ",l.jsx("code",{children:i.recipe})]}),l.jsxs("div",{className:"preview-usage-guide__grid",children:[l.jsx(Za,{title:n("guide.useWhen"),items:i.useWhen}),l.jsx(Za,{title:n("guide.composeWith"),items:i.composeWith}),l.jsx(Za,{title:n("guide.avoid"),items:i.avoid}),l.jsx(Za,{title:n("guide.states"),items:i.states})]})]});return e==="panel"?l.jsxs("div",{className:"preview-usage-guide preview-usage-guide--panel",children:[l.jsx("div",{className:"preview-usage-guide__panel-meta",children:n("guide.notes",{count:s})}),r]}):l.jsxs("details",{className:"preview-usage-guide",children:[l.jsxs("summary",{children:[l.jsx("span",{children:n("focused.usageGuidance")}),l.jsx("span",{className:"preview-usage-guide__count",children:n("guide.notes",{count:s})})]}),r]})},Mne=({category:i,example:e,index:n,total:s,previousExample:r,nextExample:c,onPrevious:u,onNext:m})=>{const h=e.render,f=i.tier??"primitive",[y,v]=k.useState(!1),{t:b}=on("design-system/preview");return l.jsxs("section",{className:`focused-preview focused-preview--${f}`,children:[l.jsxs("header",{className:"focused-preview__header",children:[l.jsxs("div",{className:"focused-preview__title-group",children:[l.jsxs("div",{className:"focused-preview__eyebrow",children:[l.jsx("span",{children:b(`focused.tiers.${f}`)}),l.jsx("span",{children:i.name})]}),l.jsxs("div",{className:"focused-preview__heading",children:[l.jsxs("div",{children:[l.jsx("h2",{children:e.name}),l.jsx("p",{children:e.description})]}),l.jsx("code",{children:e.id})]})]}),l.jsxs("div",{className:"focused-preview__controls",children:[l.jsxs("nav",{className:"focused-preview__stepper","aria-label":b("focused.examplesAriaLabel"),children:[l.jsx(ze,{size:"small",variant:"ghost",onClick:u,"aria-label":b("focused.previous",{name:r.name}),tooltip:b("focused.previous",{name:r.name}),children:l.jsx(gd,{size:14,"aria-hidden":"true"})}),l.jsxs("span",{children:[String(n+1).padStart(2,"0"),l.jsx("i",{children:"/"}),String(s).padStart(2,"0")]}),l.jsx(ze,{size:"small",variant:"ghost",onClick:m,"aria-label":b("focused.next",{name:c.name}),tooltip:b("focused.next",{name:c.name}),children:l.jsx(oo,{size:14,"aria-hidden":"true"})})]}),l.jsxs(Ce,{className:"focused-preview__usage-trigger",size:"small",variant:"ghost",onClick:()=>v(S=>!S),"aria-expanded":y,children:[l.jsx(GZ,{size:13,"aria-hidden":"true"}),b("focused.usage")]})]})]}),l.jsxs("div",{className:"focused-preview__body",children:[l.jsx("div",{className:"focused-preview__stage",children:l.jsx("div",{className:"focused-preview__viewport",children:l.jsx(h,{})})}),y&&l.jsxs("aside",{className:"focused-preview__inspector","aria-label":b("focused.usageGuidance"),children:[l.jsxs("div",{className:"focused-preview__inspector-header",children:[l.jsx("span",{children:b("focused.usage")}),l.jsx(ze,{size:"xs",variant:"ghost",onClick:()=>v(!1),"aria-label":b("focused.closeUsage"),tooltip:b("focused.closeUsage"),children:l.jsx(Cs,{size:12,"aria-hidden":"true"})})]}),l.jsx(Ine,{guide:e.ai,variant:"panel"})]})]})]})},jne="design-system/preview";function Ene({category:i}){return i.tier==="pattern"?l.jsx(zY,{size:15,"aria-hidden":"true"}):i.tier==="recipe"?l.jsx(HY,{size:15,"aria-hidden":"true"}):l.jsx(GY,{size:15,"aria-hidden":"true"})}const Lne=()=>{const i=k.useMemo(()=>Dne,[]),e=k.useMemo(()=>hte,[]),{t:n,i18n:s}=on(jne),r=k.useMemo(()=>fs,[]),c=s.resolvedLanguage??s.language,[u,m]=k.useState("light"),[h,f]=k.useState(i[0]?.id||""),[y,v]=k.useState(i[0]?.examples[0]?.id||""),[b,S]=k.useState(!1),[A,F]=k.useState(""),_=k.useRef(null),E=k.useMemo(()=>i.map(L=>({...L,name:n(`catalog.categories.${L.id}.name`,{defaultValue:L.name}),description:n(`catalog.categories.${L.id}.description`,{defaultValue:L.description}),examples:L.examples.map($=>({...$,name:n(`catalog.examples.${$.id}.name`,{defaultValue:$.name}),description:n(`catalog.examples.${$.id}.description`,{defaultValue:$.description})}))})),[i,n]),j=e.find(L=>L.id===u)??e[0];De.useEffect(()=>{document.title=n("documentTitle"),document.documentElement.setAttribute("lang",c),document.documentElement.setAttribute("dir","ltr")},[c,n]),De.useEffect(()=>{if(!j||typeof document>"u")return;const L=document.documentElement,$=j;vs(L,uh($)),vs(L,ph($)),vs(L,dh($)),L.dataset.theme=j.id,L.dataset.themeType=j.type},[j]),De.useEffect(()=>{const L=$=>{const te=$.target,G=te?.tagName==="INPUT"||te?.tagName==="TEXTAREA",C=($.metaKey||$.ctrlKey)&&$.key.toLowerCase()==="k",N=$.key==="/"&&!G;!C&&!N||($.preventDefault(),_.current?.focus())};return window.addEventListener("keydown",L),()=>window.removeEventListener("keydown",L)},[]);const z=A.trim().toLowerCase(),B=k.useMemo(()=>z?E.map(L=>{const $=i.find(C=>C.id===L.id),G=[L.name,L.description,L.tier,$?.name,$?.description].some(C=>C?.toLowerCase().includes(z))?L.examples:L.examples.filter(C=>{const N=$?.examples.find(X=>X.id===C.id);return[C.name,C.description,C.id,N?.name,N?.description].some(X=>X?.toLowerCase().includes(z))});return{...L,examples:G}}).filter(L=>L.examples.length>0):E,[z,E,i]),W=B.find(L=>L.id===h)??B[0],I=W?.examples.find(L=>L.id===y)??W?.examples[0],ee=W&&I?W.examples.findIndex(L=>L.id===I.id):0,oe=W&&I?W.examples[(ee-1+W.examples.length)%W.examples.length]:void 0,O=W&&I?W.examples[(ee+1)%W.examples.length]:void 0,U=E.reduce((L,$)=>L+$.examples.length,0),Z=B.reduce((L,$)=>L+$.examples.length,0),re=k.useMemo(()=>e.map(L=>({label:n(`themes.${L.id}.name`,{defaultValue:L.name}),value:L.id,description:n(`themes.${L.id}.description`,{defaultValue:L.type==="light"?n("themes.lightDescription"):n("themes.darkDescription")})})),[n,e]),se=k.useMemo(()=>r.map(L=>({label:L.nativeName,value:L.id,description:L.englishName})),[r]);De.useEffect(()=>{!W||!I||(W.id!==h&&f(W.id),I.id!==y&&v(I.id))},[W,I,h,y]);const pe=L=>{f(L.id),v(L.examples[0]?.id??"")},fe=(L,$)=>{f(L),v($)},we=L=>{const $=L==="previous"?oe:O;$&&v($.id)};return l.jsxs("div",{className:"preview-app",children:[l.jsxs("header",{className:"preview-header",children:[l.jsxs("div",{className:"preview-brand",children:[l.jsx("span",{className:"preview-brand__mark",children:l.jsx(ki,{size:20,"aria-hidden":"true"})}),l.jsxs("div",{className:"preview-brand__copy",children:[l.jsx("h1",{children:"Sparo"}),l.jsx("span",{children:n("header.designSystem")})]}),l.jsx("span",{className:"preview-version",children:"v0.1"})]}),l.jsxs("div",{className:"preview-header-actions",children:[l.jsxs("div",{className:"preview-theme-selector preview-language-selector",children:[l.jsxs("span",{className:"preview-theme-selector__label",children:[l.jsx(EZ,{size:14,"aria-hidden":"true"}),n("header.previewLanguage")]}),l.jsx(to,{className:"preview-theme-selector__select-control preview-language-selector__select-control",size:"small",label:n("header.previewLanguage"),value:c,options:se,onChange:L=>{if(Array.isArray(L))return;const $=r.find(te=>te.id===String(L))?.id;$&&s.changeLanguage($)},placement:"bottom",dropdownAlign:"end"})]}),l.jsxs("div",{className:"preview-theme-selector",children:[l.jsxs("span",{className:"preview-theme-selector__label",children:[l.jsx(gX,{size:14,"aria-hidden":"true"}),n("header.previewTheme")]}),l.jsx(to,{className:"preview-theme-selector__select-control",size:"small",label:n("header.previewTheme"),value:u??"",options:re,onChange:L=>{Array.isArray(L)||m(String(L))},disabled:e.length===0,placement:"bottom",dropdownAlign:"end"})]})]})]}),l.jsxs("div",{className:"preview-container",children:[l.jsxs("aside",{className:`preview-sidebar ${b?"preview-sidebar--collapsed":""}`,children:[l.jsxs("div",{className:"preview-sidebar-header",children:[l.jsxs("div",{className:"preview-sidebar-heading",children:[l.jsx("span",{className:"preview-sidebar-title",children:n("sidebar.library")}),l.jsx("span",{className:"preview-sidebar-total",children:U})]}),l.jsx(ze,{className:"preview-sidebar-toggle",size:"small",variant:"ghost",onClick:()=>S(L=>!L),"aria-label":n(b?"sidebar.expandNavigation":"sidebar.collapseNavigation"),tooltip:n(b?"sidebar.expandNavigation":"sidebar.collapseNavigation"),children:l.jsx("span",{className:`preview-sidebar-toggle__icon ${b?"is-collapsed":""}`,children:l.jsx(qZ,{size:14,"aria-hidden":"true"})})})]}),l.jsx("div",{className:"preview-sidebar-search",children:l.jsx(Ri,{ref:_,size:"small",value:A,onChange:F,placeholder:n("sidebar.searchPlaceholder"),inputAriaLabel:n("sidebar.searchAriaLabel"),ariaControls:"preview-library-navigation",suffixContent:l.jsx("kbd",{children:"⌘K"})})}),l.jsx("nav",{id:"preview-library-navigation",className:"preview-nav","aria-label":n("sidebar.navigationAriaLabel"),children:B.map(L=>{const $=W?.id===L.id||!!z;return l.jsxs("section",{className:`category-section ${$?"category-section--open":""}`,children:[l.jsxs("button",{className:`category-button ${W?.id===L.id?"active":""}`,onClick:()=>pe(L),title:L.name,"aria-label":L.name,"aria-expanded":$,children:[l.jsx("span",{className:"category-button__icon",children:l.jsx(Ene,{category:L})}),l.jsx("span",{className:"category-name",children:L.name}),l.jsx("span",{className:"example-count",children:L.examples.length})]}),$&&l.jsx("div",{className:"category-examples","aria-label":n("sidebar.categoryExamplesAriaLabel",{category:L.name}),children:L.examples.map(te=>l.jsx("button",{className:`category-example-button ${I?.id===te.id?"active":""}`,onClick:()=>fe(L.id,te.id),title:te.description,children:l.jsx("span",{children:te.name})},te.id))})]},L.id)})}),z&&Z===0&&l.jsxs("div",{className:"preview-sidebar-empty",role:"status",children:[l.jsx("strong",{children:n("empty.noMatches")}),l.jsx("span",{children:n("empty.searchSuggestion")})]}),!b&&l.jsxs("div",{className:"preview-sidebar-footer",children:[l.jsx("span",{children:n("sidebar.shown",{count:Z})}),l.jsx("span",{children:n("sidebar.searchShortcut")})]})]}),l.jsx("main",{className:"preview-main",children:W&&I&&oe&&O?l.jsx(Mne,{category:W,example:I,index:ee,total:W.examples.length,previousExample:oe,nextExample:O,onPrevious:()=>we("previous"),onNext:()=>we("next")}):l.jsxs("div",{className:"empty-state",children:[l.jsx("strong",{children:n("empty.noPreview")}),l.jsx("p",{children:n("empty.previewSuggestion")})]})})]})]})};qy.createRoot(document.getElementById("root")).render(l.jsx(De.StrictMode,{children:new URLSearchParams(window.location.search).get("qa")==="compact-tool-card"?l.jsx(ane,{}):l.jsx(zg,{i18n:ar.getI18nInstance(),children:l.jsx(Lne,{})})}));export{hJ as A,Une as F,Xt as _,V as a,J as b,ft as c,zne as d,_i as e,zt as f,$ne as g,One as h,ms as i,md as j,Hne as s,Wne as t,Bne as w}; diff --git a/src/web-ui/dist-preview/preview.html b/src/web-ui/dist-preview/preview.html new file mode 100644 index 00000000..fca8a643 --- /dev/null +++ b/src/web-ui/dist-preview/preview.html @@ -0,0 +1,14 @@ + + + + + + + Sparo OS Design System Preview + + + + +
+ + diff --git a/src/web-ui/src/app/agentic-os/work/navigation/openWork.test.ts b/src/web-ui/src/app/agentic-os/work/navigation/openWork.test.ts index a265c1ce..ac024e01 100644 --- a/src/web-ui/src/app/agentic-os/work/navigation/openWork.test.ts +++ b/src/web-ui/src/app/agentic-os/work/navigation/openWork.test.ts @@ -9,6 +9,7 @@ import { cancelPendingSessionNavigation, commitPendingSessionNavigation, } from '@/app/navigation/navigationController'; +import { useWorkspaceSurfaceStore } from '@/app/navigation/workspaceSurfaceStore'; const navigationMock = vi.hoisted(() => ({ epoch: 0, @@ -100,6 +101,7 @@ describe('openWork navigation', () => { beforeEach(() => { resetWorkDockStore(); navigationMock.epoch = 0; + useWorkspaceSurfaceStore.setState({ surfaceContext: null }); vi.mocked(openWorkspaceScene).mockClear(); vi.mocked(openMainSession).mockReset().mockResolvedValue('opened'); vi.mocked(openProductAppRuntimeForWorkSurface).mockReset().mockResolvedValue(undefined); @@ -203,6 +205,18 @@ describe('openWork navigation', () => { expect(cancelPendingSessionNavigation).toHaveBeenCalledWith(1); }); + it('does not reopen a Work that already owns the active surface', async () => { + useWorkspaceSurfaceStore.setState({ + surfaceContext: { kind: 'work', workId: 'work-active' }, + }); + + await openWork(appWork('work-active', [applicationSurface])); + + expect(navigationMock.prepareProductAppWork).not.toHaveBeenCalled(); + expect(openProductAppRuntimeForWorkSurface).not.toHaveBeenCalled(); + expect(commitPendingSessionNavigation).not.toHaveBeenCalled(); + }); + it('invalidates an older Work preparation when a newer Work is selected', async () => { const guards = new Map boolean>(); vi.mocked(openProductAppRuntimeForWorkSurface).mockImplementation(async (request, options) => { diff --git a/src/web-ui/src/app/agentic-os/work/navigation/openWork.ts b/src/web-ui/src/app/agentic-os/work/navigation/openWork.ts index 14414693..d9a7b2ad 100644 --- a/src/web-ui/src/app/agentic-os/work/navigation/openWork.ts +++ b/src/web-ui/src/app/agentic-os/work/navigation/openWork.ts @@ -25,6 +25,7 @@ import { useThemeStore } from '@/infrastructure/theme'; import { productAppRuntimeAPI, type ProductAppWorkCompatibility } from '@/infrastructure/api/service-api/ProductAppRuntimeAPI'; import { i18nService } from '@/infrastructure/i18n'; import { notificationService } from '@/shared/notification-system'; +import { useWorkspaceSurfaceStore } from '@/app/navigation/workspaceSurfaceStore'; interface PendingWorkOpen { intent: number; @@ -183,15 +184,21 @@ async function performOpenWork( } export async function openWork(work: WorkRecord): Promise { - const intent = ++workOpenIntent; const existing = pendingWorkOpens.get(work.id); if (existing && existing.navigationEpoch === getNavigationEpoch()) { // Re-selecting the same in-flight Work joins its preparation instead of // starting another catalog/runtime resolution chain. + const intent = ++workOpenIntent; existing.intent = intent; return existing.promise; } + const activeContext = useWorkspaceSurfaceStore.getState().surfaceContext; + if (activeContext?.kind === 'work' && activeContext.workId === work.id) { + return; + } + + const intent = ++workOpenIntent; const navigationEpoch = beginNavigationIntent(); const pending: PendingWorkOpen = { intent, diff --git a/src/web-ui/src/app/auxiliary-surface/AuxiliarySurfaceCoordinator.tsx b/src/web-ui/src/app/auxiliary-surface/AuxiliarySurfaceCoordinator.tsx new file mode 100644 index 00000000..a6028f30 --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/AuxiliarySurfaceCoordinator.tsx @@ -0,0 +1,145 @@ +import { useEffect, useMemo } from 'react'; +import { useCanvasStore } from '@/app/components/panels/content-canvas'; +import { + selectFocusedSessionId, + useWorkspaceSurfaceStore, +} from '@/app/navigation/workspaceSurfaceStore'; +import { useProductAppRuntimeStore } from '@/app/scenes/apps/product-app-runtime/productAppRuntimeStore'; +import { useSessionProfile } from '@/app/session-profiles'; +import { useWorkStore } from '@/app/agentic-os/work/data/workStore'; +import { isSessionTranscriptLoading } from '@/flow_chat/domain/sessionLoadPhase'; +import { useActiveSession } from '@/flow_chat/store/modernFlowChatStore'; +import { + appScopeFromWorkScope, + type AppScope, +} from '@/shared/types/app-scope'; +import { createLogger } from '@/shared/utils/logger'; +import { useAuxiliarySurfaceStore } from './auxiliarySurfaceStore'; +import { openAuxiliaryItem } from './controller'; + +const log = createLogger('AuxiliarySurfaceCoordinator'); + +function workSessionScopeToAppScope( + sessionId: string | undefined, + works: ReturnType['works'], +): AppScope | undefined { + if (!sessionId) return undefined; + const work = works.find(candidate => + candidate.surfaces.some(surface => + (surface.kind === 'work_session' || surface.kind === 'agent_session') + && surface.sessionId === sessionId + ), + ); + return work ? appScopeFromWorkScope(work.scope, work.workspacePath) : undefined; +} + +/** + * Reconciles profile policy and live content for the active session host. + * It does not own navigation and never mutates an inactive host. + */ +export function AuxiliarySurfaceCoordinator(): null { + const { profile } = useSessionProfile(); + const focusedSessionId = useWorkspaceSurfaceStore(selectFocusedSessionId); + const activeSession = useActiveSession(); + const works = useWorkStore(state => state.works); + const activeHostKey = useAuxiliarySurfaceStore(state => state.activeHostKey); + const activeHostState = useAuxiliarySurfaceStore(state => ( + state.activeHostKey ? state.hosts[state.activeHostKey] : undefined + )); + const configureHost = useAuxiliarySurfaceStore(state => state.configureHost); + const reconcileItems = useAuxiliarySurfaceStore(state => state.reconcileItems); + const markProfileInitialized = useAuxiliarySurfaceStore( + state => state.markProfileInitialized, + ); + const visibleItemCount = useCanvasStore(state => ( + [state.primaryGroup, state.secondaryGroup, state.tertiaryGroup] + .flatMap(group => group.tabs) + .filter(tab => tab.isHidden !== true) + .length + )); + + const runtimeAppId = useProductAppRuntimeStore(state => ( + activeSession?.sessionId + ? state.sessionAppIds[activeSession.sessionId] + : undefined + )); + const profileExtra = useMemo | null>(() => { + if (!activeSession || activeSession.sessionId !== focusedSessionId) return null; + const binding = activeSession.customMetadata?.agentSessionBinding; + const subjectData = binding?.surface?.data; + const boundDraftAppId = + binding?.subject.kind === 'builder-draft' + && subjectData + && typeof subjectData.appId === 'string' + ? subjectData.appId + : undefined; + return { + appId: boundDraftAppId ?? runtimeAppId, + tabTitle: 'App Builder', + agentSessionBinding: binding, + scope: binding?.scope ?? workSessionScopeToAppScope(activeSession.sessionId, works), + productAppRuntime: activeSession.customMetadata?.productAppRuntime, + customMetadata: activeSession.customMetadata, + }; + }, [activeSession, focusedSessionId, runtimeAppId, works]); + + useEffect(() => { + if (!activeHostKey || !focusedSessionId) return; + configureHost(activeHostKey, profile.id, profile.auxiliarySurface.defaultVisibility); + }, [ + activeHostKey, + configureHost, + focusedSessionId, + profile.id, + profile.auxiliarySurface.defaultVisibility, + ]); + + useEffect(() => { + if (!activeHostKey) return; + reconcileItems(activeHostKey, visibleItemCount); + }, [activeHostKey, reconcileItems, visibleItemCount]); + + useEffect(() => { + if ( + !activeHostKey + || !activeHostState + || !activeSession + || activeSession.sessionId !== focusedSessionId + || isSessionTranscriptLoading({ loadPhase: activeSession.loadPhase }) + || !profile.auxiliarySurface.initialize + || activeHostState.initializedProfileIds.includes(profile.id) + || !profileExtra + ) { + return; + } + + const result = profile.auxiliarySurface.initialize(activeSession.sessionId, profileExtra); + if (!result) return; + const items = Array.isArray(result) ? result : [result]; + if (items.length === 0) return; + + log.debug('Initializing profile auxiliary items', { + hostKey: activeHostKey, + profileId: profile.id, + itemTypes: items.map(item => item.type), + }); + items.forEach(item => { + openAuxiliaryItem({ + hostKey: activeHostKey, + item, + reveal: 'policy', + }); + }); + markProfileInitialized(activeHostKey, profile.id); + }, [ + activeHostKey, + activeHostState, + activeSession, + focusedSessionId, + markProfileInitialized, + profile, + profileExtra, + ]); + + return null; +} diff --git a/src/web-ui/src/app/auxiliary-surface/auxiliarySurface.test.ts b/src/web-ui/src/app/auxiliary-surface/auxiliarySurface.test.ts new file mode 100644 index 00000000..f1275d75 --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/auxiliarySurface.test.ts @@ -0,0 +1,148 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { + activateAgentCanvasHost, + removeAgentCanvasHost, + useAgentCanvasStore, +} from '@/app/components/panels/content-canvas/stores'; +import { createAgenticOsHomeSurface } from '@/app/navigation/workspaceSurfaceTypes'; +import { useWorkspaceSurfaceStore } from '@/app/navigation/workspaceSurfaceStore'; +import { useAuxiliarySurfaceStore } from './auxiliarySurfaceStore'; +import { openAuxiliaryItem } from './controller'; +import { homeAuxiliaryHostKey, sessionAuxiliaryHostKey } from './host'; + +const sessionAHost = sessionAuxiliaryHostKey('session-a'); +const sessionBHost = sessionAuxiliaryHostKey('session-b'); +const homeHost = homeAuxiliaryHostKey('os-home'); +const testHosts = [sessionAHost, sessionBHost, homeHost] as const; + +function visibleTabTitles(): string[] { + return useAgentCanvasStore.getState().getAllTabs() + .filter(tab => tab.isHidden !== true) + .map(tab => tab.title); +} + +function resetState(): void { + testHosts.forEach(removeAgentCanvasHost); + activateAgentCanvasHost(null); + useAgentCanvasStore.getState().reset(); + useAuxiliarySurfaceStore.setState({ + activeHostKey: null, + hosts: {}, + }); + useWorkspaceSurfaceStore.setState({ + activeSurface: createAgenticOsHomeSurface(), + previousSurface: null, + currentOsSessionId: null, + sceneHistory: [], + surfaceContext: null, + }); +} + +describe('auxiliary surface lifecycle', () => { + beforeEach(resetState); + + it('does not carry a session workbench into Home when returning', () => { + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-a', + }); + openAuxiliaryItem({ + hostKey: sessionAHost, + item: { + type: 'product-app-runtime', + title: 'Product App', + duplicateCheckKey: 'product-app:session-a', + }, + }); + + expect(visibleTabTitles()).toEqual(['Product App']); + expect(useAuxiliarySurfaceStore.getState().hosts[sessionAHost]?.presentation) + .toBe('docked'); + + useWorkspaceSurfaceStore.getState().returnHome('os-home'); + + expect(useAuxiliarySurfaceStore.getState().activeHostKey).toBe(homeHost); + expect(visibleTabTitles()).toEqual([]); + expect(useAuxiliarySurfaceStore.getState().hosts[homeHost]?.presentation) + .toBe('closed'); + + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-a', + }); + + expect(visibleTabTitles()).toEqual(['Product App']); + expect(useAuxiliarySurfaceStore.getState().hosts[sessionAHost]?.presentation) + .toBe('docked'); + }); + + it('queues background-host items without changing the active surface', () => { + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-a', + }); + openAuxiliaryItem({ + hostKey: sessionBHost, + item: { + type: 'code-editor', + title: 'Background file', + duplicateCheckKey: 'file:b', + }, + }); + + expect(visibleTabTitles()).toEqual([]); + expect(useAuxiliarySurfaceStore.getState().hosts[sessionAHost]?.presentation) + .toBe('closed'); + + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-b', + }); + + expect(visibleTabTitles()).toEqual(['Background file']); + expect(useAuxiliarySurfaceStore.getState().hosts[sessionBHost]?.presentation) + .toBe('docked'); + }); + + it('keeps a user-closed host closed when profile policy reconciles again', () => { + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-a', + }); + const store = useAuxiliarySurfaceStore.getState(); + store.configureHost(sessionAHost, 'product-app-runtime', 'visible'); + openAuxiliaryItem({ + hostKey: sessionAHost, + item: { + type: 'product-app-runtime', + title: 'Product App', + duplicateCheckKey: 'product-app:session-a', + }, + reveal: 'policy', + }); + store.reconcileItems(sessionAHost, 1); + expect(useAuxiliarySurfaceStore.getState().hosts[sessionAHost]?.presentation) + .toBe('docked'); + + useAuxiliarySurfaceStore.getState().collapse(sessionAHost, 'user'); + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-b', + }); + useWorkspaceSurfaceStore.getState().openSurface({ + kind: 'session', + sessionId: 'session-a', + }); + useAuxiliarySurfaceStore.getState().configureHost( + sessionAHost, + 'product-app-runtime', + 'visible', + ); + useAuxiliarySurfaceStore.getState().reconcileItems(sessionAHost, 1); + + expect(useAuxiliarySurfaceStore.getState().hosts[sessionAHost]).toMatchObject({ + presentation: 'closed', + userDisposition: 'closed', + }); + }); +}); diff --git a/src/web-ui/src/app/auxiliary-surface/auxiliarySurfaceStore.ts b/src/web-ui/src/app/auxiliary-surface/auxiliarySurfaceStore.ts new file mode 100644 index 00000000..7c8152a0 --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/auxiliarySurfaceStore.ts @@ -0,0 +1,180 @@ +import { create } from 'zustand'; +import { + AUXILIARY_SURFACE_CONFIG, + STORAGE_KEYS, + loadPanelWidth, + savePanelWidth, +} from '@/app/layout/panelConfig'; +import type { + AuxiliarySurfaceDefaultVisibility, + AuxiliarySurfaceHostKey, + AuxiliarySurfaceHostState, + AuxiliarySurfacePresentation, +} from './types'; + +const createHostState = (): AuxiliarySurfaceHostState => ({ + presentation: 'closed', + userDisposition: 'default', + defaultVisibility: 'collapsed', + configuredProfileId: null, + entryPolicyApplied: false, + initializedProfileIds: [], +}); + +interface AuxiliarySurfaceState { + activeHostKey: AuxiliarySurfaceHostKey | null; + width: number; + hosts: Record; + activateHost: (hostKey: AuxiliarySurfaceHostKey | null) => void; + configureHost: ( + hostKey: AuxiliarySurfaceHostKey, + profileId: string, + defaultVisibility: AuxiliarySurfaceDefaultVisibility, + ) => void; + reconcileItems: (hostKey: AuxiliarySurfaceHostKey, visibleItemCount: number) => void; + reveal: ( + hostKey: AuxiliarySurfaceHostKey, + source: 'user' | 'explicit' | 'policy', + presentation?: Exclude, + ) => void; + collapse: (hostKey: AuxiliarySurfaceHostKey, source: 'user' | 'empty') => void; + setWidth: (width: number) => void; + markProfileInitialized: (hostKey: AuxiliarySurfaceHostKey, profileId: string) => void; + forgetHosts: (hostKeys: readonly AuxiliarySurfaceHostKey[]) => void; +} + +function updateHost( + hosts: Record, + hostKey: AuxiliarySurfaceHostKey, + update: (state: AuxiliarySurfaceHostState) => AuxiliarySurfaceHostState, +): Record { + const current = hosts[hostKey] ?? createHostState(); + return { ...hosts, [hostKey]: update(current) }; +} + +export const useAuxiliarySurfaceStore = create((set) => ({ + activeHostKey: null, + width: loadPanelWidth( + STORAGE_KEYS.AUXILIARY_SURFACE_WIDTH, + AUXILIARY_SURFACE_CONFIG.COMFORTABLE_DEFAULT, + ), + hosts: {}, + + activateHost: (hostKey) => { + set(state => ({ + activeHostKey: hostKey, + hosts: hostKey && !state.hosts[hostKey] + ? { ...state.hosts, [hostKey]: createHostState() } + : state.hosts, + })); + }, + + configureHost: (hostKey, profileId, defaultVisibility) => { + set(state => ({ + hosts: updateHost(state.hosts, hostKey, current => { + if ( + current.configuredProfileId === profileId + && current.defaultVisibility === defaultVisibility + ) { + return current; + } + return { + ...current, + configuredProfileId: profileId, + defaultVisibility, + entryPolicyApplied: false, + }; + }), + })); + }, + + reconcileItems: (hostKey, visibleItemCount) => { + set(state => ({ + hosts: updateHost(state.hosts, hostKey, current => { + if (visibleItemCount === 0) { + return current.presentation === 'closed' + ? current + : { ...current, presentation: 'closed' }; + } + if (current.entryPolicyApplied) return current; + + const presentation = + current.userDisposition === 'closed' + ? 'closed' + : current.userDisposition === 'opened' || current.defaultVisibility === 'visible' + ? 'docked' + : 'closed'; + return { + ...current, + presentation, + entryPolicyApplied: true, + }; + }), + })); + }, + + reveal: (hostKey, source, presentation = 'docked') => { + set(state => ({ + hosts: updateHost(state.hosts, hostKey, current => ({ + ...current, + presentation, + userDisposition: + source === 'user' || source === 'explicit' + ? 'opened' + : current.userDisposition, + entryPolicyApplied: source === 'policy' ? true : current.entryPolicyApplied, + })), + })); + }, + + collapse: (hostKey, source) => { + set(state => ({ + hosts: updateHost(state.hosts, hostKey, current => ({ + ...current, + presentation: 'closed', + userDisposition: source === 'user' ? 'closed' : current.userDisposition, + })), + })); + }, + + setWidth: (width) => { + savePanelWidth(STORAGE_KEYS.AUXILIARY_SURFACE_WIDTH, width); + set({ width }); + }, + + markProfileInitialized: (hostKey, profileId) => { + set(state => ({ + hosts: updateHost(state.hosts, hostKey, current => ( + current.initializedProfileIds.includes(profileId) + ? current + : { + ...current, + initializedProfileIds: [...current.initializedProfileIds, profileId], + } + )), + })); + }, + + forgetHosts: (hostKeys) => { + if (hostKeys.length === 0) return; + set(state => { + const removed = new Set(hostKeys); + const hosts = Object.fromEntries( + Object.entries(state.hosts).filter(([key]) => !removed.has(key)), + ); + return { + hosts, + activeHostKey: + state.activeHostKey && removed.has(state.activeHostKey) + ? null + : state.activeHostKey, + }; + }); + }, +})); + +export function selectActiveAuxiliaryHostState( + state: AuxiliarySurfaceState, +): AuxiliarySurfaceHostState | null { + return state.activeHostKey ? state.hosts[state.activeHostKey] ?? null : null; +} diff --git a/src/web-ui/src/app/auxiliary-surface/controller.ts b/src/web-ui/src/app/auxiliary-surface/controller.ts new file mode 100644 index 00000000..56f912f5 --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/controller.ts @@ -0,0 +1,121 @@ +import { + getActiveAgentCanvasHostKey, + useAgentCanvasStore, +} from '@/app/components/panels/content-canvas/stores'; +import { openCanvasItemInStore } from '@/app/components/panels/content-canvas/openCanvasItem'; +import { + AUXILIARY_SURFACE_CONFIG, + getModeWidth, + type PanelDisplayMode, +} from '@/app/layout/panelConfig'; +import { createLogger } from '@/shared/utils/logger'; +import { useAuxiliarySurfaceStore } from './auxiliarySurfaceStore'; +import type { + AuxiliaryItemDescriptor, + AuxiliarySurfaceHostKey, + OpenAuxiliaryItemCommand, +} from './types'; + +const log = createLogger('AuxiliarySurface'); +const pendingCommands = new Map(); + +function duplicateKey(item: AuxiliaryItemDescriptor): string | undefined { + return item.duplicateCheckKey + ?? (typeof item.metadata?.duplicateCheckKey === 'string' + ? item.metadata.duplicateCheckKey + : undefined); +} + +function openInLiveCanvas(command: OpenAuxiliaryItemCommand): void { + const { hostKey, item } = command; + const store = useAgentCanvasStore.getState(); + openCanvasItemInStore(store, item, { auxiliaryHostKey: hostKey }); +} + +function reveal(command: OpenAuxiliaryItemCommand): void { + const revealMode = command.reveal ?? 'explicit'; + if (revealMode === 'explicit') { + useAuxiliarySurfaceStore.getState().reveal(command.hostKey, 'explicit'); + } +} + +function enqueue(command: OpenAuxiliaryItemCommand): void { + const queue = pendingCommands.get(command.hostKey) ?? []; + const key = duplicateKey(command.item); + if (key) { + const index = queue.findIndex(item => duplicateKey(item.item) === key); + if (index >= 0) { + queue[index] = command; + pendingCommands.set(command.hostKey, queue); + return; + } + } + pendingCommands.set(command.hostKey, [...queue, command]); +} + +export function openAuxiliaryItem(command: OpenAuxiliaryItemCommand): void { + if (getActiveAgentCanvasHostKey() !== command.hostKey) { + enqueue(command); + log.debug('Queued auxiliary item for inactive host', { + hostKey: command.hostKey, + type: command.item.type, + }); + return; + } + + openInLiveCanvas(command); + reveal(command); +} + +export function openActiveAuxiliaryItem( + item: AuxiliaryItemDescriptor, + revealMode: OpenAuxiliaryItemCommand['reveal'] = 'explicit', +): boolean { + const hostKey = useAuxiliarySurfaceStore.getState().activeHostKey; + if (!hostKey) return false; + openAuxiliaryItem({ hostKey, item, reveal: revealMode }); + return true; +} + +export function flushAuxiliaryItems(hostKey: AuxiliarySurfaceHostKey): void { + const queue = pendingCommands.get(hostKey); + if (!queue?.length || getActiveAgentCanvasHostKey() !== hostKey) return; + pendingCommands.delete(hostKey); + queue.forEach(command => { + openInLiveCanvas(command); + reveal(command); + }); +} + +export function forgetAuxiliaryCommands(hostKeys: readonly AuxiliarySurfaceHostKey[]): void { + hostKeys.forEach(hostKey => pendingCommands.delete(hostKey)); +} + +export function toggleActiveAuxiliarySurface(): boolean { + const store = useAuxiliarySurfaceStore.getState(); + const hostKey = store.activeHostKey; + if (!hostKey) return false; + const presentation = store.hosts[hostKey]?.presentation ?? 'closed'; + if (presentation === 'closed') { + store.reveal(hostKey, 'user'); + } else { + store.collapse(hostKey, 'user'); + } + return true; +} + +export function collapseActiveAuxiliarySurface(): boolean { + const store = useAuxiliarySurfaceStore.getState(); + if (!store.activeHostKey) return false; + store.collapse(store.activeHostKey, 'user'); + return true; +} + +export function resizeActiveAuxiliarySurface( + mode: Exclude, +): boolean { + const store = useAuxiliarySurfaceStore.getState(); + if (!store.activeHostKey) return false; + store.setWidth(getModeWidth(mode, AUXILIARY_SURFACE_CONFIG)); + return true; +} diff --git a/src/web-ui/src/app/auxiliary-surface/host.ts b/src/web-ui/src/app/auxiliary-surface/host.ts new file mode 100644 index 00000000..51476bad --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/host.ts @@ -0,0 +1,27 @@ +import type { WorkspaceSurface } from '@/app/navigation/workspaceSurfaceTypes'; +import type { AuxiliarySurfaceHostKey } from './types'; + +export function homeAuxiliaryHostKey(sessionId: string): AuxiliarySurfaceHostKey { + return `home:${sessionId}`; +} + +export function sessionAuxiliaryHostKey(sessionId: string): AuxiliarySurfaceHostKey { + return `session:${sessionId}`; +} + +export function resolveAuxiliaryHostKey( + surface: WorkspaceSurface, + currentOsSessionId: string | null, +): AuxiliarySurfaceHostKey | null { + if (surface.kind === 'session') { + return sessionAuxiliaryHostKey(surface.sessionId); + } + if (surface.kind === 'agentic-os-home' && currentOsSessionId) { + return homeAuxiliaryHostKey(currentOsSessionId); + } + return null; +} + +export function auxiliaryHostKeysForSession(sessionId: string): AuxiliarySurfaceHostKey[] { + return [homeAuxiliaryHostKey(sessionId), sessionAuxiliaryHostKey(sessionId)]; +} diff --git a/src/web-ui/src/app/auxiliary-surface/index.ts b/src/web-ui/src/app/auxiliary-surface/index.ts new file mode 100644 index 00000000..a63669ac --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/index.ts @@ -0,0 +1,33 @@ +export { + selectActiveAuxiliaryHostState, + useAuxiliarySurfaceStore, +} from './auxiliarySurfaceStore'; +export { AuxiliarySurfaceCoordinator } from './AuxiliarySurfaceCoordinator'; +export { + collapseActiveAuxiliarySurface, + flushAuxiliaryItems, + openActiveAuxiliaryItem, + openAuxiliaryItem, + resizeActiveAuxiliarySurface, + toggleActiveAuxiliarySurface, +} from './controller'; +export { + auxiliaryHostKeysForSession, + homeAuxiliaryHostKey, + resolveAuxiliaryHostKey, + sessionAuxiliaryHostKey, +} from './host'; +export { + forgetSessionAuxiliarySurfaces, + synchronizeAuxiliarySurface, +} from './navigationSync'; +export type { + AuxiliaryItemDescriptor, + AuxiliarySurfaceDefaultVisibility, + AuxiliarySurfaceHostKey, + AuxiliarySurfaceHostState, + AuxiliarySurfacePresentation, + AuxiliarySurfaceReveal, + AuxiliarySurfaceUserDisposition, + OpenAuxiliaryItemCommand, +} from './types'; diff --git a/src/web-ui/src/app/auxiliary-surface/navigationSync.ts b/src/web-ui/src/app/auxiliary-surface/navigationSync.ts new file mode 100644 index 00000000..2eacc717 --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/navigationSync.ts @@ -0,0 +1,25 @@ +import { + activateAgentCanvasHost, + removeAgentCanvasHost, +} from '@/app/components/panels/content-canvas/stores'; +import type { WorkspaceSurface } from '@/app/navigation/workspaceSurfaceTypes'; +import { useAuxiliarySurfaceStore } from './auxiliarySurfaceStore'; +import { flushAuxiliaryItems, forgetAuxiliaryCommands } from './controller'; +import { auxiliaryHostKeysForSession, resolveAuxiliaryHostKey } from './host'; + +export function synchronizeAuxiliarySurface( + surface: WorkspaceSurface, + currentOsSessionId: string | null, +): void { + const hostKey = resolveAuxiliaryHostKey(surface, currentOsSessionId); + activateAgentCanvasHost(hostKey); + useAuxiliarySurfaceStore.getState().activateHost(hostKey); + if (hostKey) flushAuxiliaryItems(hostKey); +} + +export function forgetSessionAuxiliarySurfaces(sessionIds: readonly string[]): void { + const hostKeys = sessionIds.flatMap(auxiliaryHostKeysForSession); + hostKeys.forEach(removeAgentCanvasHost); + forgetAuxiliaryCommands(hostKeys); + useAuxiliarySurfaceStore.getState().forgetHosts(hostKeys); +} diff --git a/src/web-ui/src/app/auxiliary-surface/types.ts b/src/web-ui/src/app/auxiliary-surface/types.ts new file mode 100644 index 00000000..1c0dfc7e --- /dev/null +++ b/src/web-ui/src/app/auxiliary-surface/types.ts @@ -0,0 +1,24 @@ +import type { CanvasItemDescriptor } from '@/app/components/panels/content-canvas/types'; + +export type AuxiliarySurfaceHostKey = `home:${string}` | `session:${string}`; +export type AuxiliarySurfacePresentation = 'closed' | 'docked'; +export type AuxiliarySurfaceDefaultVisibility = 'collapsed' | 'visible'; +export type AuxiliarySurfaceUserDisposition = 'default' | 'opened' | 'closed'; +export type AuxiliarySurfaceReveal = 'explicit' | 'policy' | 'preserve'; + +export type AuxiliaryItemDescriptor = CanvasItemDescriptor; + +export interface OpenAuxiliaryItemCommand { + hostKey: AuxiliarySurfaceHostKey; + item: AuxiliaryItemDescriptor; + reveal?: AuxiliarySurfaceReveal; +} + +export interface AuxiliarySurfaceHostState { + presentation: AuxiliarySurfacePresentation; + userDisposition: AuxiliarySurfaceUserDisposition; + defaultVisibility: AuxiliarySurfaceDefaultVisibility; + configuredProfileId: string | null; + entryPolicyApplied: boolean; + initializedProfileIds: readonly string[]; +} diff --git a/src/web-ui/src/app/components/WorkDock/WorkDock.scss b/src/web-ui/src/app/components/WorkDock/WorkDock.scss index 4c04d936..78a8dbac 100644 --- a/src/web-ui/src/app/components/WorkDock/WorkDock.scss +++ b/src/web-ui/src/app/components/WorkDock/WorkDock.scss @@ -962,7 +962,6 @@ padding: 6px var(--work-dock-inline-pad); flex-shrink: 0; min-width: 0; - border-bottom: 1px solid var(--ds-color-border-subtle); box-sizing: border-box; overflow: hidden; } @@ -1045,7 +1044,6 @@ gap: var(--ds-space-1); padding: var(--ds-space-1) var(--work-dock-inline-pad); flex-shrink: 0; - border-top: 1px solid var(--ds-color-border-subtle); } .work-dock__list { diff --git a/src/web-ui/src/app/components/WorkDock/WorkDock.tsx b/src/web-ui/src/app/components/WorkDock/WorkDock.tsx index 2180292f..c8a54072 100644 --- a/src/web-ui/src/app/components/WorkDock/WorkDock.tsx +++ b/src/web-ui/src/app/components/WorkDock/WorkDock.tsx @@ -85,6 +85,7 @@ const WorkDock: React.FC = () => { const [expanded, setExpanded] = useState(readExpandedFromStorage); const [pinned, setPinned] = useState(readPinnedFromStorage); const [surfaceExpanded, setSurfaceExpanded] = useState(false); + const [hoverExpanded, setHoverExpanded] = useState(false); const [listFilterQuery, setListFilterQuery] = useState(''); const [selectedListResultIndex, setSelectedListResultIndex] = useState(0); const [listResultCount, setListResultCount] = useState(0); @@ -130,6 +131,7 @@ const WorkDock: React.FC = () => { }, []); const openWorkDock = useCallback(() => { + setHoverExpanded(false); if (activeSurface.kind === 'scene') { setSurfaceExpanded(true); return; @@ -139,6 +141,7 @@ const WorkDock: React.FC = () => { }, [activeSurface.kind]); const closeWorkDock = useCallback(() => { + setHoverExpanded(false); if (activeSurface.kind === 'scene') { setSurfaceExpanded(false); return; @@ -148,6 +151,7 @@ const WorkDock: React.FC = () => { }, [activeSurface.kind]); const toggleWorkDock = useCallback(() => { + setHoverExpanded(false); if (activeSurface.kind === 'scene') { setSurfaceExpanded((value) => !value); return; @@ -175,6 +179,10 @@ const WorkDock: React.FC = () => { if (!surfaceExpanded) setListFilterQuery(''); }, [surfaceExpanded]); + useEffect(() => { + if (!hoverExpanded) setListFilterQuery(''); + }, [hoverExpanded]); + useEffect(() => { setSelectedListResultIndex(0); }, [listFilterQuery]); @@ -204,7 +212,7 @@ const WorkDock: React.FC = () => { const isSessionSurface = activeSurface.kind === 'agentic-os-home' || activeSurface.kind === 'session'; const suppressInWorkCenter = activeSurface.kind === 'scene' && activeSurface.sceneId === 'work-center'; const showExpandedPanel = !suppressInWorkCenter && ( - isSessionSurface ? (expanded || newWorkDialogOpen) : surfaceExpanded + hoverExpanded || (isSessionSurface ? (expanded || newWorkDialogOpen) : surfaceExpanded) ); const liftAboveSurface = activeSurface.kind === 'scene'; const showCollapsedDock = isSessionSurface && !suppressInWorkCenter; @@ -276,6 +284,9 @@ const WorkDock: React.FC = () => { aria-label={t('nav.workDock.label')} data-testid="work-dock" data-sparo-ignore-work-dock-outside + onMouseEnter={showRunningCollapsedDock ? () => setHoverExpanded(true) : undefined} + onMouseLeave={hoverExpanded ? () => setHoverExpanded(false) : undefined} + onFocus={showRunningCollapsedDock ? openWorkDock : undefined} > {showExpandedPanel ? ( <> diff --git a/src/web-ui/src/app/components/WorkspaceFooterActions/WorkspaceFooterActions.scss b/src/web-ui/src/app/components/WorkspaceFooterActions/WorkspaceFooterActions.scss index 2d00c7c7..a8e66296 100644 --- a/src/web-ui/src/app/components/WorkspaceFooterActions/WorkspaceFooterActions.scss +++ b/src/web-ui/src/app/components/WorkspaceFooterActions/WorkspaceFooterActions.scss @@ -353,7 +353,7 @@ &:hover, &:focus-within { - background: var(--ds-color-element-soft, var(--element-bg-soft)); + background: var(--ds-color-element-medium, var(--element-bg-medium)); } &.is-selected, @@ -538,6 +538,10 @@ transform: none; } + &:hover:not(:disabled) { + background: var(--ds-color-element-medium, var(--element-bg-medium)); + } + } .sparo-workspace-hub__unread-dot { diff --git a/src/web-ui/src/app/components/panels/content-canvas/ContentCanvas.tsx b/src/web-ui/src/app/components/panels/content-canvas/ContentCanvas.tsx index 913c20d0..1f72ce5b 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/ContentCanvas.tsx +++ b/src/web-ui/src/app/components/panels/content-canvas/ContentCanvas.tsx @@ -1,6 +1,6 @@ /** * ContentCanvas main container component. - * Core component for the right panel, aggregating submodules. + * Core canvas used by auxiliary and standalone workbench surfaces. */ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; @@ -8,7 +8,7 @@ import { EditorArea } from './editor-area'; import { AnchorZone } from './anchor-zone'; import { EmptyState } from './empty-state'; import { useCanvasStore } from './stores'; -import { useTabLifecycle, useKeyboardShortcuts, usePanelTabCoordinator } from './hooks'; +import { useTabLifecycle, useKeyboardShortcuts } from './hooks'; import type { AnchorPosition } from './types'; import { openMainSession, selectActiveChildSessionTab } from '@/flow_chat/services/childSessionPanels'; import './ContentCanvas.scss'; @@ -25,6 +25,8 @@ export interface ContentCanvasProps { onBeforeClose?: (content: any) => Promise; /** Disable pop-out and panel-close controls (used in panel-view scene) */ disablePopOut?: boolean; + /** Request that the owning host hide this canvas. */ + onRequestClose?: () => void; } export const ContentCanvas: React.FC = ({ @@ -33,6 +35,7 @@ export const ContentCanvas: React.FC = ({ isSceneActive = true, onInteraction, disablePopOut = false, + onRequestClose, }) => { // Store state const { @@ -49,12 +52,6 @@ export const ContentCanvas: React.FC = ({ // Initialize hooks const { handleCloseWithDirtyCheck, handleCloseAllWithDirtyCheck } = useTabLifecycle({ mode }); useKeyboardShortcuts({ enabled: true, handleCloseWithDirtyCheck }); - // Panel/tab state coordinator (auto manage expand/collapse) - const { collapsePanel } = usePanelTabCoordinator({ - autoCollapseOnEmpty: true, - autoExpandOnTabOpen: true, - }); - useEffect(() => { if (mode !== 'agent' || !activeChildSessionTab?.id || !activeChildSessionData?.parentSessionId) { lastSyncedChildSessionTabIdRef.current = null; @@ -94,7 +91,7 @@ export const ContentCanvas: React.FC = ({ const renderContent = () => { // Show empty state when primary group has no visible tabs if (!hasPrimaryVisibleTabs) { - return ; + return ; } return ( diff --git a/src/web-ui/src/app/components/panels/content-canvas/hooks/README.md b/src/web-ui/src/app/components/panels/content-canvas/hooks/README.md deleted file mode 100644 index 9574c6a2..00000000 --- a/src/web-ui/src/app/components/panels/content-canvas/hooks/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# ContentCanvas Hooks - -## usePanelTabCoordinator - -Tab and panel state coordinator that manages synchronized state changes. - -### Features - -1. **Auto-collapse**: collapse the right panel when all tabs are closed -2. **Auto-expand**: expand the right panel when a tab opens -3. **Event listening**: listen to `expand-right-panel` to ensure all open paths expand the panel -4. **State sync**: keep tab and panel state consistent - -### Usage - -```tsx -usePanelTabCoordinator({ - autoCollapseOnEmpty: true, // Auto-collapse when all tabs are closed - autoExpandOnTabOpen: true, // Auto-expand when a tab opens -}); -``` - -### Design principles - -1. **Single responsibility**: coordinate state only, do not replace store methods -2. **Reactive**: listen to tab count changes and respond automatically -3. **Debounced**: use `requestAnimationFrame` to avoid frequent updates -4. **Event-driven**: coordinate with other modules through events diff --git a/src/web-ui/src/app/components/panels/content-canvas/hooks/index.ts b/src/web-ui/src/app/components/panels/content-canvas/hooks/index.ts index 4cc8f815..b370e483 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/hooks/index.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/hooks/index.ts @@ -5,4 +5,3 @@ export { useTabLifecycle } from './useTabLifecycle'; export { useLayoutState } from './useLayoutState'; export { useKeyboardShortcuts } from './useKeyboardShortcuts'; -export { usePanelTabCoordinator } from './usePanelTabCoordinator'; diff --git a/src/web-ui/src/app/components/panels/content-canvas/hooks/usePanelTabCoordinator.ts b/src/web-ui/src/app/components/panels/content-canvas/hooks/usePanelTabCoordinator.ts deleted file mode 100644 index 4ee5eacc..00000000 --- a/src/web-ui/src/app/components/panels/content-canvas/hooks/usePanelTabCoordinator.ts +++ /dev/null @@ -1,433 +0,0 @@ -/** - * usePanelTabCoordinator Hook - * Tab and panel state coordinator. - * - * Responsibilities: - * 1. Watch tab count changes and manage panel expand/collapse - * 2. Auto-open the profile-designated tab when the active session changes - * 3. Close exclusive tab types that belong to a previous profile - * 4. Ensure state consistency and avoid race conditions - */ - -import { useEffect, useLayoutEffect, useRef, useCallback } from 'react'; -import { useCanvasStore } from '../stores'; -import { useAgentCanvasStore } from '../stores'; -import { useApp } from '@/app/hooks/useApp'; -import { useSessionProfile } from '@/app/session-profiles'; -import { useActiveSession } from '@/flow_chat/store/modernFlowChatStore'; -import { isSessionTranscriptLoading } from '@/flow_chat/domain/sessionLoadPhase'; -import { - selectFocusedSessionId, - useWorkspaceSurfaceStore, -} from '@/app/navigation/workspaceSurfaceStore'; -import { useProductAppRuntimeStore } from '@/app/scenes/apps/product-app-runtime/productAppRuntimeStore'; -import { useWorkStore } from '@/app/agentic-os/work/data/workStore'; -import { - appScopeFromWorkScope, - type AppScope, -} from '@/shared/types/app-scope'; -import { TAB_EVENTS } from '../types'; -import { loadPanelWidth, STORAGE_KEYS, RIGHT_PANEL_CONFIG } from '@/app/layout/panelConfig'; -import type { EditorGroupId } from '../types'; -import { createLogger } from '@/shared/utils/logger'; - -const log = createLogger('usePanelTabCoordinator'); - -function workSessionScopeToAppScope( - sessionId: string | undefined, - works: ReturnType['works'] -): AppScope | undefined { - if (!sessionId) return undefined; - const work = works.find((candidate) => - candidate.surfaces.some((surface) => - (surface.kind === 'work_session' || surface.kind === 'agent_session') && - surface.sessionId === sessionId - ) - ); - if (!work) return undefined; - return appScopeFromWorkScope(work.scope, work.workspacePath); -} - -interface UsePanelTabCoordinatorOptions { - /** Auto-collapse when all tabs are closed */ - autoCollapseOnEmpty?: boolean; - /** Auto-expand when a tab opens */ - autoExpandOnTabOpen?: boolean; -} - -/** - * Tab and panel state coordinator. - * - * Design principles: - * 1. Single source of truth: tabs from canvasStore, panels from useApp - * 2. Profile-driven: auto-open/close logic comes from SessionProfile.auxTabs - * 3. Reactive sync: update panel state on tab changes - * 4. Event-driven: coordinate through unified events - */ -export const usePanelTabCoordinator = (options: UsePanelTabCoordinatorOptions = {}) => { - const { - autoCollapseOnEmpty = true, - autoExpandOnTabOpen = true, - } = options; - - const { - primaryGroup, - secondaryGroup, - addTab, - findTabByMetadata, - promoteTab, - tertiaryGroup, - switchToTab, - updateTabContent, - } = useCanvasStore(); - - const { state, toggleRightPanel, updateRightPanelWidth } = useApp(); - const { profile } = useSessionProfile(); - const activeSession = useActiveSession(); - const focusedSessionId = useWorkspaceSurfaceStore(selectFocusedSessionId); - const works = useWorkStore((store) => store.works); - - // Use refs to avoid stale closures and add guards - const rightPanelCollapsedRef = useRef( - state?.layout?.rightPanelCollapsed ?? true - ); - const toggleRightPanelRef = useRef(toggleRightPanel); - const isInitializedRef = useRef(false); - - // Track which session we've already auto-opened a tab for (avoid duplicate opens) - const autoOpenedSessionIdsRef = useRef>(new Set()); - // Track which profile's exclusive tabs we've already cleaned (avoid thrash) - const lastCleanedProfileIdRef = useRef(null); - - // Sync refs - useEffect(() => { - if (state?.layout) { - rightPanelCollapsedRef.current = state.layout.rightPanelCollapsed ?? true; - } - toggleRightPanelRef.current = toggleRightPanel; - if (!isInitializedRef.current) { - isInitializedRef.current = true; - } - }, [state?.layout, toggleRightPanel]); - - // Read the current product app id for App Builder. - const storeBuilderAppId = useProductAppRuntimeStore((s) => - activeSession?.sessionId ? s.sessionAppIds[activeSession.sessionId] : undefined - ); - const agentSessionBinding = activeSession?.customMetadata?.agentSessionBinding; - const activeSessionAppScope = - agentSessionBinding?.scope ?? - workSessionScopeToAppScope(activeSession?.sessionId, works); - const subjectData = agentSessionBinding?.surface?.data; - const boundDraftAppId = agentSessionBinding?.subject.kind === 'builder-draft' && - subjectData && typeof subjectData.appId === 'string' - ? subjectData.appId - : undefined; - const builderAppId = boundDraftAppId ?? storeBuilderAppId; - - /** - * Expand right panel (set width first, then expand to avoid flicker). - */ - const expandPanel = useCallback(() => { - if (rightPanelCollapsedRef.current && toggleRightPanelRef.current && updateRightPanelWidth) { - const persisted = loadPanelWidth( - STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, - RIGHT_PANEL_CONFIG.COMFORTABLE_DEFAULT - ); - const current = state.layout.rightPanelWidth; - const widthToUse = - current >= RIGHT_PANEL_CONFIG.COMPACT_WIDTH ? current : persisted; - updateRightPanelWidth(widthToUse); - - window.dispatchEvent(new CustomEvent('expand-right-panel-immediate', { - detail: { noAnimation: true } - })); - - requestAnimationFrame(() => { - if (toggleRightPanelRef.current) { - toggleRightPanelRef.current(); - } - }); - } - }, [updateRightPanelWidth, state.layout.rightPanelWidth]); - - /** - * Collapse right panel. - */ - const collapsePanel = useCallback(() => { - if (!rightPanelCollapsedRef.current && toggleRightPanelRef.current) { - requestAnimationFrame(() => { - if (toggleRightPanelRef.current) { - toggleRightPanelRef.current(); - } - }); - } - }, []); - - /** - * Close all tabs matching the given exclusive tab types from the agent canvas store. - * Runs up to maxPasses iterations to handle stores that update asynchronously. - */ - const closeExclusiveTabTypes = useCallback((tabTypes: readonly string[]) => { - if (tabTypes.length === 0) return; - const maxPasses = 32; - const groupIds: EditorGroupId[] = ['primary', 'secondary', 'tertiary']; - for (let pass = 0; pass < maxPasses; pass++) { - const store = useAgentCanvasStore.getState() as any; - let closedOne = false; - for (const groupId of groupIds) { - const group = - groupId === 'primary' - ? store.primaryGroup - : groupId === 'secondary' - ? store.secondaryGroup - : store.tertiaryGroup; - const tab = group?.tabs?.find((t: any) => tabTypes.includes(t.content.type)); - if (tab) { - store.closeTab(tab.id, groupId, { forceRemove: true }); - closedOne = true; - break; - } - } - if (!closedOne) return; - } - }, []); - - /** - * Profile-driven auto-open: when active session changes, open the profile's - * designated tab if autoOpen is defined and we haven't done so for this session. - */ - useEffect(() => { - if (!isInitializedRef.current) return; - if (!activeSession?.sessionId) return; - if (!profile.auxTabs.autoOpen) return; - // Historical chat is the foreground resume path. Heavy sidecars (Product - // Apps, Excel, App Builder) start only after the transcript has committed, - // so iframe/runtime boot cannot starve the left conversation's first paint. - if (isSessionTranscriptLoading({ loadPhase: activeSession.loadPhase })) return; - - // Map profile id -> tab title. Keeps the profile free of i18n imports. - const extra: Record = { - appId: builderAppId, - tabTitle: 'App Builder', - agentSessionBinding, - scope: activeSessionAppScope, - productAppRuntime: activeSession.customMetadata?.productAppRuntime, - customMetadata: activeSession.customMetadata, - }; - - const autoOpenResult = profile.auxTabs.autoOpen(activeSession.sessionId, extra); - if (!autoOpenResult) return; - const descriptors = Array.isArray(autoOpenResult) ? autoOpenResult : [autoOpenResult]; - if (descriptors.length === 0) return; - - const hasMissingDescriptor = descriptors.some((descriptor) => { - if (!descriptor.duplicateCheckKey) { - return !autoOpenedSessionIdsRef.current.has(activeSession.sessionId); - } - return !findTabByMetadata({ duplicateCheckKey: descriptor.duplicateCheckKey }); - }); - if (autoOpenedSessionIdsRef.current.has(activeSession.sessionId) && !hasMissingDescriptor) { - return; - } - - autoOpenedSessionIdsRef.current.add(activeSession.sessionId); - - log.debug('Auto-opening profile tab', { - profileId: profile.id, - sessionId: activeSession.sessionId, - tabTypes: descriptors.map(descriptor => descriptor.type), - }); - - descriptors.forEach((descriptor) => { - const content = { - type: descriptor.type, - title: descriptor.title, - data: descriptor.data, - metadata: { - ...descriptor.metadata, - duplicateCheckKey: descriptor.duplicateCheckKey, - }, - }; - - if (descriptor.duplicateCheckKey) { - const existing = findTabByMetadata({ duplicateCheckKey: descriptor.duplicateCheckKey }); - if (existing) { - if (descriptor.replaceExisting) { - updateTabContent(existing.tab.id, existing.groupId, content); - } - switchToTab(existing.tab.id, existing.groupId); - if (existing.tab.state === 'preview') { - promoteTab(existing.tab.id, existing.groupId); - } - return; - } - } - - addTab(content, 'active'); - }); - expandPanel(); - }, [ - activeSession?.customMetadata, - activeSession?.loadPhase, - activeSession?.sessionId, - addTab, - expandPanel, - findTabByMetadata, - profile, - primaryGroup.tabs, - promoteTab, - activeSessionAppScope, - agentSessionBinding, - secondaryGroup.tabs, - builderAppId, - switchToTab, - tertiaryGroup.tabs, - updateTabContent, - ]); - - /** - * Profile-driven exclusive tab cleanup: when the profile changes (user switches - * session type), close tabs that belong exclusively to the previous profile. - */ - useEffect(() => { - if (!isInitializedRef.current) return; - const exclusiveTypes = profile.auxTabs.exclusiveTabTypes; - if (!exclusiveTypes || exclusiveTypes.length === 0) return; - - // Only clean up when we've navigated AWAY from this profile's exclusive tabs - // (i.e., the current profile does NOT own these types). - // We track by profile.id to avoid re-running on every render. - if (lastCleanedProfileIdRef.current === profile.id) return; - - // Do not close these; they belong to the CURRENT profile. - // The cleanup runs for the PREVIOUS profile's exclusive types. - // We detect "away" by the fact that a new profile.id differs from what we - // stored. The actual close happens on the next profile change. - lastCleanedProfileIdRef.current = profile.id; - }, [profile.id, profile.auxTabs.exclusiveTabTypes]); - - useLayoutEffect(() => { - if (!focusedSessionId) return; - - const productAppRuntimeTabTypes = ['product-app-runtime']; - const currentOwnedTypes = profile.auxTabs.exclusiveTabTypes || []; - const maxPasses = 48; - const groupIds: EditorGroupId[] = ['primary', 'secondary', 'tertiary']; - for (let pass = 0; pass < maxPasses; pass++) { - const store = useAgentCanvasStore.getState() as any; - let closedOne = false; - for (const groupId of groupIds) { - const group = - groupId === 'primary' - ? store.primaryGroup - : groupId === 'secondary' - ? store.secondaryGroup - : store.tertiaryGroup; - const tab = group?.tabs?.find((t: any) => { - if (!productAppRuntimeTabTypes.includes(t.content.type)) return false; - const bound = t.content.metadata?.boundSessionId; - const ownedByCurrentProfile = currentOwnedTypes.includes(t.content.type); - return !ownedByCurrentProfile || (typeof bound === 'string' && bound !== focusedSessionId); - }); - if (tab) { - store.closeTab(tab.id, groupId, { forceRemove: true }); - closedOne = true; - break; - } - } - if (!closedOne) break; - } - }, [focusedSessionId, profile]); - - /** - * Non-AppBuilder sessions: close any app-builder tabs that don't belong - * to the active session. This is the generalised replacement for the old - * closeForeignAppBuilderTabs call. - */ - useEffect(() => { - if (!isInitializedRef.current) return; - if (!activeSession?.sessionId) return; - - // If the current profile owns app-builder tabs, don't clean them up. - if (profile.auxTabs.exclusiveTabTypes?.includes('app-builder')) return; - - // Otherwise, close any stray app-builder tabs from other sessions. - const maxPasses = 48; - const groupIds: EditorGroupId[] = ['primary', 'secondary', 'tertiary']; - for (let pass = 0; pass < maxPasses; pass++) { - const store = useAgentCanvasStore.getState() as any; - let closedOne = false; - for (const groupId of groupIds) { - const group = - groupId === 'primary' - ? store.primaryGroup - : groupId === 'secondary' - ? store.secondaryGroup - : store.tertiaryGroup; - const tab = group?.tabs?.find((t: any) => { - if (t.content.type !== 'app-builder') return false; - const bound = t.content.metadata?.appBuilderSessionId; - return typeof bound === 'string' && bound !== activeSession.sessionId; - }); - if (tab) { - store.closeTab(tab.id, groupId, { forceRemove: true }); - closedOne = true; - break; - } - } - if (!closedOne) break; - } - }, [activeSession?.sessionId, profile]); - - /** - * Watch tab count changes and manage panel expand/collapse. - */ - useEffect(() => { - if (!isInitializedRef.current) return; - - const primaryVisible = primaryGroup.tabs.filter(t => !t.isHidden).length; - const secondaryVisible = secondaryGroup.tabs.filter(t => !t.isHidden).length; - const visibleCount = primaryVisible + secondaryVisible; - - const isCollapsed = rightPanelCollapsedRef.current; - - if (visibleCount === 0 && autoCollapseOnEmpty && !isCollapsed) { - collapsePanel(); - } else if (visibleCount > 0 && autoExpandOnTabOpen && isCollapsed) { - expandPanel(); - } - }, [ - primaryGroup.tabs, - secondaryGroup.tabs, - autoCollapseOnEmpty, - autoExpandOnTabOpen, - expandPanel, - collapsePanel, - ]); - - /** - * Listen for expand-right-panel events. - */ - useEffect(() => { - const handleExpandRightPanel = () => { - if (autoExpandOnTabOpen) { - expandPanel(); - } - }; - - window.addEventListener(TAB_EVENTS.EXPAND_RIGHT_PANEL, handleExpandRightPanel); - - return () => { - window.removeEventListener(TAB_EVENTS.EXPAND_RIGHT_PANEL, handleExpandRightPanel); - }; - }, [autoExpandOnTabOpen, expandPanel]); - - return { - expandPanel, - collapsePanel, - closeExclusiveTabTypes, - }; -}; - -export default usePanelTabCoordinator; diff --git a/src/web-ui/src/app/components/panels/content-canvas/hooks/useTabLifecycle.ts b/src/web-ui/src/app/components/panels/content-canvas/hooks/useTabLifecycle.ts index 488d3444..2b291bc5 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/hooks/useTabLifecycle.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/hooks/useTabLifecycle.ts @@ -10,10 +10,8 @@ import { useCallback, useEffect } from 'react'; import { useCanvasStore, useAgentCanvasStore, useProjectCanvasStore } from '../stores'; -import type { EditorGroupId, PanelContent, CreateTabEventDetail } from '../types'; -import { TAB_EVENTS } from '../types'; +import type { EditorGroupId, PanelContent } from '../types'; import { useI18n } from '@/infrastructure/i18n'; -import { drainPendingTabs } from '@/shared/services/pendingTabQueue'; import { confirmDialog } from '@/design-system'; interface UseTabLifecycleOptions { /** App mode / target canvas */ @@ -55,12 +53,9 @@ export const useTabLifecycle = (options: UseTabLifecycleOptions = {}): UseTabLif togglePinTab, findTabByMetadata, switchToTab, - updateTabContent, closeTab, closeAllTabs, activeGroupId, - layout, - setSplitMode, } = useCanvasStore(); /** @@ -215,83 +210,6 @@ export const useTabLifecycle = (options: UseTabLifecycleOptions = {}): UseTabLif }; }, [mode]); - /** - * Listen for external tab creation events. - */ - useEffect(() => { - const eventName = - mode === 'project' - ? TAB_EVENTS.PROJECT_CREATE_TAB - : TAB_EVENTS.AGENT_CREATE_TAB; - - const handleCreateTab = (event: CustomEvent) => { - const { - type, - title, - data, - metadata, - checkDuplicate, - duplicateCheckKey, - replaceExisting, - targetGroup, - enableSplitView, - } = event.detail; - - const content: PanelContent = { - type, - title, - data, - metadata: { ...metadata, duplicateCheckKey }, - }; - - // If split view is enabled, switch to vertical split first (top/bottom) - if (enableSplitView && layout.splitMode === 'none') { - setSplitMode('vertical'); - } - - // Check duplicates - if (checkDuplicate && duplicateCheckKey) { - const existing = findTabByMetadata({ duplicateCheckKey }); - if (existing) { - const hasJumpInfo = data?.jumpToRange || data?.jumpToLine || data?.jumpToColumn; - - if (replaceExisting || hasJumpInfo) { - // Update content - updateTabContent(existing.tab.id, existing.groupId, content); - } - - // Switch to existing tab - switchToTab(existing.tab.id, existing.groupId); - - // Trigger right panel expansion - window.dispatchEvent(new CustomEvent(TAB_EVENTS.EXPAND_RIGHT_PANEL)); - return; - } - } - - // Determine target group: use specified group when split enabled, otherwise active group - const groupId = (enableSplitView && targetGroup) ? targetGroup : (targetGroup || activeGroupId); - - // Open all tabs in active state by default (no preview replacement) - addTab(content, 'active', groupId); - - // Trigger right panel expansion - window.dispatchEvent(new CustomEvent(TAB_EVENTS.EXPAND_RIGHT_PANEL)); - }; - - window.addEventListener(eventName, handleCreateTab as EventListener); - - // Drain any tab events that were enqueued before this listener was - // registered (happens when the scene was just mounted for the first time). - const pendingMode = mode === 'project' ? 'project' : 'agent'; - const pending = drainPendingTabs(pendingMode); - pending.forEach(detail => handleCreateTab({ detail } as CustomEvent)); - - return () => { - window.removeEventListener(eventName, handleCreateTab as EventListener); - }; - }, [mode, findTabByMetadata, updateTabContent, switchToTab, addTab, activeGroupId, layout.splitMode, setSplitMode]); - return { openPreview, openActive, diff --git a/src/web-ui/src/app/components/panels/content-canvas/index.ts b/src/web-ui/src/app/components/panels/content-canvas/index.ts index 72b9892c..49e4d6b1 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/index.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/index.ts @@ -8,6 +8,7 @@ export type { ContentCanvasProps } from './ContentCanvas'; // Types export * from './types'; +export { openCanvasItemInStore, openProjectCanvasItem } from './openCanvasItem'; // Store export { useCanvasStore, CanvasStoreModeContext } from './stores'; diff --git a/src/web-ui/src/app/components/panels/content-canvas/openCanvasItem.ts b/src/web-ui/src/app/components/panels/content-canvas/openCanvasItem.ts new file mode 100644 index 00000000..55130d19 --- /dev/null +++ b/src/web-ui/src/app/components/panels/content-canvas/openCanvasItem.ts @@ -0,0 +1,60 @@ +import type { PanelContent } from './types'; +import type { CanvasItemDescriptor } from './types'; +import { + useProjectCanvasStore, + type CanvasStore, +} from './stores/canvasStore'; + +export function openCanvasItemInStore( + store: CanvasStore, + item: CanvasItemDescriptor, + ownershipMetadata?: Record, +): void { + const duplicateCheckKey = + item.duplicateCheckKey + ?? (typeof item.metadata?.duplicateCheckKey === 'string' + ? item.metadata.duplicateCheckKey + : undefined); + const content: PanelContent = { + type: item.type, + title: item.title, + data: item.data, + metadata: { + ...item.metadata, + ...(duplicateCheckKey ? { duplicateCheckKey } : {}), + ...ownershipMetadata, + }, + }; + + if (item.enableSplitView && store.layout.splitMode === 'none') { + store.setSplitMode('vertical'); + } + + if (duplicateCheckKey) { + const existing = store.findTabByMetadata({ duplicateCheckKey }); + if (existing) { + const data = item.data as Record | undefined; + const hasJumpTarget = Boolean( + data?.jumpToRange || data?.jumpToLine || data?.jumpToColumn, + ); + if (item.replaceExisting !== false || hasJumpTarget) { + store.updateTabContent(existing.tab.id, existing.groupId, content); + } + store.switchToTab(existing.tab.id, existing.groupId); + if (existing.tab.state === 'preview') { + store.promoteTab(existing.tab.id, existing.groupId); + } + return; + } + } + + const groupId = + item.enableSplitView && item.targetGroup + ? item.targetGroup + : item.targetGroup ?? store.activeGroupId; + store.addTab(content, 'active', groupId); +} + +export function openProjectCanvasItem(item: CanvasItemDescriptor): void { + openCanvasItemInStore(useProjectCanvasStore.getState(), item); +} diff --git a/src/web-ui/src/app/components/panels/content-canvas/stores/canvasStore.ts b/src/web-ui/src/app/components/panels/content-canvas/stores/canvasStore.ts index e6056f57..0ae8f3cd 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/stores/canvasStore.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/stores/canvasStore.ts @@ -138,7 +138,7 @@ interface CanvasStoreActions { getAllTabs: () => CanvasTab[]; } -type CanvasStore = CanvasStoreState & CanvasStoreActions; +export type CanvasStore = CanvasStoreState & CanvasStoreActions; // ==================== Initial State ==================== @@ -1049,19 +1049,14 @@ export const useAgentCanvasStore = createCanvasStoreHook(); export const useProjectCanvasStore = createCanvasStoreHook(); export const usePanelViewCanvasStore = createCanvasStoreHook(); -// ==================== Agent canvas: per-workspace snapshots (AuxPane / Session scene) ==================== -// Switching active workspace saves the current agent canvas under the previous workspace id and restores -// the snapshot for the next id, so remote/local tabs coexist across workspace switches. +// ==================== Agent canvas: host-scoped snapshots ==================== +// The right-side canvas belongs to a concrete UI host (home/session), not to a +// workspace. Navigation activates exactly one host and scenes activate none. -const AGENT_CANVAS_SNAPSHOT_MAX = 12; -const agentWorkspaceSnapshots = new Map(); -const agentSnapshotLruOrder: string[] = []; -/** Dedupes React Strict Mode double-invoke when `prev` is null (ref reset on remount). */ -let lastAgentCanvasSwitchTargetKey: string | null = null; - -function normalizeAgentWorkspaceKey(id: string | null | undefined): string { - return id ?? '__none__'; -} +const AGENT_CANVAS_HOST_LIMIT = 24; +const agentHostSnapshots = new Map(); +const agentHostLruOrder: string[] = []; +let activeAgentCanvasHostKey: string | null = null; function extractAgentPersistableState(state: CanvasStore): CanvasStoreState { return { @@ -1077,23 +1072,18 @@ function extractAgentPersistableState(state: CanvasStore): CanvasStoreState { }; } -function hasVisibleAgentTabs(snapshot: CanvasStoreState): boolean { - return [snapshot.primaryGroup, snapshot.secondaryGroup, snapshot.tertiaryGroup] - .some(group => group.tabs.some(tab => tab.isHidden !== true)); -} - -function rememberAgentSnapshot(key: string, snapshot: CanvasStoreState): void { +function rememberAgentHost(key: string, snapshot: CanvasStoreState): void { const clone = structuredClone(snapshot); clone.draggingTabId = null; clone.draggingFromGroupId = null; - agentWorkspaceSnapshots.set(key, clone); - const idx = agentSnapshotLruOrder.indexOf(key); - if (idx >= 0) agentSnapshotLruOrder.splice(idx, 1); - agentSnapshotLruOrder.push(key); - while (agentWorkspaceSnapshots.size > AGENT_CANVAS_SNAPSHOT_MAX) { - const evict = agentSnapshotLruOrder.shift(); + agentHostSnapshots.set(key, clone); + const idx = agentHostLruOrder.indexOf(key); + if (idx >= 0) agentHostLruOrder.splice(idx, 1); + agentHostLruOrder.push(key); + while (agentHostSnapshots.size > AGENT_CANVAS_HOST_LIMIT) { + const evict = agentHostLruOrder.shift(); if (!evict) break; - agentWorkspaceSnapshots.delete(evict); + agentHostSnapshots.delete(evict); } } @@ -1111,36 +1101,15 @@ function applyEmptyAgentCanvas(): void { }); } -/** - * Save the current agent canvas under `prevWorkspaceId` (unless first mount) and restore the snapshot - * for `nextWorkspaceId` (or empty canvas if none). Capture target snapshot before LRU eviction. - */ -export function switchAgentCanvasWorkspace( - prevWorkspaceId: string | null | undefined, - nextWorkspaceId: string | null | undefined -): void { - const from = - prevWorkspaceId === null || prevWorkspaceId === undefined - ? null - : normalizeAgentWorkspaceKey(prevWorkspaceId); - const to = normalizeAgentWorkspaceKey(nextWorkspaceId); - - if (from === null && lastAgentCanvasSwitchTargetKey === to) { - return; - } +/** Atomically save the current host and restore the next host. */ +export function activateAgentCanvasHost(nextHostKey: string | null): void { + if (activeAgentCanvasHostKey === nextHostKey) return; - const rawNext = agentWorkspaceSnapshots.get(to); - const nextSnapshotClone = rawNext ? structuredClone(rawNext) : null; + const nextSnapshot = nextHostKey ? agentHostSnapshots.get(nextHostKey) : null; + const nextSnapshotClone = nextSnapshot ? structuredClone(nextSnapshot) : null; const current = extractAgentPersistableState(useAgentCanvasStore.getState() as CanvasStore); - - if (from === null && hasVisibleAgentTabs(current)) { - rememberAgentSnapshot(to, current); - lastAgentCanvasSwitchTargetKey = to; - return; - } - - if (from !== null) { - rememberAgentSnapshot(from, current); + if (activeAgentCanvasHostKey) { + rememberAgentHost(activeAgentCanvasHostKey, current); } if (nextSnapshotClone) { @@ -1159,15 +1128,22 @@ export function switchAgentCanvasWorkspace( applyEmptyAgentCanvas(); } - lastAgentCanvasSwitchTargetKey = to; + activeAgentCanvasHostKey = nextHostKey; } -/** Drop cached canvas for a closed workspace (does not touch the live canvas unless user switches back). */ -export function removeAgentCanvasSnapshot(workspaceId: string): void { - const key = normalizeAgentWorkspaceKey(workspaceId); - agentWorkspaceSnapshots.delete(key); - const idx = agentSnapshotLruOrder.indexOf(key); - if (idx >= 0) agentSnapshotLruOrder.splice(idx, 1); +export function getActiveAgentCanvasHostKey(): string | null { + return activeAgentCanvasHostKey; +} + +/** Drop a host and clear the live canvas if that host is currently active. */ +export function removeAgentCanvasHost(hostKey: string): void { + agentHostSnapshots.delete(hostKey); + const idx = agentHostLruOrder.indexOf(hostKey); + if (idx >= 0) agentHostLruOrder.splice(idx, 1); + if (activeAgentCanvasHostKey === hostKey) { + activeAgentCanvasHostKey = null; + applyEmptyAgentCanvas(); + } } diff --git a/src/web-ui/src/app/components/panels/content-canvas/stores/index.ts b/src/web-ui/src/app/components/panels/content-canvas/stores/index.ts index aa263b0d..5fdd01d7 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/stores/index.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/stores/index.ts @@ -12,6 +12,7 @@ export { useActiveTabId, useLayout, useDragging, - switchAgentCanvasWorkspace, - removeAgentCanvasSnapshot, + activateAgentCanvasHost, + getActiveAgentCanvasHostKey, + removeAgentCanvasHost, } from './canvasStore'; diff --git a/src/web-ui/src/app/components/panels/content-canvas/types/content.ts b/src/web-ui/src/app/components/panels/content-canvas/types/content.ts index 56fdd41e..553c0023 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/types/content.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/types/content.ts @@ -32,7 +32,7 @@ export const isFileViewerType = (type: PanelContentType): boolean => { /** * Options for creating a tab. */ -export interface CreateTabOptions { +export interface CanvasItemDescriptor { /** Content type */ type: PanelContentType; /** Title */ @@ -41,8 +41,6 @@ export interface CreateTabOptions { data?: any; /** Metadata */ metadata?: Record; - /** Whether to check duplicates */ - checkDuplicate?: boolean; /** Duplicate check key */ duplicateCheckKey?: string; /** Whether to replace existing tab */ @@ -52,23 +50,3 @@ export interface CreateTabOptions { /** Enable split view (auto-switch to horizontal split) */ enableSplitView?: boolean; } - -/** - * Create-tab event detail. - */ -export interface CreateTabEventDetail extends CreateTabOptions { - /** App mode / target canvas */ - mode?: 'agent' | 'project'; -} - -/** - * Tab event names. - */ -export const TAB_EVENTS = { - /** Create tab in agent mode */ - AGENT_CREATE_TAB: 'agent-create-tab', - /** Create tab in project mode */ - PROJECT_CREATE_TAB: 'project-create-tab', - /** Expand right panel */ - EXPAND_RIGHT_PANEL: 'expand-right-panel', -} as const; diff --git a/src/web-ui/src/app/components/panels/content-canvas/types/index.ts b/src/web-ui/src/app/components/panels/content-canvas/types/index.ts index 33d29edb..384d7152 100644 --- a/src/web-ui/src/app/components/panels/content-canvas/types/index.ts +++ b/src/web-ui/src/app/components/panels/content-canvas/types/index.ts @@ -39,12 +39,10 @@ export { export type { PanelContentType, PanelContent, - CreateTabOptions, - CreateTabEventDetail, + CanvasItemDescriptor, } from './content'; export { FILE_VIEWER_TYPES, isFileViewerType, - TAB_EVENTS, } from './content'; diff --git a/src/web-ui/src/app/daily-letter-arrival/components/DailyLetterArrivalDock.tsx b/src/web-ui/src/app/daily-letter-arrival/components/DailyLetterArrivalDock.tsx index c6bc2425..5eee1b5b 100644 --- a/src/web-ui/src/app/daily-letter-arrival/components/DailyLetterArrivalDock.tsx +++ b/src/web-ui/src/app/daily-letter-arrival/components/DailyLetterArrivalDock.tsx @@ -154,7 +154,6 @@ const DailyLetterArrivalDock: React.FC = () => { onSeal={() => void handleSeal()} formatDate={formatDate} t={t} - originCorner onFirstOpen={markDailyLetterAcknowledged} /> diff --git a/src/web-ui/src/app/hooks/useApp.ts b/src/web-ui/src/app/hooks/useApp.ts index ddc12e3a..37b73d18 100644 --- a/src/web-ui/src/app/hooks/useApp.ts +++ b/src/web-ui/src/app/hooks/useApp.ts @@ -9,7 +9,6 @@ import { AppState, AgentConfig, ChatSession, - TabInfo, PanelType } from '../types'; import { appManager } from '../services/AppManager'; @@ -40,22 +39,6 @@ export const useApp = (): UseAppReturn => { }); }, [state.layout.leftPanelCollapsed]); - const toggleRightPanel = useCallback(() => { - appManager.updateLayout({ - rightPanelCollapsed: !state.layout.rightPanelCollapsed - }); - }, [state.layout.rightPanelCollapsed]); - - const toggleChatPanel = useCallback(() => { - const nextChatCollapsed = !state.layout.chatCollapsed; - appManager.updateLayout({ - chatCollapsed: nextChatCollapsed, - // Keep behavior aligned with editor-mode layout: - // when chat is hidden, ensure the right panel is visible to occupy center space. - rightPanelCollapsed: nextChatCollapsed ? false : state.layout.rightPanelCollapsed - }); - }, [state.layout.chatCollapsed, state.layout.rightPanelCollapsed]); - const switchLeftPanelTab = useCallback((tab: PanelType) => { appManager.updateLayout({ leftPanelActiveTab: tab, @@ -73,33 +56,6 @@ export const useApp = (): UseAppReturn => { }); }, []); - const updateCenterPanelWidth = useCallback((width: number) => { - // Clamp width: minimum 400px - const MIN_WIDTH = 400; - const clampedWidth = Math.max(MIN_WIDTH, width); - - appManager.updateLayout({ - centerPanelWidth: clampedWidth - }); - }, []); - - const updateRightPanelWidth = useCallback((width: number) => { - // Clamp width: 200px min, 1200px max - const MIN_WIDTH = 200; - const MAX_WIDTH = 1200; - const clampedWidth = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, width)); - - appManager.updateLayout({ - rightPanelWidth: clampedWidth - }); - }, []); - - const toggleCenterPanel = useCallback(() => { - appManager.updateLayout({ - centerPanelCollapsed: !state.layout.centerPanelCollapsed - }); - }, [state.layout.centerPanelCollapsed]); - const updateAgentConfig = useCallback(async (agentId: string, config: Partial): Promise => { try { await appManager.updateAgentConfig(agentId, config); @@ -165,32 +121,6 @@ export const useApp = (): UseAppReturn => { } }, []); - // Tab actions - const openTab = useCallback((tab: Omit): string => { - try { - return appManager.openTab(tab); - } catch (error) { - log.error('Failed to open tab', error); - throw error; - } - }, []); - - const closeTab = useCallback((tabId: string) => { - try { - appManager.closeTab(tabId); - } catch (error) { - log.error('Failed to close tab', error); - } - }, []); - - const selectTab = useCallback((tabId: string) => { - try { - appManager.selectTab(tabId); - } catch (error) { - log.error('Failed to select tab', error); - } - }, []); - // Utility actions const clearError = useCallback(() => { appManager.clearError(); @@ -202,13 +132,8 @@ export const useApp = (): UseAppReturn => { // Layout actions toggleLeftPanel, - toggleCenterPanel, - toggleRightPanel, - toggleChatPanel, switchLeftPanelTab, updateLeftPanelWidth, - updateCenterPanelWidth, - updateRightPanelWidth, updateAgentConfig, @@ -221,53 +146,7 @@ export const useApp = (): UseAppReturn => { enableExtension, disableExtension, - // Tab actions - openTab, - closeTab, - selectTab, - // Utility actions clearError }; }; - -// Layout helper hook -export const useLayout = () => { - const { state, toggleLeftPanel, toggleRightPanel, toggleChatPanel, switchLeftPanelTab, updateLeftPanelWidth } = useApp(); - - return { - layout: state.layout, - toggleLeftPanel, - toggleRightPanel, - toggleChatPanel, - switchLeftPanelTab, - updateLeftPanelWidth - }; -}; - -// Chat helper hook -export const useChat = () => { - const { state, createChatSession, selectChatSession, sendMessage } = useApp(); - - return { - sessions: state.chatSessions, - activeSession: state.activeChatSession, - currentAgent: state.currentAgent, - createSession: createChatSession, - selectSession: selectChatSession, - sendMessage - }; -}; - -// Tab helper hook -export const useTabs = () => { - const { state, openTab, closeTab, selectTab } = useApp(); - - return { - tabs: state.layout.rightPanelTabs, - activeTabId: state.layout.rightPanelActiveTabId, - openTab, - closeTab, - selectTab - }; -}; diff --git a/src/web-ui/src/app/layout/AppLayout.tsx b/src/web-ui/src/app/layout/AppLayout.tsx index 13302c7f..9233c96c 100644 --- a/src/web-ui/src/app/layout/AppLayout.tsx +++ b/src/web-ui/src/app/layout/AppLayout.tsx @@ -60,7 +60,7 @@ const AppLayout: React.FC = ({ className = '' }) => { const { handleMinimize, handleMaximize, handleClose, isMaximized } = useWindowControls(); - const { state, switchLeftPanelTab, toggleLeftPanel, toggleRightPanel } = useApp(); + const { state, switchLeftPanelTab, toggleLeftPanel } = useApp(); // ── Load user keybinding overrides from config on startup ──────────────── useEffect(() => { @@ -384,14 +384,11 @@ const AppLayout: React.FC = ({ className = '' }) => { const handleSwitchToFilesPanel = () => { switchLeftPanelTab('files'); if (state.layout.leftPanelCollapsed) toggleLeftPanel(); - if (state.layout.rightPanelCollapsed) { - setTimeout(() => toggleRightPanel(), 100); - } }; window.addEventListener('switch-to-files-panel', handleSwitchToFilesPanel); return () => window.removeEventListener('switch-to-files-panel', handleSwitchToFilesPanel); - }, [state.layout.leftPanelCollapsed, state.layout.rightPanelCollapsed, switchLeftPanelTab, toggleLeftPanel, toggleRightPanel]); + }, [state.layout.leftPanelCollapsed, switchLeftPanelTab, toggleLeftPanel]); // Global drag-and-drop React.useEffect(() => { diff --git a/src/web-ui/src/app/layout/WorkspaceBody.tsx b/src/web-ui/src/app/layout/WorkspaceBody.tsx index 06a7002e..fd4ed5e6 100644 --- a/src/web-ui/src/app/layout/WorkspaceBody.tsx +++ b/src/web-ui/src/app/layout/WorkspaceBody.tsx @@ -18,6 +18,7 @@ import WorkspaceFooterActions from '../components/WorkspaceFooterActions/Workspa import { useWorkspaceSurfaceStore } from '../navigation/workspaceSurfaceStore'; import { useProductAppRuntimeCatalogSync } from '../scenes/apps/product-app-runtime/useProductAppRuntimeCatalogSync'; import { SessionProfileProvider } from '../session-profiles'; +import { AuxiliarySurfaceCoordinator } from '../auxiliary-surface'; import './WorkspaceBody.scss'; interface WorkspaceBodyProps { @@ -50,6 +51,7 @@ const WorkspaceBody: React.FC = ({ return ( +
diff --git a/src/web-ui/src/app/layout/panelConfig.ts b/src/web-ui/src/app/layout/panelConfig.ts index 0da50077..37546654 100644 --- a/src/web-ui/src/app/layout/panelConfig.ts +++ b/src/web-ui/src/app/layout/panelConfig.ts @@ -39,8 +39,8 @@ export const LEFT_PANEL_CONFIG = { TRANSITION_DURATION: 200, // Mode transition duration (ms) } as const; -// ==================== Right panel config ==================== -export const RIGHT_PANEL_CONFIG = { +// ==================== Auxiliary surface dock config ==================== +export const AUXILIARY_SURFACE_CONFIG = { // Width thresholds (px) COLLAPSED_WIDTH: 0, // Fully collapsed COMPACT_WIDTH: 300, // Compact mode minimum width - also the minimum drag width @@ -58,19 +58,6 @@ export const RIGHT_PANEL_CONFIG = { TRANSITION_DURATION: 200, // Mode transition duration (ms) } as const; -/** Canvas-first Product Apps need enough width for their primary workbench. */ -export const WIDE_WORKBENCH_RIGHT_PANEL_CONFIG = { - ...RIGHT_PANEL_CONFIG, - COMFORTABLE_DEFAULT: 720, - EXPANDED_THRESHOLD: 820, - SNAP_POINTS: [400, 540, 720, 900, 1100], -} as const; - -export const WIDE_WORKBENCH_PRODUCT_APP_IDS = new Set([ - 'builtin-excel-live', - 'builtin-remotion-live', -]); - // ==================== Common config ==================== export const PANEL_COMMON_CONFIG = { RESIZER_WIDTH: 4, // Resizer width @@ -208,17 +195,16 @@ export function clampWidth( // ==================== Local storage keys ==================== export const STORAGE_KEYS = { LEFT_PANEL_WIDTH: 'sparo:leftPanelWidth', - RIGHT_PANEL_WIDTH: 'sparo:rightPanelWidth', LEFT_PANEL_COLLAPSED: 'sparo:leftPanelCollapsed', - RIGHT_PANEL_COLLAPSED: 'sparo:rightPanelCollapsed', LEFT_PANEL_LAST_WIDTH: 'sparo:leftPanelLastWidth', // Remembered width before collapse - RIGHT_PANEL_LAST_WIDTH: 'sparo:rightPanelLastWidth', // Remembered width before collapse + AUXILIARY_SURFACE_WIDTH: 'sparo:auxiliarySurfaceWidth', } as const; /** * Save panel width to local storage. */ export function savePanelWidth(key: string, width: number): void { + if (typeof localStorage === 'undefined') return; try { localStorage.setItem(key, String(width)); } catch (e) { @@ -230,6 +216,7 @@ export function savePanelWidth(key: string, width: number): void { * Load panel width from local storage. */ export function loadPanelWidth(key: string, defaultValue: number): number { + if (typeof localStorage === 'undefined') return defaultValue; try { const stored = localStorage.getItem(key); if (stored) { diff --git a/src/web-ui/src/app/navigation/workspaceSurfaceStore.ts b/src/web-ui/src/app/navigation/workspaceSurfaceStore.ts index 7b6f73b2..a29791c1 100644 --- a/src/web-ui/src/app/navigation/workspaceSurfaceStore.ts +++ b/src/web-ui/src/app/navigation/workspaceSurfaceStore.ts @@ -9,6 +9,10 @@ import { type WorkspaceSurface, } from './workspaceSurfaceTypes'; import { systemRuntimeScope } from '@/shared/types/runtime-scope'; +import { + forgetSessionAuxiliarySurfaces, + synchronizeAuxiliarySurface, +} from '@/app/auxiliary-surface/navigationSync'; export const WORKSPACE_SCENE_HISTORY_LIMIT = 5; @@ -129,6 +133,7 @@ export const useWorkspaceSurfaceStore = create((set, get) : state.currentOsSessionId; if (isSameWorkspaceSurface(current, surface)) { + synchronizeAuxiliarySurface(surface, nextCurrentOsSessionId); set({ sceneHistory: surface.kind === 'agentic-os-home' ? [] : state.sceneHistory, surfaceContext: nextSurfaceContext, @@ -145,6 +150,7 @@ export const useWorkspaceSurfaceStore = create((set, get) : shouldCaptureCurrentScene(current, surface, historyMode) ? pushSceneHistory(state.sceneHistory, current, state.surfaceContext) : state.sceneHistory; + synchronizeAuxiliarySurface(surface, nextCurrentOsSessionId); set({ activeSurface: surface, previousSurface: current, @@ -170,6 +176,7 @@ export const useWorkspaceSurfaceStore = create((set, get) if (!entry) return false; const nextHistory = state.sceneHistory.filter((_, i) => i !== index); + synchronizeAuxiliarySurface(entry.surface, state.currentOsSessionId); set({ activeSurface: entry.surface, previousSurface: state.activeSurface, @@ -192,6 +199,7 @@ export const useWorkspaceSurfaceStore = create((set, get) forgetSessions: (sessionIds) => { if (sessionIds.length === 0) return; const removedSessionIds = new Set(sessionIds); + forgetSessionAuxiliarySurfaces(sessionIds); set((state) => { const activeSurface = @@ -215,6 +223,8 @@ export const useWorkspaceSurfaceStore = create((set, get) currentOsSessionId: nextCurrentOsSessionId, }; }); + const next = get(); + synchronizeAuxiliarySurface(next.activeSurface, next.currentOsSessionId); syncSceneNav(get().activeSurface); }, diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts b/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts index c51b74c6..f781fbae 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts @@ -32,6 +32,7 @@ import { } from '@/app/agentic-os/excel-live/excelLiveFocusStore'; import { useContextStore } from '@/shared/stores/contextStore'; import type { ProductAppRuntimeHostedViewBridge } from './productAppRuntimeHostedViews'; +import { resizeActiveAuxiliarySurface } from '@/app/auxiliary-surface'; interface JSONRPC { jsonrpc?: string; @@ -561,9 +562,7 @@ export function useProductAppRuntimeBridge( if (mode !== 'comfortable' && mode !== 'expanded') { throw new Error('host.setPanelMode requires comfortable or expanded'); } - window.dispatchEvent(new CustomEvent('product-app-request-panel-mode', { - detail: { appId, mode }, - })); + resizeActiveAuxiliarySurface(mode); reply(null); return; } diff --git a/src/web-ui/src/app/scenes/daily-letter/LetterPaper.scss b/src/web-ui/src/app/scenes/daily-letter/LetterPaper.scss index d7b3513b..a759592c 100644 --- a/src/web-ui/src/app/scenes/daily-letter/LetterPaper.scss +++ b/src/web-ui/src/app/scenes/daily-letter/LetterPaper.scss @@ -3,102 +3,28 @@ // Reading stack for letter prose: editorial serif with CJK fallbacks. $dl-serif: georgia, 'Iowan Old Style', 'Times New Roman', 'Songti SC', simsun, 'Noto Serif CJK SC', serif; -// Letter paper overlay: a dark slate scrim with a soft vignette that -// focuses the eye on the sheet, in both light and dark themes. -.dl-paper-overlay { - background: - radial-gradient( - 130% 110% at 50% 36%, - transparent 30%, - color-mix(in srgb, var(--ds-shadow-color-strong) 72%, transparent) 100% - ), - var(--ds-overlay-scrim-strong); - backdrop-filter: blur(4px); -} - -.dl-paper-dialog { - max-width: min(720px, calc(100vw - 48px)); - border: 1px solid color-mix(in srgb, var(--ds-color-border-strong) 72%, var(--ds-color-border-subtle)); - border-radius: $size-radius-lg; - // Layered longhand keeps the paper fully opaque even when the theme's - // elevated surface carries alpha: scene color at the bottom, elevated - // surface above it, then a faint accent wash at the top edge. - background-color: var(--ds-color-bg-scene); - background-image: - linear-gradient( - 178deg, - color-mix(in srgb, var(--ds-color-accent) 5%, transparent) 0%, - transparent 30% - ), - linear-gradient(var(--ds-color-bg-elevated), var(--ds-color-bg-elevated)); - // Contact, key, and ambient layers: the sheet should feel lifted off - // the desk rather than printed onto the scrim. - box-shadow: - 0 1px 2px var(--ds-shadow-color-soft), - 0 16px 40px var(--ds-shadow-color-modal), - 0 64px 140px var(--ds-shadow-color-strong); - animation: dl-paper-unfold 420ms cubic-bezier(0.16, 1, 0.3, 1); - - // Letterhead ribbon: a hairline of accent light along the top edge. - &::after { - content: ''; - position: absolute; - top: 0; - right: 0; - left: 0; - height: 2px; - pointer-events: none; - background: - linear-gradient( - 90deg, - transparent 0%, - color-mix(in srgb, var(--ds-color-accent) 70%, transparent) 24%, - color-mix(in srgb, var(--ds-color-accent) 70%, transparent) 76%, - transparent 100% - ); - } - - // The paper draws its own masthead; float the close control over both - // the sheet and the compact letterhead bar. - .ds-dialog__header-shell { - position: absolute; - inset-block-start: 0; - inset-inline-end: 0; - z-index: var(--ds-z-floating, 50); - min-height: 0; - } - - .ds-dialog__close { - inset-block-start: $size-gap-3; - inset-inline-end: $size-gap-3; - width: 28px; - height: 28px; - border-radius: 50%; - color: var(--ds-color-text-tertiary); - background: color-mix(in srgb, var(--ds-color-bg-elevated) 82%, var(--ds-color-text-tertiary)); - - &:hover { - color: var(--ds-color-text-primary); - background: color-mix(in srgb, var(--ds-color-bg-elevated) 68%, var(--ds-color-text-tertiary)); - border-color: transparent; - } - } +.dl-paper-popup-layer { + position: fixed; + inset: 0; + z-index: var(--ds-z-popover); + display: flex; + align-items: center; + justify-content: center; + padding: $size-gap-6; + pointer-events: none; } -// Opened from the bottom-left arrival card: grow from that corner -// instead of the viewport center, so the sheet reads as "this is the -// letter I just clicked" rather than appearing out of nowhere. -.dl-paper-dialog--from-corner { - transform-origin: 64px calc(100% - 64px); - animation-name: dl-paper-unfold-from-corner; +.dl-paper-popup { + width: min(760px, 100%); + max-height: calc(100vh - 48px); + pointer-events: auto; } -// The dialog body stops scrolling itself; the shell owns a viewport so the -// letterhead bar, progress ink, and tray can react to scroll position. +// The popup card owns the surface; the shell owns the reading viewport so +// the letterhead bar, progress ink, and tray can react to scroll position. .dl-paper-scroll { display: flex; flex-direction: column; - padding: 0; overflow: hidden; } @@ -419,34 +345,6 @@ $dl-serif: georgia, 'Iowan Old Style', 'Times New Roman', 'Songti SC', simsun, ' gap: $size-gap-2; } -@keyframes dl-paper-unfold { - from { - opacity: 0; - transform: perspective(1200px) translateY(26px) rotateX(4deg) scale(0.985); - } - - to { - opacity: 1; - transform: perspective(1200px) translateY(0) rotateX(0deg) scale(1); - } -} - -@keyframes dl-paper-unfold-from-corner { - from { - opacity: 0; - transform: perspective(1200px) translateY(18px) scale(0.6); - } - - 60% { - opacity: 1; - } - - to { - opacity: 1; - transform: perspective(1200px) translateY(0) scale(1); - } -} - @keyframes dl-paper-rise { from { opacity: 0; @@ -460,7 +358,6 @@ $dl-serif: georgia, 'Iowan Old Style', 'Times New Roman', 'Songti SC', simsun, ' } @media (prefers-reduced-motion: reduce) { - .dl-paper-dialog, .dl-paper__masthead, .dl-paper__content, .dl-paper__sign { @@ -475,6 +372,14 @@ $dl-serif: georgia, 'Iowan Old Style', 'Times New Roman', 'Songti SC', simsun, ' } @media (max-width: 820px) { + .dl-paper-popup-layer { + padding: $size-gap-4; + } + + .dl-paper-popup { + max-height: calc(100vh - 32px); + } + .dl-paper { --dl-paper-inset: #{$size-gap-5}; diff --git a/src/web-ui/src/app/scenes/daily-letter/LetterPaper.tsx b/src/web-ui/src/app/scenes/daily-letter/LetterPaper.tsx index 67ff48d0..c41ea9c1 100644 --- a/src/web-ui/src/app/scenes/daily-letter/LetterPaper.tsx +++ b/src/web-ui/src/app/scenes/daily-letter/LetterPaper.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; import { Archive, Check } from 'lucide-react'; -import { Button, Dialog, type DialogProps } from '@/design-system'; +import { Button, FloatingCard } from '@/design-system'; import { Markdown } from '@/shared/markdown'; import { parseDateKey } from './dailyLetterDateUtils'; import type { DailyLetterRecord } from './dailyLetterTypes'; @@ -16,7 +17,7 @@ interface PaperScrollState { } /** - * The paper overlay renders its own masthead, so a duplicated leading + * The paper popup renders its own masthead, so a duplicated leading * markdown H1 ("# 今日来信 · date") is dropped from the body. */ function letterBodyForPaper(markdown: string): string { @@ -38,21 +39,12 @@ export interface LetterPaperProps { onSeal: () => void; formatDate: FormatDateFn; t: TFn; - /** - * When the paper is opened from a corner-anchored surface (e.g. the - * bottom-left arrival card), the unfold animation grows from that - * corner instead of the viewport center — a cheap way to keep the - * "this letter came from where I just clicked" continuity without a - * real shared-element transition. - */ - originCorner?: boolean; /** * Called once, the first time this record is shown open. Lets callers * (the arrival dock, the scene) mark the letter as read in one place * regardless of who triggered the open. */ onFirstOpen?: (letter: DailyLetterRecord) => void; - dialogProps?: Partial; } export function LetterPaper({ @@ -64,14 +56,48 @@ export function LetterPaper({ onSeal, formatDate, t, - originCorner = false, onFirstOpen, - dialogProps, }: LetterPaperProps) { const viewportRef = useRef(null); + const popupRef = useRef(null); + const previousFocusRef = useRef(null); + const onOpenChangeRef = useRef(onOpenChange); const [scroll, setScroll] = useState({ collapsed: false, progress: 0, atEnd: false }); const announcedIdRef = useRef(null); + useEffect(() => { + onOpenChangeRef.current = onOpenChange; + }, [onOpenChange]); + + useEffect(() => { + if (!open) return undefined; + + previousFocusRef.current = document.activeElement instanceof HTMLElement + ? document.activeElement + : null; + + const focusFrame = window.requestAnimationFrame(() => popupRef.current?.focus()); + const handlePointerDown = (event: PointerEvent) => { + if (!popupRef.current?.contains(event.target as Node)) { + onOpenChangeRef.current(false); + } + }; + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key !== 'Escape') return; + event.preventDefault(); + onOpenChangeRef.current(false); + }; + + document.addEventListener('pointerdown', handlePointerDown); + document.addEventListener('keydown', handleKeyDown); + return () => { + window.cancelAnimationFrame(focusFrame); + document.removeEventListener('pointerdown', handlePointerDown); + document.removeEventListener('keydown', handleKeyDown); + previousFocusRef.current?.focus(); + }; + }, [open]); + const readScroll = useCallback(() => { const el = viewportRef.current; if (!el) return; @@ -105,7 +131,7 @@ export function LetterPaper({ onFirstOpen?.(letter); }, [letter, onFirstOpen, open]); - if (!letter) return null; + if (!letter || !open) return null; const scopeLabel = letter.scope === 'agentic_os' ? t('scope.agenticOs') : t('scope.workspace'); const postmarkDate = `${letter.date.slice(5, 7)} · ${letter.date.slice(8, 10)}`; @@ -117,91 +143,95 @@ export function LetterPaper({ } const writtenAt = formatDate(new Date(letter.createdAtMs), { timeStyle: 'short' }); - return ( - -
+ onOpenChange(false)} + dismissLabel={t('actions.close')} + dismissTooltip={t('actions.close')} + role="dialog" + aria-modal="false" + aria-label={t('paper.label')} + tabIndex={-1} > -
-
-
-
- - -
-

{t('paper.eyebrow')}

-

{dateLine}

-

- {letter.workspace ? `${letter.workspace.name} · ` : ''} - {t('paper.writtenAt', { time: writtenAt })} -

-
- -
- -
- -
- {letter.status === 'sealed' && ( - - )} - {t('paper.signature')} - {letter.date} -
- -
-
- {pendingCount > 0 && ( - {t('paper.pending', { count: pendingCount })} - )} +
+
+
+
+
+ + +
+

{t('paper.eyebrow')}

+

{dateLine}

+

+ {letter.workspace ? `${letter.workspace.name} · ` : ''} + {t('paper.writtenAt', { time: writtenAt })} +

+
+ +
+
-
- - + +
+ {letter.status === 'sealed' && ( + + )} + {t('paper.signature')} + {letter.date} +
+ +
+
+ {pendingCount > 0 && ( + {t('paper.pending', { count: pendingCount })} + )} +
+
+ + +
-
-
+
+
-
- + + , + document.body, ); } diff --git a/src/web-ui/src/app/scenes/panel-view/PanelViewScene.tsx b/src/web-ui/src/app/scenes/panel-view/PanelViewScene.tsx index 6e129354..2ccc4ed2 100644 --- a/src/web-ui/src/app/scenes/panel-view/PanelViewScene.tsx +++ b/src/web-ui/src/app/scenes/panel-view/PanelViewScene.tsx @@ -2,7 +2,7 @@ * PanelViewScene �?a standalone scene that hosts a ContentCanvas * with its own independent store (panel-view mode). * - * Tabs popped out from the agent scene's right panel are added here, + * Tabs popped out from the active auxiliary surface are added here, * allowing them all to be viewed and managed in one place. */ diff --git a/src/web-ui/src/app/scenes/session/AuxPane.tsx b/src/web-ui/src/app/scenes/session/AuxPane.tsx index b839222f..953f50ac 100644 --- a/src/web-ui/src/app/scenes/session/AuxPane.tsx +++ b/src/web-ui/src/app/scenes/session/AuxPane.tsx @@ -1,151 +1,44 @@ -/** - * AuxPane �?AI Agent scene right pane. - * Hosts ContentCanvas with tab management for editor views and visualizations. - * - * Renamed from panels/ContentPanel. All logic preserved. - */ - -import { forwardRef, useEffect, useLayoutEffect, useRef, useImperativeHandle, useCallback } from 'react'; -import { ContentCanvas, useCanvasStore } from '../../components/panels/content-canvas'; -import { - switchAgentCanvasWorkspace, - removeAgentCanvasSnapshot, -} from '../../components/panels/content-canvas/stores'; -import { workspaceManager } from '@/infrastructure/services/business/workspaceManager'; -import { useWorkspaceContext } from '@/infrastructure/contexts/WorkspaceContext'; -import type { PanelContent as OldPanelContent } from '../../components/panels/base/types'; -import type { PanelContent } from '../../components/panels/content-canvas/types'; +import { useCallback } from 'react'; +import { ContentCanvas } from '../../components/panels/content-canvas'; +import { useAuxiliarySurfaceStore } from '@/app/auxiliary-surface'; import { createLogger } from '@/shared/utils/logger'; -import { isSamePath } from '@/shared/utils/pathUtils'; - import './AuxPane.scss'; const log = createLogger('AuxPane'); -export interface AuxPaneRef { - addTab: (content: OldPanelContent) => void; - switchToTab: (tabId: string) => void; - findTabByMetadata: (metadata: Record) => { tabId: string } | null; - updateTabContent: (tabId: string, content: OldPanelContent) => void; - closeAllTabs: () => void; -} - interface AuxPaneProps { workspacePath?: string; isSceneActive?: boolean; } -const AuxPane = forwardRef( - ({ workspacePath, isSceneActive = true }, ref) => { - const { openedWorkspacesList } = useWorkspaceContext(); - const workspaceId = workspacePath - ? openedWorkspacesList.find(workspace => isSamePath(workspace.rootPath, workspacePath))?.id - : undefined; - - const { - addTab, - switchToTab, - findTabByMetadata, - updateTabContent, - closeAllTabs, - primaryGroup, - secondaryGroup, - } = useCanvasStore(); - - const convertContent = useCallback((oldContent: OldPanelContent): PanelContent => { - return { - type: oldContent.type, - title: oldContent.title, - data: oldContent.data, - metadata: oldContent.metadata, - }; - }, []); - - useImperativeHandle(ref, () => ({ - addTab: (content: OldPanelContent) => { - addTab(convertContent(content), 'active'); - window.dispatchEvent(new CustomEvent('expand-right-panel')); - }, - switchToTab: (tabId: string) => { - if (primaryGroup.tabs.find(t => t.id === tabId)) { - switchToTab(tabId, 'primary'); - window.dispatchEvent(new CustomEvent('expand-right-panel')); - } else if (secondaryGroup.tabs.find(t => t.id === tabId)) { - switchToTab(tabId, 'secondary'); - window.dispatchEvent(new CustomEvent('expand-right-panel')); - } - }, - findTabByMetadata: (metadata: Record) => { - const result = findTabByMetadata(metadata); - return result ? { tabId: result.tab.id } : null; - }, - updateTabContent: (tabId: string, content: OldPanelContent) => { - if (primaryGroup.tabs.find(t => t.id === tabId)) { - updateTabContent(tabId, 'primary', convertContent(content)); - } else if (secondaryGroup.tabs.find(t => t.id === tabId)) { - updateTabContent(tabId, 'secondary', convertContent(content)); - } - }, - closeAllTabs: () => { - closeAllTabs(); - }, - }), [ - addTab, - switchToTab, - findTabByMetadata, - updateTabContent, - closeAllTabs, - primaryGroup.tabs, - secondaryGroup.tabs, - convertContent, - ]); - - const prevWorkspaceIdRef = useRef(undefined); - - useLayoutEffect(() => { - const next = workspaceId; - const prev = prevWorkspaceIdRef.current; - if (prev === next) return; - - log.debug('Active workspace changed, swapping agent canvas snapshot', { - from: prev ?? '(none)', - to: next ?? '(none)', - }); - switchAgentCanvasWorkspace(prev ?? null, next ?? null); - prevWorkspaceIdRef.current = next; - }, [workspaceId]); - - useEffect(() => { - const removeListener = workspaceManager.addEventListener((event) => { - if (event.type === 'workspace:closed') { - removeAgentCanvasSnapshot(event.workspaceId); - } - }); - return () => removeListener(); - }, []); - - const handleInteraction = useCallback(async (itemId: string, userInput: string) => { - log.debug('Panel interaction', { itemId, userInput }); - }, []); - - const handleBeforeClose = useCallback(async (_content: any) => { - return true; - }, []); - - return ( -
- -
- ); - } -); - -AuxPane.displayName = 'AuxPane'; - -export default AuxPane; +/** + * Pure presentation adapter for the active auxiliary host. + * Host activation and tab ownership are handled by workspace navigation. + */ +export default function AuxPane({ + workspacePath, + isSceneActive = true, +}: AuxPaneProps) { + const activeHostKey = useAuxiliarySurfaceStore(state => state.activeHostKey); + const collapse = useAuxiliarySurfaceStore(state => state.collapse); + + const handleInteraction = useCallback(async (itemId: string, userInput: string) => { + log.debug('Panel interaction', { itemId, userInput }); + }, []); + + const handleRequestClose = useCallback(() => { + if (activeHostKey) collapse(activeHostKey, 'user'); + }, [activeHostKey, collapse]); + + return ( +
+ +
+ ); +} diff --git a/src/web-ui/src/app/scenes/session/SessionScene.tsx b/src/web-ui/src/app/scenes/session/SessionScene.tsx index 0ec9890c..f5ccebcb 100644 --- a/src/web-ui/src/app/scenes/session/SessionScene.tsx +++ b/src/web-ui/src/app/scenes/session/SessionScene.tsx @@ -12,25 +12,19 @@ import React, { useRef, useState, useCallback, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { useApp } from '../../hooks/useApp'; import { useSessionProfile } from '../../session-profiles'; import { useSessionGoalSnapshot } from '@/flow_chat/store/sessionGoalStore'; import ChatPane from './ChatPane'; -import AuxPane, { type AuxPaneRef } from './AuxPane'; +import AuxPane from './AuxPane'; import { - RIGHT_PANEL_CONFIG, - WIDE_WORKBENCH_RIGHT_PANEL_CONFIG, - WIDE_WORKBENCH_PRODUCT_APP_IDS, + AUXILIARY_SURFACE_CONFIG, PANEL_COMMON_CONFIG, - STORAGE_KEYS, PanelDisplayMode, getPanelDisplayMode, getModeWidth, getSnappedWidth, getNextMode, - savePanelWidth, - loadPanelWidth, } from '../../layout/panelConfig'; import { useActiveSession } from '@/flow_chat/store/modernFlowChatStore'; import { @@ -39,6 +33,10 @@ import { } from '@/flow_chat/domain/sessionLoadPhase'; import { DotMatrixLoader } from '@/design-system'; import { useCanvasStore } from '@/app/components/panels/content-canvas'; +import { + selectActiveAuxiliaryHostState, + useAuxiliarySurfaceStore, +} from '@/app/auxiliary-surface'; import './SessionScene.scss'; @@ -57,8 +55,12 @@ const SessionScene: React.FC = ({ isActive = true, }) => { const { t } = useTranslation('flow-chat'); - const { state, updateRightPanelWidth, toggleRightPanel } = useApp(); const { profile } = useSessionProfile(); + const activeAuxiliaryHost = useAuxiliarySurfaceStore(selectActiveAuxiliaryHostState); + const currentRightWidth = useAuxiliarySurfaceStore(store => store.width); + const updateAuxiliaryWidth = useAuxiliarySurfaceStore(store => store.setWidth); + const auxiliaryCollapsed = + !activeAuxiliaryHost || activeAuxiliaryHost.presentation === 'closed'; const activeSession = useActiveSession(); const [auxPaneReleasedSessionId, setAuxPaneReleasedSessionId] = useState(null); const hasBoundProductAppTab = useCanvasStore(state => ( @@ -91,43 +93,19 @@ const SessionScene: React.FC = ({ // Once the goal is completed the session returns to its normal look: drop the // focus frame. The banner stays (neutral) so the result is still visible/clearable. const hasGoalMode = goalSnapshot.phase !== 'none' && goalSnapshot.phase !== 'completed'; - const auxPaneRef = useRef(null); - const [isDragging, setIsDragging] = useState(false); const [isHovering, setIsHovering] = useState(false); - const rightPanelConfig = useMemo( - () => ( - productAppId && WIDE_WORKBENCH_PRODUCT_APP_IDS.has(productAppId) - ? WIDE_WORKBENCH_RIGHT_PANEL_CONFIG - : RIGHT_PANEL_CONFIG - ), - [productAppId], - ); - - const [, setLastRightWidth] = useState(() => - loadPanelWidth(STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, RIGHT_PANEL_CONFIG.COMFORTABLE_DEFAULT) - ); + const auxiliaryConfig = AUXILIARY_SURFACE_CONFIG; const containerRef = useRef(null); const resizerRef = useRef(null); const auxPaneElementRef = useRef(null); const animationFrameRef = useRef(null); - const autoSizedWorkbenchRef = useRef(null); - - const currentRightWidth = state.layout.rightPanelWidth || rightPanelConfig.COMFORTABLE_DEFAULT; - - const rightPanelMode: PanelDisplayMode = useMemo(() => { - if (state.layout.rightPanelCollapsed) return 'collapsed'; - return getPanelDisplayMode(currentRightWidth, rightPanelConfig); - }, [state.layout.rightPanelCollapsed, currentRightWidth, rightPanelConfig]); - - // Keep right panel visible when chat is hidden - useEffect(() => { - if (state.layout.chatCollapsed && state.layout.rightPanelCollapsed) { - toggleRightPanel(); - } - }, [state.layout.chatCollapsed, state.layout.rightPanelCollapsed, toggleRightPanel]); + const auxiliaryDisplayMode: PanelDisplayMode = useMemo(() => { + if (auxiliaryCollapsed) return 'collapsed'; + return getPanelDisplayMode(currentRightWidth, auxiliaryConfig); + }, [auxiliaryCollapsed, currentRightWidth, auxiliaryConfig]); const calculateValidRightWidth = useCallback((newWidth: number): number => { if (!containerRef.current) return newWidth; @@ -136,58 +114,21 @@ const SessionScene: React.FC = ({ const reserved = PANEL_COMMON_CONFIG.RESIZER_WIDTH + PANEL_COMMON_CONFIG.MIN_CENTER_WIDTH; const dynamicMax = containerWidth - reserved; const maxWidth = - dynamicMax < rightPanelConfig.COMPACT_WIDTH - ? rightPanelConfig.MAX_WIDTH - : Math.min(rightPanelConfig.MAX_WIDTH, dynamicMax); - return Math.min(maxWidth, Math.max(rightPanelConfig.COMPACT_WIDTH, newWidth)); - }, [rightPanelConfig]); + dynamicMax < auxiliaryConfig.COMPACT_WIDTH + ? auxiliaryConfig.MAX_WIDTH + : Math.min(auxiliaryConfig.MAX_WIDTH, dynamicMax); + return Math.min(maxWidth, Math.max(auxiliaryConfig.COMPACT_WIDTH, newWidth)); + }, [auxiliaryConfig]); const saveAndUpdateRightWidth = useCallback((width: number) => { - updateRightPanelWidth(width); - setLastRightWidth(width); - savePanelWidth(STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, width); - }, [updateRightPanelWidth]); + updateAuxiliaryWidth(width); + }, [updateAuxiliaryWidth]); const handleDoubleClick = useCallback(() => { - const nextMode = getNextMode(rightPanelMode); - const targetWidth = getModeWidth(nextMode, rightPanelConfig); + const nextMode = getNextMode(auxiliaryDisplayMode); + const targetWidth = getModeWidth(nextMode, auxiliaryConfig); saveAndUpdateRightWidth(calculateValidRightWidth(targetWidth)); - }, [rightPanelMode, rightPanelConfig, calculateValidRightWidth, saveAndUpdateRightWidth]); - - // Canvas-first Product Apps should enter at a usable workbench width. - useEffect(() => { - if (!productAppId || !WIDE_WORKBENCH_PRODUCT_APP_IDS.has(productAppId)) { - autoSizedWorkbenchRef.current = null; - return; - } - const workbenchKey = `${surfaceSessionId ?? 'active'}:${productAppId}`; - if (autoSizedWorkbenchRef.current === workbenchKey) return; - autoSizedWorkbenchRef.current = workbenchKey; - if ((state.layout.rightPanelWidth || 0) >= WIDE_WORKBENCH_RIGHT_PANEL_CONFIG.COMFORTABLE_DEFAULT) { - return; - } - saveAndUpdateRightWidth( - calculateValidRightWidth(WIDE_WORKBENCH_RIGHT_PANEL_CONFIG.COMFORTABLE_DEFAULT), - ); - }, [ - productAppId, - surfaceSessionId, - state.layout.rightPanelWidth, - calculateValidRightWidth, - saveAndUpdateRightWidth, - ]); - - useEffect(() => { - const handleProductAppPanelMode = (event: Event) => { - const detail = (event as CustomEvent<{ appId?: string; mode?: PanelDisplayMode }>).detail; - if (!productAppId || detail?.appId !== productAppId) return; - if (detail.mode !== 'comfortable' && detail.mode !== 'expanded') return; - const targetWidth = getModeWidth(detail.mode, rightPanelConfig); - saveAndUpdateRightWidth(calculateValidRightWidth(targetWidth)); - }; - window.addEventListener('product-app-request-panel-mode', handleProductAppPanelMode); - return () => window.removeEventListener('product-app-request-panel-mode', handleProductAppPanelMode); - }, [productAppId, rightPanelConfig, calculateValidRightWidth, saveAndUpdateRightWidth]); + }, [auxiliaryDisplayMode, auxiliaryConfig, calculateValidRightWidth, saveAndUpdateRightWidth]); const handleMouseDownResizer = useCallback((e: React.MouseEvent) => { e.preventDefault(); @@ -206,10 +147,10 @@ const SessionScene: React.FC = ({ animationFrameRef.current = requestAnimationFrame(() => { const valid = calculateValidRightWidth(startWidth + (startX - ev.clientX)); lastValidWidth = valid; - if (auxPaneElementRef.current && !state.layout.chatCollapsed) { + if (auxPaneElementRef.current) { auxPaneElementRef.current.style.width = `${valid}px`; } else { - updateRightPanelWidth(valid); + updateAuxiliaryWidth(valid); } animationFrameRef.current = null; }); @@ -222,13 +163,11 @@ const SessionScene: React.FC = ({ document.body.style.cursor = ''; document.body.style.userSelect = ''; - const snapped = getSnappedWidth(lastValidWidth, rightPanelConfig, false); + const snapped = getSnappedWidth(lastValidWidth, auxiliaryConfig, false); if (snapped !== lastValidWidth) { saveAndUpdateRightWidth(snapped); } else { - updateRightPanelWidth(lastValidWidth); - setLastRightWidth(lastValidWidth); - savePanelWidth(STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, lastValidWidth); + updateAuxiliaryWidth(lastValidWidth); } requestAnimationFrame(() => requestAnimationFrame(() => setIsDragging(false))); }; @@ -238,31 +177,16 @@ const SessionScene: React.FC = ({ }, [ currentRightWidth, calculateValidRightWidth, - updateRightPanelWidth, + updateAuxiliaryWidth, saveAndUpdateRightWidth, - state.layout.chatCollapsed, - rightPanelConfig, + auxiliaryConfig, ]); - // No-animation expansion - const [isAuxPaneExpandingImmediate, setIsAuxPaneExpandingImmediate] = useState(false); - - useEffect(() => { - const handler = (event: CustomEvent) => { - if (event.detail?.noAnimation && state.layout.rightPanelCollapsed) { - setIsAuxPaneExpandingImmediate(true); - setTimeout(() => setIsAuxPaneExpandingImmediate(false), 0); - } - }; - window.addEventListener('expand-right-panel-immediate', handler as EventListener); - return () => window.removeEventListener('expand-right-panel-immediate', handler as EventListener); - }, [state.layout.rightPanelCollapsed]); - // Responsive resize �?also validate on mount to clamp widths restored from localStorage. useEffect(() => { const validate = () => { const valid = calculateValidRightWidth(currentRightWidth); - if (valid !== currentRightWidth) updateRightPanelWidth(valid); + if (valid !== currentRightWidth) updateAuxiliaryWidth(valid); }; const rafId = requestAnimationFrame(validate); window.addEventListener('resize', validate); @@ -270,16 +194,13 @@ const SessionScene: React.FC = ({ cancelAnimationFrame(rafId); window.removeEventListener('resize', validate); }; - }, [currentRightWidth, calculateValidRightWidth, updateRightPanelWidth]); + }, [currentRightWidth, calculateValidRightWidth, updateAuxiliaryWidth]); // Cleanup animation frames useEffect(() => () => { if (animationFrameRef.current !== null) cancelAnimationFrame(animationFrameRef.current); }, []); - const isRightAsMain = state.layout.chatCollapsed; - const isChatHidden = state.layout.centerPanelCollapsed || isRightAsMain; - const panelModeLabels = useMemo(() => ({ collapsed: t('layout.panelMode.collapsed'), compact: t('layout.panelMode.compact'), @@ -314,78 +235,71 @@ const SessionScene: React.FC = ({ style={rootStyle} > {/* ChatPane �?FlowChat conversation */} - {!isChatHidden && ( -
- -
- )} +
+ +
{/* Resizer �?always rendered (when chat visible) for slide animation */} - {!isChatHidden && ( -
setIsHovering(true)} - onMouseLeave={() => setIsHovering(false)} - tabIndex={state.layout.rightPanelCollapsed ? -1 : 0} - role="separator" - aria-orientation="vertical" - aria-label={t('layout.resizer.rightAriaLabel')} - aria-valuenow={currentRightWidth} - aria-valuemin={rightPanelConfig.COMPACT_WIDTH} - aria-valuemax={rightPanelConfig.MAX_WIDTH} - title={t('layout.resizer.title', { mode: panelModeLabels[rightPanelMode] })} - > -
-
- - - - - - - - -
+ ].filter(Boolean).join(' ')} + onMouseDown={handleMouseDownResizer} + onDoubleClick={handleDoubleClick} + onMouseEnter={() => setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + tabIndex={auxiliaryCollapsed ? -1 : 0} + role="separator" + aria-orientation="vertical" + aria-label={t('layout.resizer.rightAriaLabel')} + aria-valuenow={currentRightWidth} + aria-valuemin={auxiliaryConfig.COMPACT_WIDTH} + aria-valuemax={auxiliaryConfig.MAX_WIDTH} + title={t('layout.resizer.title', { mode: panelModeLabels[auxiliaryDisplayMode] })} + > +
+
+ + + + + + + +
- )} +
{/* AuxPane �?ContentCanvas */}
{auxPaneReleased ? ( diff --git a/src/web-ui/src/app/scenes/session/index.ts b/src/web-ui/src/app/scenes/session/index.ts index d508ca04..779daac7 100644 --- a/src/web-ui/src/app/scenes/session/index.ts +++ b/src/web-ui/src/app/scenes/session/index.ts @@ -1,4 +1,3 @@ export { default as SessionScene } from './SessionScene'; export { default as ChatPane } from './ChatPane'; export { default as AuxPane } from './AuxPane'; -export type { AuxPaneRef } from './AuxPane'; diff --git a/src/web-ui/src/app/services/AppManager.ts b/src/web-ui/src/app/services/AppManager.ts index e80b946f..5c432810 100644 --- a/src/web-ui/src/app/services/AppManager.ts +++ b/src/web-ui/src/app/services/AppManager.ts @@ -11,16 +11,9 @@ import { AgentConfig, ChatSession, ChatMessage, - TabInfo, DEFAULT_LAYOUT_STATE, DEFAULT_AGENTS } from '../types'; -import { - loadPanelWidth, - savePanelWidth, - STORAGE_KEYS, - RIGHT_PANEL_CONFIG, -} from '../layout/panelConfig'; import { globalEventBus } from '../../infrastructure/event-bus'; import { createLogger } from '@/shared/utils/logger'; import { i18nService } from '@/infrastructure/i18n'; @@ -32,21 +25,13 @@ export class AppManager implements IAppManager { private listeners = new Set<(event: AppEvent) => void>(); constructor() { - // Clear legacy panel state data (run once) - this.clearPersistedPanelState(); - // Initialize state - const restoredRightWidth = loadPanelWidth( - STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, - DEFAULT_LAYOUT_STATE.rightPanelWidth - ); this.state = { layout: { ...DEFAULT_LAYOUT_STATE, leftPanelWidth: typeof window !== 'undefined' && window.innerWidth > 0 ? Math.min(300, Math.floor(window.innerWidth * 0.15)) // Left 15%, max 300px : 280, - rightPanelWidth: restoredRightWidth, }, currentAgent: DEFAULT_AGENTS[0], availableAgents: [...DEFAULT_AGENTS], @@ -72,31 +57,7 @@ export class AppManager implements IAppManager { } updateLayout(layout: Partial): void { - const prev = this.state.layout; - let newLayout = { ...prev, ...layout }; - - if (layout.rightPanelCollapsed === true && !prev.rightPanelCollapsed) { - savePanelWidth(STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, prev.rightPanelWidth); - } - if (layout.rightPanelCollapsed === false && prev.rightPanelCollapsed) { - const w = newLayout.rightPanelWidth; - if (w < RIGHT_PANEL_CONFIG.COMPACT_WIDTH) { - newLayout = { - ...newLayout, - rightPanelWidth: loadPanelWidth( - STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, - RIGHT_PANEL_CONFIG.COMFORTABLE_DEFAULT - ), - }; - } - } - if ( - typeof layout.rightPanelWidth === 'number' && - !newLayout.rightPanelCollapsed - ) { - savePanelWidth(STORAGE_KEYS.RIGHT_PANEL_LAST_WIDTH, layout.rightPanelWidth); - } - + const newLayout = { ...this.state.layout, ...layout }; this.state = { ...this.state, layout: newLayout }; this.notifyStateChange(); @@ -285,72 +246,6 @@ export class AppManager implements IAppManager { this.updateState({ extensions: updatedExtensions }); } - // Tab management - openTab(tab: Omit): string { - const tabId = `tab_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - const newTab: TabInfo = { ...tab, id: tabId }; - - const updatedTabs = [...this.state.layout.rightPanelTabs, newTab]; - const newLayout = { - ...this.state.layout, - rightPanelTabs: updatedTabs, - rightPanelActiveTabId: tabId, - rightPanelCollapsed: false // Auto-expand right panel - }; - - this.updateState({ layout: newLayout }); - - this.emitEvent({ - type: 'tab:opened', - payload: newTab - }); - - return tabId; - } - - closeTab(tabId: string): void { - const updatedTabs = this.state.layout.rightPanelTabs.filter(t => t.id !== tabId); - - let newActiveTabId = this.state.layout.rightPanelActiveTabId; - if (newActiveTabId === tabId) { - newActiveTabId = updatedTabs.length > 0 ? updatedTabs[updatedTabs.length - 1].id : null; - } - - const newLayout = { - ...this.state.layout, - rightPanelTabs: updatedTabs, - rightPanelActiveTabId: newActiveTabId, - rightPanelCollapsed: updatedTabs.length === 0 // Collapse when no tabs remain - }; - - this.updateState({ layout: newLayout }); - - this.emitEvent({ - type: 'tab:closed', - payload: { tabId } - }); - } - - selectTab(tabId: string): void { - const tab = this.state.layout.rightPanelTabs.find(t => t.id === tabId); - if (!tab) { - throw new Error(`Tab not found: ${tabId}`); - } - - const newLayout = { - ...this.state.layout, - rightPanelActiveTabId: tabId, - rightPanelCollapsed: false - }; - - this.updateState({ layout: newLayout }); - - this.emitEvent({ - type: 'tab:selected', - payload: { tabId } - }); - } - // Error handling clearError(): void { this.updateState({ error: null }); @@ -382,22 +277,6 @@ export class AppManager implements IAppManager { globalEventBus.emit('app:state:changed', this.state); } - // Clear legacy panel state data - private clearPersistedPanelState(): void { - try { - // Clear AppManager persisted state - localStorage.removeItem('sparo-app-state'); - - // Clear other potential panel state keys - localStorage.removeItem('Sparo-left-panel-width'); - localStorage.removeItem('Sparo-left-panel-collapsed'); - localStorage.removeItem('Sparo-right-panel-collapsed'); - localStorage.removeItem('right-panel-collapsed'); - } catch (error) { - log.warn('Failed to clear persisted panel state', error); - } - } - private setupEventListeners(): void { // Listen for global events globalEventBus.on('workspace:changed', () => { @@ -419,12 +298,8 @@ export class AppManager implements IAppManager { const windowWidth = window.innerWidth; // Left 15%, max 300px const newLeftPanelWidth = Math.min(300, Math.max(200, Math.floor(windowWidth * 0.15))); - // Center 50% - const newCenterPanelWidth = Math.max(400, Math.floor(windowWidth * 0.50)); - this.updateLayout({ leftPanelWidth: newLeftPanelWidth, - centerPanelWidth: newCenterPanelWidth }); }, 200); }; diff --git a/src/web-ui/src/app/session-profiles/index.ts b/src/web-ui/src/app/session-profiles/index.ts index bd4842d7..9ce8b945 100644 --- a/src/web-ui/src/app/session-profiles/index.ts +++ b/src/web-ui/src/app/session-profiles/index.ts @@ -27,7 +27,7 @@ export { export { SessionProfileProvider } from './SessionProfileProvider'; export { SessionProfileScope } from './SessionProfileScope'; export { useSessionProfile } from './useSessionProfile'; -export { openSessionSidecarPanel } from './sidecarActionController'; +export { openActiveSessionSidecarPanel } from './sidecarActionController'; // Individual profiles (useful for type-checking in tests or profile-specific imports) export { agenticOsProfile } from './profiles/agenticOsProfile'; diff --git a/src/web-ui/src/app/session-profiles/profiles/agenticOsProfile.ts b/src/web-ui/src/app/session-profiles/profiles/agenticOsProfile.ts index 21e663ee..276209ed 100644 --- a/src/web-ui/src/app/session-profiles/profiles/agenticOsProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/agenticOsProfile.ts @@ -3,14 +3,8 @@ import type { SessionProfile } from '../types'; export const agenticOsProfile: SessionProfile = { id: 'agentic-os', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: false, - }, - - auxTabs: { - // Agentic OS has no auto-opened tabs and no exclusive tab types. + auxiliarySurface: { + defaultVisibility: 'collapsed', }, capabilities: { diff --git a/src/web-ui/src/app/session-profiles/profiles/appBuilderProfile.ts b/src/web-ui/src/app/session-profiles/profiles/appBuilderProfile.ts index 33be7070..42b93bd0 100644 --- a/src/web-ui/src/app/session-profiles/profiles/appBuilderProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/appBuilderProfile.ts @@ -71,17 +71,11 @@ function buildPanel(sessionId: string, extra?: Record) { export const appBuilderProfile: SessionProfile = { id: 'app-builder', - layout: { - showChat: true, - defaultAuxPane: 'visible', - chatCollapsible: true, - }, - - auxTabs: { - autoOpen(sessionId, extra) { + auxiliarySurface: { + defaultVisibility: 'visible', + initialize(sessionId, extra) { return buildPanel(sessionId, extra); }, - exclusiveTabTypes: ['app-builder'], }, sidecarActions(sessionId, extra) { diff --git a/src/web-ui/src/app/session-profiles/profiles/bitfunCoderProfile.ts b/src/web-ui/src/app/session-profiles/profiles/bitfunCoderProfile.ts index 9c39f248..d61983bd 100644 --- a/src/web-ui/src/app/session-profiles/profiles/bitfunCoderProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/bitfunCoderProfile.ts @@ -4,14 +4,8 @@ import type { SessionProfile } from '../types'; export const bitfunCoderProfile: SessionProfile = { id: 'bitfun-coder', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: true, - }, - - auxTabs: { - // No auto-opened tabs; user opens editor/diff tabs via tool calls. + auxiliarySurface: { + defaultVisibility: 'collapsed', }, composer: { diff --git a/src/web-ui/src/app/session-profiles/profiles/coworkProfile.ts b/src/web-ui/src/app/session-profiles/profiles/coworkProfile.ts index ede39c7e..30cacafe 100644 --- a/src/web-ui/src/app/session-profiles/profiles/coworkProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/coworkProfile.ts @@ -3,14 +3,10 @@ import type { SessionProfile } from '../types'; export const coworkProfile: SessionProfile = { id: 'cowork', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: true, + auxiliarySurface: { + defaultVisibility: 'collapsed', }, - auxTabs: {}, - capabilities: { showWelcomePanel: true, showAgenticOsModelRoundUI: false, diff --git a/src/web-ui/src/app/session-profiles/profiles/deepResearchProfile.ts b/src/web-ui/src/app/session-profiles/profiles/deepResearchProfile.ts index a450c933..398de781 100644 --- a/src/web-ui/src/app/session-profiles/profiles/deepResearchProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/deepResearchProfile.ts @@ -3,14 +3,10 @@ import type { SessionProfile } from '../types'; export const deepResearchProfile: SessionProfile = { id: 'deep-research', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: true, + auxiliarySurface: { + defaultVisibility: 'collapsed', }, - auxTabs: {}, - capabilities: { showWelcomePanel: true, showAgenticOsModelRoundUI: false, diff --git a/src/web-ui/src/app/session-profiles/profiles/designProfile.ts b/src/web-ui/src/app/session-profiles/profiles/designProfile.ts index b0dd7104..e450e820 100644 --- a/src/web-ui/src/app/session-profiles/profiles/designProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/designProfile.ts @@ -3,14 +3,10 @@ import type { SessionProfile } from '../types'; export const designProfile: SessionProfile = { id: 'design', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: true, + auxiliarySurface: { + defaultVisibility: 'collapsed', }, - auxTabs: {}, - sidecarActions(sessionId, extra) { const workspacePath = extra?.workspacePath as string | undefined; return [ diff --git a/src/web-ui/src/app/session-profiles/profiles/productAppRuntimeProfile.ts b/src/web-ui/src/app/session-profiles/profiles/productAppRuntimeProfile.ts index 968b841e..c9c34a8b 100644 --- a/src/web-ui/src/app/session-profiles/profiles/productAppRuntimeProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/productAppRuntimeProfile.ts @@ -8,8 +8,6 @@ import type { TabAutoOpenDescriptor, } from '../types'; -const RUNTIME_EXCLUSIVE_TAB_TYPES = ['product-app-runtime'] as const; - function getRuntimeBinding(extra?: Record): ProductAppRuntimeSessionMetadata | null { const binding = extra?.productAppRuntime; if (!binding || typeof binding !== 'object') return null; @@ -102,19 +100,12 @@ function createProductAppRuntimeProfile( return { id, - layout: { - showChat: true, - defaultAuxPane: 'visible', - chatCollapsible: true, - }, - - auxTabs: { - autoOpen(sessionId, extra) { + auxiliarySurface: { + defaultVisibility: 'visible', + initialize(sessionId, extra) { const binding = getRuntimeBinding(extra); return binding ? buildDefaultRuntimeTabDescriptors(sessionId, binding) : null; }, - - exclusiveTabTypes: RUNTIME_EXCLUSIVE_TAB_TYPES, }, sidecarActions(sessionId, extra) { diff --git a/src/web-ui/src/app/session-profiles/profiles/runnoProfile.ts b/src/web-ui/src/app/session-profiles/profiles/runnoProfile.ts index 60b06382..c2f80864 100644 --- a/src/web-ui/src/app/session-profiles/profiles/runnoProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/runnoProfile.ts @@ -4,14 +4,10 @@ import type { SessionProfile } from '../types'; export const runnoProfile: SessionProfile = { id: 'runno', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: true, + auxiliarySurface: { + defaultVisibility: 'collapsed', }, - auxTabs: {}, - composer: { visibility: { showActionButtonWhenCollapsed: true, diff --git a/src/web-ui/src/app/session-profiles/profiles/settingsProfile.ts b/src/web-ui/src/app/session-profiles/profiles/settingsProfile.ts index fe26ba7f..41bcab21 100644 --- a/src/web-ui/src/app/session-profiles/profiles/settingsProfile.ts +++ b/src/web-ui/src/app/session-profiles/profiles/settingsProfile.ts @@ -4,14 +4,10 @@ import type { SessionProfile } from '../types'; export const settingsProfile: SessionProfile = { id: 'settings', - layout: { - showChat: true, - defaultAuxPane: 'collapsed', - chatCollapsible: false, + auxiliarySurface: { + defaultVisibility: 'collapsed', }, - auxTabs: {}, - composer: { visibility: { showActionButtonWhenCollapsed: false, diff --git a/src/web-ui/src/app/session-profiles/sidecarActionController.ts b/src/web-ui/src/app/session-profiles/sidecarActionController.ts index 901d51e4..ce835345 100644 --- a/src/web-ui/src/app/session-profiles/sidecarActionController.ts +++ b/src/web-ui/src/app/session-profiles/sidecarActionController.ts @@ -1,91 +1,14 @@ -import { TAB_EVENTS, type CreateTabEventDetail } from '@/app/components/panels/content-canvas/types'; -import { useAgentCanvasStore } from '@/app/components/panels/content-canvas/stores'; -import type { PanelContent } from '@/app/components/panels/content-canvas/types'; +import { openActiveAuxiliaryItem } from '@/app/auxiliary-surface'; import { createLogger } from '@/shared/utils/logger'; import type { TabAutoOpenDescriptor } from './types'; const log = createLogger('SessionSidecarActions'); -function expandRightPanel(): void { - window.dispatchEvent(new CustomEvent(TAB_EVENTS.EXPAND_RIGHT_PANEL)); -} - -function openAgentCanvasTab(detail: CreateTabEventDetail): void { - const { - type, - title, - data, - metadata, - checkDuplicate, - duplicateCheckKey, - replaceExisting, - targetGroup, - enableSplitView, - } = detail; - - const store = useAgentCanvasStore.getState(); - const content: PanelContent = { - type, - title, - data, - metadata: duplicateCheckKey - ? { ...metadata, duplicateCheckKey } - : metadata, - }; - - if (enableSplitView && store.layout.splitMode === 'none') { - store.setSplitMode('vertical'); - } - - if (checkDuplicate && duplicateCheckKey) { - const existing = store.findTabByMetadata({ duplicateCheckKey }); - if (existing) { - const hasJumpInfo = data?.jumpToRange || data?.jumpToLine || data?.jumpToColumn; - if (replaceExisting || hasJumpInfo) { - store.updateTabContent(existing.tab.id, existing.groupId, content); - } - store.switchToTab(existing.tab.id, existing.groupId); - if (existing.tab.state === 'preview') { - store.promoteTab(existing.tab.id, existing.groupId); - } - expandRightPanel(); - return; - } - } - - const groupId = (enableSplitView && targetGroup) - ? targetGroup - : targetGroup || store.activeGroupId; - store.addTab(content, 'active', groupId); - expandRightPanel(); -} - -export function openSessionSidecarPanel(panel: TabAutoOpenDescriptor): void { - const duplicateCheckKey = - panel.duplicateCheckKey ?? - (typeof panel.metadata?.duplicateCheckKey === 'string' - ? panel.metadata.duplicateCheckKey - : undefined); - - const detail: CreateTabEventDetail = { - type: panel.type, - title: panel.title, - data: panel.data, - metadata: duplicateCheckKey - ? { ...panel.metadata, duplicateCheckKey } - : panel.metadata, - checkDuplicate: Boolean(duplicateCheckKey), - duplicateCheckKey, - replaceExisting: panel.replaceExisting ?? true, - targetGroup: panel.targetGroup, - enableSplitView: panel.enableSplitView, - }; - - log.debug('Opening session sidecar panel', { +export function openActiveSessionSidecarPanel(panel: TabAutoOpenDescriptor): boolean { + log.debug('Opening active session sidecar panel', { type: panel.type, - duplicateCheckKey, + duplicateCheckKey: panel.duplicateCheckKey, title: panel.title, }); - - openAgentCanvasTab(detail); + return openActiveAuxiliaryItem(panel); } diff --git a/src/web-ui/src/app/session-profiles/types.ts b/src/web-ui/src/app/session-profiles/types.ts index b3d6e14f..a2b40c36 100644 --- a/src/web-ui/src/app/session-profiles/types.ts +++ b/src/web-ui/src/app/session-profiles/types.ts @@ -5,7 +5,7 @@ * Register profiles in SessionProfileRegistry; consume via useSessionProfile(). */ -import type { PanelContentType } from '../components/panels/base/types'; +import type { AuxiliaryItemDescriptor } from '@/app/auxiliary-surface/types'; import type { SessionProfileId } from '@/flow_chat/domain/sessionDescriptor'; import type { Session } from '@/flow_chat/types/flow-chat'; import type { AgentSessionBindingMetadata } from '@/shared/types/session-history'; @@ -14,17 +14,7 @@ import type { AgentSessionBindingMetadata } from '@/shared/types/session-history * Descriptor for a tab that a Profile wants to auto-open * when the matching session becomes active. */ -export interface TabAutoOpenDescriptor { - type: PanelContentType; - title: string; - data?: Record; - metadata?: Record; - /** Prevent duplicate tabs of the same key. */ - duplicateCheckKey?: string; - replaceExisting?: boolean; - targetGroup?: 'primary' | 'secondary'; - enableSplitView?: boolean; -} +export type TabAutoOpenDescriptor = AuxiliaryItemDescriptor; export type TabAutoOpenResult = | TabAutoOpenDescriptor @@ -148,26 +138,13 @@ export interface SessionProfile { /** Unique stable identifier for this profile. */ readonly id: SessionProfileId; - readonly layout: { - /** Whether the ChatPane (conversation area) is shown. */ - showChat: boolean; - /** Initial AuxPane visibility when a session of this type becomes active. */ - defaultAuxPane: 'collapsed' | 'visible'; - /** Whether the user may collapse/expand the chat pane. */ - chatCollapsible: boolean; - }; - - readonly auxTabs: { - /** - * Called when a session of this profile becomes active. - * Return a TabAutoOpenDescriptor to auto-open a tab, or null to skip. - */ - autoOpen?: (sessionId: string, extra?: Record) => TabAutoOpenResult; + readonly auxiliarySurface: { + /** Initial visibility when this profile first contributes content to a host. */ + defaultVisibility: 'collapsed' | 'visible'; /** - * Tab types that belong exclusively to this profile. - * When switching away from this profile these tab types are closed. + * Called once when a ready session first initializes its auxiliary host. */ - exclusiveTabTypes?: readonly PanelContentType[]; + initialize?: (sessionId: string, extra?: Record) => TabAutoOpenResult; }; /** diff --git a/src/web-ui/src/app/types/index.ts b/src/web-ui/src/app/types/index.ts index 39fd0f8b..1faddaf0 100644 --- a/src/web-ui/src/app/types/index.ts +++ b/src/web-ui/src/app/types/index.ts @@ -37,25 +37,7 @@ export type PanelType = 'sessions' | 'files' | 'terminal' | 'capabilities' | 'ag export interface LayoutState { leftPanelWidth: number; leftPanelCollapsed: boolean; - centerPanelWidth: number; - centerPanelCollapsed: boolean; - chatCollapsed: boolean; - rightPanelWidth: number; // Fixed right panel width - rightPanelCollapsed: boolean; leftPanelActiveTab: PanelType; - rightPanelTabs: TabInfo[]; - rightPanelActiveTabId: string | null; -} - -// Tab info -export interface TabInfo { - id: string; - title: string; - type: 'file' | 'diff' | 'extension' | 'chat' | 'preview'; - content?: any; - isClosable: boolean; - isDirty?: boolean; - metadata?: Record; } // Chat types @@ -114,9 +96,6 @@ export type AppEvent = | { type: 'chat:session:selected'; payload: ChatSession } | { type: 'extension:enabled'; payload: Extension } | { type: 'extension:disabled'; payload: Extension } - | { type: 'tab:opened'; payload: TabInfo } - | { type: 'tab:closed'; payload: { tabId: string } } - | { type: 'tab:selected'; payload: { tabId: string } } | { type: 'error:occurred'; payload: { error: string } }; // App manager interface @@ -138,11 +117,6 @@ export interface IAppManager { disableExtension(extensionId: string): Promise; configureExtension(extensionId: string, config: Record): Promise; - // Tab management - openTab(tab: Omit): string; - closeTab(tabId: string): void; - selectTab(tabId: string): void; - // Event listeners addEventListener(listener: (event: AppEvent) => void): () => void; } @@ -184,13 +158,8 @@ export interface UseAppReturn { // Layout actions toggleLeftPanel: () => void; - toggleCenterPanel: () => void; - toggleRightPanel: () => void; - toggleChatPanel: () => void; switchLeftPanelTab: (tab: PanelType) => void; updateLeftPanelWidth: (width: number, options?: { persist?: boolean }) => void; - updateCenterPanelWidth: (width: number) => void; - updateRightPanelWidth: (width: number) => void; // Agent actions - selectAgent removed; backend decides agent selection updateAgentConfig: (agentId: string, config: Partial) => Promise; @@ -204,11 +173,6 @@ export interface UseAppReturn { enableExtension: (extensionId: string) => Promise; disableExtension: (extensionId: string) => Promise; - // Tab actions - openTab: (tab: Omit) => string; - closeTab: (tabId: string) => void; - selectTab: (tabId: string) => void; - // Utility clearError: () => void; } @@ -221,18 +185,7 @@ export const DEFAULT_LAYOUT_STATE: LayoutState = { ? Math.min(400, Math.floor(window.innerWidth * 0.15)) // Left 15%, max 400px : 280, leftPanelCollapsed: false, - centerPanelWidth: typeof window !== 'undefined' - ? Math.floor(window.innerWidth * 0.50) // Kept for compatibility - : 960, - centerPanelCollapsed: false, - chatCollapsed: false, - rightPanelWidth: typeof window !== 'undefined' - ? Math.max(540, Math.min(800, Math.floor(window.innerWidth * 0.35))) // Right 35%, min 540px (for config-tabs), max 800px - : 540, - rightPanelCollapsed: true, leftPanelActiveTab: 'sessions', // Default to sessions list - rightPanelTabs: [], - rightPanelActiveTabId: null }; // Default agents diff --git a/src/web-ui/src/design-system/preview/FocusedPreview.css b/src/web-ui/src/design-system/preview/FocusedPreview.css new file mode 100644 index 00000000..d1500dfc --- /dev/null +++ b/src/web-ui/src/design-system/preview/FocusedPreview.css @@ -0,0 +1,262 @@ +.focused-preview { + height: 100%; + min-height: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + overflow: hidden; + background: var(--color-bg-secondary); +} + +.focused-preview__header { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: start; + gap: 32px; + padding: 26px clamp(28px, 3.6vw, 52px) 23px; + border-bottom: 1px solid var(--border-subtle); + background: var(--color-bg-secondary); +} + +.focused-preview__title-group, +.focused-preview__heading > div { + min-width: 0; +} + +.focused-preview__eyebrow { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 10px; + color: var(--color-text-muted); + font-size: 9px; + font-weight: 700; + letter-spacing: 0.09em; + text-transform: uppercase; +} + +.focused-preview__eyebrow span + span::before { + content: '/'; + margin-right: 8px; + color: var(--border-base); +} + +.focused-preview__heading { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 28px; +} + +.focused-preview__heading h2 { + margin: 0; + color: var(--color-text-primary); + font-size: clamp(26px, 2.5vw, 34px); + font-weight: 650; + letter-spacing: -0.035em; + line-height: 1.08; +} + +.focused-preview__heading p { + max-width: 720px; + margin: 8px 0 0; + color: var(--color-text-secondary); + font-size: 12px; + line-height: 1.55; +} + +.focused-preview__heading code { + max-width: 240px; + overflow: hidden; + padding-top: 7px; + color: var(--color-text-muted); + font-family: var(--tool-card-font-mono, 'Courier New', monospace); + font-size: 9px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.focused-preview__controls, +.focused-preview__stepper { + display: flex; + align-items: center; +} + +.focused-preview__controls { + gap: 12px; + padding-top: 13px; +} + +.focused-preview__stepper { + gap: 3px; +} + +.focused-preview__stepper > span { + min-width: 54px; + color: var(--color-text-secondary); + font-family: var(--tool-card-font-mono, 'Courier New', monospace); + font-size: 9px; + text-align: center; +} + +.focused-preview__stepper i { + margin: 0 5px; + color: var(--border-base); + font-style: normal; +} + +.focused-preview__usage-trigger { + gap: 6px; + color: var(--color-text-secondary); +} + +.focused-preview__body { + position: relative; + min-height: 0; + overflow: hidden; +} + +.focused-preview__stage { + width: 100%; + height: 100%; + min-height: 0; + display: flex; + align-items: stretch; + justify-content: center; + overflow: auto; + padding: clamp(26px, 3.8vw, 52px); + scrollbar-width: thin; +} + +.focused-preview__viewport { + min-width: 0; +} + +.focused-preview--primitive .focused-preview__stage { + align-items: center; + background: var(--color-bg-secondary); +} + +.focused-preview--primitive .focused-preview__viewport { + width: min(100%, 900px); + display: flex; + align-items: center; + justify-content: center; +} + +.focused-preview--pattern .focused-preview__stage, +.focused-preview--recipe .focused-preview__stage { + align-items: flex-start; + background: var(--color-bg-primary); +} + +.focused-preview--pattern .focused-preview__viewport { + width: min(100%, 1280px); +} + +.focused-preview--recipe .focused-preview__viewport { + width: min(100%, 1120px); +} + +.focused-preview--pattern .focused-preview__viewport > *, +.focused-preview--recipe .focused-preview__viewport > * { + width: 100%; +} + +.focused-preview__inspector { + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: min(340px, 88%); + overflow-y: auto; + padding: 0 22px 24px; + border-left: 1px solid var(--border-subtle); + background: var(--color-bg-secondary); + scrollbar-width: thin; +} + +.focused-preview__inspector-header { + position: sticky; + top: 0; + min-height: 54px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + border-bottom: 1px solid var(--border-subtle); + background: var(--color-bg-secondary); + color: var(--color-text-primary); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.focused-preview__inspector .preview-usage-guide { + width: 100%; + border: 0; + background: transparent; +} + +.focused-preview__inspector .preview-usage-guide__panel-meta { + padding: 16px 0 2px; + color: var(--color-text-muted); + font-size: 10px; +} + +.focused-preview__inspector .preview-usage-guide__body { + padding: 12px 0 0; +} + +.focused-preview__inspector .preview-usage-guide__grid { + grid-template-columns: 1fr; + gap: 20px; +} + +@media (max-width: 900px) { + .focused-preview__header { + gap: 20px; + padding: 22px; + } + + .focused-preview__heading code { + display: none; + } + + .focused-preview__controls { + gap: 6px; + } + + .focused-preview__usage-trigger { + padding-inline: 8px; + } + + .focused-preview__stage { + padding: 22px; + } +} + +@media (max-width: 700px) { + .focused-preview__header { + grid-template-columns: 1fr; + gap: 14px; + padding: 18px 14px 15px; + } + + .focused-preview__heading h2 { + font-size: 24px; + } + + .focused-preview__controls { + justify-content: space-between; + padding-top: 0; + } + + .focused-preview__stage { + padding: 18px 14px; + } + + .focused-preview__inspector { + width: 100%; + } +} diff --git a/src/web-ui/src/design-system/preview/FocusedPreview.tsx b/src/web-ui/src/design-system/preview/FocusedPreview.tsx new file mode 100644 index 00000000..690f09c4 --- /dev/null +++ b/src/web-ui/src/design-system/preview/FocusedPreview.tsx @@ -0,0 +1,124 @@ +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ChevronLeft, ChevronRight, PanelRightOpen, X } from 'lucide-react'; +import { Button, IconButton } from '@/design-system'; +import type { PreviewCategory, PreviewExample } from '@/design-system/types'; +import { PreviewUsageGuide } from './PreviewUsageGuide'; +import './FocusedPreview.css'; + +interface FocusedPreviewProps { + category: PreviewCategory; + example: PreviewExample; + index: number; + total: number; + previousExample: PreviewExample; + nextExample: PreviewExample; + onPrevious: () => void; + onNext: () => void; +} + +export const FocusedPreview: React.FC = ({ + category, + example, + index, + total, + previousExample, + nextExample, + onPrevious, + onNext, +}) => { + const Example = example.render; + const tier = category.tier ?? 'primitive'; + const [isUsageOpen, setIsUsageOpen] = useState(false); + const { t } = useTranslation('design-system/preview'); + + return ( +
+
+
+
+ {t(`focused.tiers.${tier}`)} + {category.name} +
+
+
+

{example.name}

+

{example.description}

+
+ {example.id} +
+
+ +
+ + +
+
+ +
+
+
+ +
+
+ + {isUsageOpen && ( + + )} +
+
+ ); +}; diff --git a/src/web-ui/src/design-system/preview/PreviewApp.tsx b/src/web-ui/src/design-system/preview/PreviewApp.tsx index f0ac592b..2ace49b6 100644 --- a/src/web-ui/src/design-system/preview/PreviewApp.tsx +++ b/src/web-ui/src/design-system/preview/PreviewApp.tsx @@ -1,8 +1,15 @@ -import React, { useMemo, useState } from 'react'; +import React, { useMemo, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { designSystemPreviewCategories } from '@/design-system/preview/registries'; import type { PreviewCategory } from '../types'; -import { FullPageLayout, LargeCardLayout, GridLayout, DemoLayout, ColumnLayout } from './layouts'; -import { IconButton, Select, type SelectOption } from '@/design-system'; +import { FocusedPreview } from './FocusedPreview'; +import { + IconButton, + Search, + Select, + SparoLogoMark, + type SelectOption, +} from '@/design-system'; import { builtinThemes } from '@/infrastructure/theme/presets'; import { applyCssVars, @@ -11,20 +18,75 @@ import { createThemeCssVarMap, type ThemeConfig, } from '@/design-system/foundation/tokens'; -import { PanelLeftClose } from 'lucide-react'; +import { builtinLocales } from '@/infrastructure/i18n'; +import { + Blocks, + BookOpen, + Box, + Languages, + PanelLeftClose, + SunMedium, +} from 'lucide-react'; import './preview.css'; +const PREVIEW_NAMESPACE = 'design-system/preview' as const; + +function TierIcon({ category }: { category: PreviewCategory }) { + if (category.tier === 'pattern') { + return
diff --git a/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.test.ts b/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.test.ts new file mode 100644 index 00000000..40dccdfc --- /dev/null +++ b/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.test.ts @@ -0,0 +1,124 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import type { ActiveAppRef } from '@/infrastructure/api/service-api/IntelligentAppAPI'; +import { launchActiveIntelligentApp } from './intelligentAppLaunchService'; + +const mocks = vi.hoisted(() => ({ + openProductAppRuntime: vi.fn(), +})); + +vi.mock('./product-app-runtime/productAppRuntimeService', () => ({ + openProductAppRuntime: mocks.openProductAppRuntime, +})); + +vi.mock('./app-builder/openAppBuilderSession', () => ({ + createAndOpenAppBuilder: vi.fn(), +})); + +vi.mock('@/app/agentic-os/work/data/workStore', () => ({ + useWorkStore: { getState: vi.fn() }, +})); + +vi.mock('@/app/agentic-os/work/domain/productAppRefs', () => ({ + productAppWorkRef: vi.fn(), +})); + +vi.mock('@/app/agentic-os/work/navigation/openWork', () => ({ + openWork: vi.fn(), +})); + +vi.mock('@/app/stores/sessionModeStore', () => ({ + useSessionModeStore: { getState: vi.fn() }, +})); + +vi.mock('@/app/session-profiles', () => ({ + resolveSessionTypeDefinitionForDescriptor: vi.fn(), +})); + +vi.mock('@/flow_chat/domain/sessionDescriptor', () => ({ + descriptorFromAgentType: vi.fn(), + getBackendAgentType: vi.fn(), +})); + +function applicationSurfaceApp(): ActiveAppRef { + return { + slotId: 'builtin-ppt-live', + appId: 'builtin-ppt-live', + releaseId: 'release-ppt-live', + configRevision: 'config-ppt-live', + dataSchemaVersion: '1', + runtime: { + launch: { + kind: 'applicationSurface', + targetId: 'builtin-ppt-live', + scopeRequirement: 'workspaceOptional', + }, + primarySurface: { + componentId: 'builtin-ppt-live-surface', + surfaceId: 'primary', + }, + primarySurfaceMode: 'immersivePrimary', + workMultiplicity: 'multiple', + icon: { kind: 'builtin', name: 'presentation' }, + category: 'productivity', + tags: [], + }, + }; +} + +describe('launchActiveIntelligentApp intent', () => { + beforeEach(() => { + vi.clearAllMocks(); + mocks.openProductAppRuntime.mockResolvedValue(undefined); + }); + + it('maps an explicit new-object intent to fresh Work creation', async () => { + await launchActiveIntelligentApp(applicationSurfaceApp(), { + title: 'New presentation', + intent: { kind: 'create_new' }, + }); + + expect(mocks.openProductAppRuntime).toHaveBeenCalledWith( + expect.objectContaining({ appId: 'builtin-ppt-live' }), + expect.objectContaining({ + title: 'New presentation', + workMode: 'create', + }), + ); + }); + + it('maps an explicit resume intent to the most recent compatible Work', async () => { + await launchActiveIntelligentApp(applicationSurfaceApp(), { + title: 'PPT Live', + intent: { kind: 'resume_last' }, + }); + + expect(mocks.openProductAppRuntime).toHaveBeenCalledWith( + expect.objectContaining({ appId: 'builtin-ppt-live' }), + expect.objectContaining({ + title: 'PPT Live', + workMode: 'resume', + }), + ); + }); + + it('maps an existing-object intent and preserves the selected source Work', async () => { + const sourceWorkLocator = { + scope: { kind: 'workspace' as const, workspaceId: 'ws_project' }, + workId: 'work-source', + }; + + await launchActiveIntelligentApp(applicationSurfaceApp(), { + title: 'Presentation', + intent: { kind: 'create_for_existing_object', sourceWorkLocator }, + }); + + expect(mocks.openProductAppRuntime).toHaveBeenCalledWith( + expect.objectContaining({ appId: 'builtin-ppt-live' }), + expect.objectContaining({ + title: 'Presentation', + workMode: 'existing_object', + sourceWorkLocator, + }), + ); + }); +}); diff --git a/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.ts b/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.ts index bdca7131..ceddca71 100644 --- a/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.ts +++ b/src/web-ui/src/app/scenes/apps/intelligentAppLaunchService.ts @@ -1,6 +1,6 @@ import { useWorkStore } from '@/app/agentic-os/work/data/workStore'; import { productAppWorkRef } from '@/app/agentic-os/work/domain/productAppRefs'; -import type { WorkRecord } from '@/app/agentic-os/work/domain/workTypes'; +import type { WorkLocator, WorkRecord } from '@/app/agentic-os/work/domain/workTypes'; import { openWork } from '@/app/agentic-os/work/navigation/openWork'; import { useSessionModeStore, type SessionMode } from '@/app/stores/sessionModeStore'; import { resolveSessionTypeDefinitionForDescriptor } from '@/app/session-profiles'; @@ -19,8 +19,19 @@ export interface LaunchIntelligentAppOptions { scope?: AppScope | null; title: string; objective?: string; - /** Resume the most recent compatible Work unless the user explicitly asks for a new one. */ - workMode?: 'resume' | 'create'; + /** User intent must stay explicit so a create entry point can never silently resume old Work. */ + intent: IntelligentAppLaunchIntent; +} + +export type IntelligentAppLaunchIntent = + | { kind: 'create_new' } + | { kind: 'create_for_existing_object'; sourceWorkLocator: WorkLocator } + | { kind: 'resume_last' }; + +function workModeFromIntent(intent: IntelligentAppLaunchIntent): 'resume' | 'create' | 'existing_object' { + if (intent.kind === 'create_new') return 'create'; + if (intent.kind === 'create_for_existing_object') return 'existing_object'; + return 'resume'; } function agentTypeFor(app: ActiveAppRef): string | null { @@ -99,9 +110,22 @@ export async function launchActiveIntelligentApp( throw new Error(`App ${app.appId} requires a workspace scope`); } const agentType = agentTypeFor(app); + const workMode = workModeFromIntent(options.intent); if (agentType) { - await openAgentAppWork(app, scope, title, objective, agentType, options.workMode ?? 'resume'); + if (options.intent.kind === 'create_for_existing_object') { + throw new Error( + `App ${app.appId} does not support starting agent-session Work for an existing WorkObject`, + ); + } + await openAgentAppWork( + app, + scope, + title, + objective, + agentType, + options.intent.kind === 'create_new' ? 'create' : 'resume', + ); return; } if (launch?.kind === 'applicationSurface') { @@ -109,7 +133,10 @@ export async function launchActiveIntelligentApp( scope, title, objective, - workMode: options.workMode ?? 'resume', + workMode, + sourceWorkLocator: options.intent.kind === 'create_for_existing_object' + ? options.intent.sourceWorkLocator + : undefined, }); return; } diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/ProductAppRuntimeIframeHost.tsx b/src/web-ui/src/app/scenes/apps/product-app-runtime/ProductAppRuntimeIframeHost.tsx index ffc3566e..c5a3bcd0 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/ProductAppRuntimeIframeHost.tsx +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/ProductAppRuntimeIframeHost.tsx @@ -399,7 +399,6 @@ const ProductAppRuntimeIframeHost: React.FC = const { theme } = useTheme(); const { currentLanguage } = useI18n(); const displayMeta = resolveProductAppHostSurfaceMeta(app, currentLanguage); - const locksViewportScroll = app.id === 'builtin-spark-board'; const normalizedRoute = useMemo(() => route?.trim() || '/', [route]); const effectiveScope = useMemo( () => normalizeAppScope( @@ -810,10 +809,7 @@ const ProductAppRuntimeIframeHost: React.FC = onLoad={handlePreviewLoad} sandbox="allow-scripts allow-forms allow-modals allow-popups allow-downloads" allow={iframeFeaturePolicy(app)} - scrolling={locksViewportScroll ? 'no' : undefined} style={{ - overflow: locksViewportScroll ? 'hidden' : undefined, - overscrollBehavior: locksViewportScroll ? 'none' : undefined, background: 'var(--ds-color-bg-app)', }} title={displayMeta.name} diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeOpenTypes.ts b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeOpenTypes.ts index 79eaba0c..46e79fca 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeOpenTypes.ts +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeOpenTypes.ts @@ -1,4 +1,5 @@ import type { WorkspaceSurfaceContext } from '@/app/navigation/workspaceSurfaceTypes'; +import type { WorkLocator } from '@/app/agentic-os/work/domain/workTypes'; import type { AppScope } from '@/shared/types/app-scope'; import type { ProductAppWorkMultiplicity } from '@/shared/types/app-manifest'; import type { ProductAppRuntimeContext } from '@/shared/types/product-app-runtime'; @@ -9,7 +10,9 @@ import type { export interface OpenProductAppRuntimeOptions { /** Resume the most recent compatible Work by default; create is always explicit. */ - workMode?: 'resume' | 'create'; + workMode?: 'resume' | 'create' | 'existing_object'; + /** Source Work whose primary WorkObject the new Work should share. */ + sourceWorkLocator?: WorkLocator | null; entityId?: string | null; locale?: string | null; workspacePath?: string | null; diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.test.ts b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.test.ts index b9d64ef8..4aefecaf 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.test.ts +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.test.ts @@ -5,6 +5,7 @@ import { openProductAppRuntime } from './productAppRuntimeService'; const mocks = vi.hoisted(() => ({ createWork: vi.fn(), + createWorkForObject: vi.fn(), resolveAppWork: vi.fn(), deleteWork: vi.fn(), requestWorkRefresh: vi.fn(), @@ -19,6 +20,7 @@ vi.mock('@/app/agentic-os/work/data/workStore', () => ({ useWorkStore: { getState: () => ({ createWork: mocks.createWork, + createWorkForObject: mocks.createWorkForObject, resolveAppWork: mocks.resolveAppWork, deleteWork: mocks.deleteWork, }), @@ -92,6 +94,7 @@ describe('openProductAppRuntime work multiplicity', () => { beforeEach(() => { vi.clearAllMocks(); mocks.createWork.mockResolvedValue(work('work-new')); + mocks.createWorkForObject.mockResolvedValue(work('work-shared-object')); mocks.resolveAppWork.mockResolvedValue({ work: work('work-existing'), created: false }); mocks.deleteWork.mockResolvedValue({ deleted: true }); mocks.resolveRuntime.mockImplementation(async ({ locator }) => ({ @@ -185,6 +188,86 @@ describe('openProductAppRuntime work multiplicity', () => { expect(mocks.openRuntimeHost).toHaveBeenCalledAfter(mocks.backendCall); }); + it('attaches a new Work to the same existing WorkObject before opening it', async () => { + mocks.getHostSurface.mockResolvedValue({ + id: 'runtime-host', + backends: [{ + id: 'deck-engine', + role: 'deckEngine', + actions: [{ name: 'attachWorkObject' }], + }], + }); + mocks.createWorkForObject.mockResolvedValueOnce(work( + 'work-shared-object', + { kind: 'workspace', workspaceId: 'ws_project' }, + 'D:/workspace/project', + )); + const sourceWorkLocator = { + scope: { kind: 'workspace' as const, workspaceId: 'ws_project' }, + workId: 'work-source', + }; + + await openProductAppRuntime(app('multiple'), { + workMode: 'existing_object', + sourceWorkLocator, + title: 'Activation Review', + scope: { + kind: 'workspace', + workspaceId: 'ws_project', + workspacePath: 'D:/workspace/project', + }, + }); + + expect(mocks.createWorkForObject).toHaveBeenCalledWith( + sourceWorkLocator, + expect.objectContaining({ + kind: 'app_workflow', + title: 'Activation Review', + }), + ); + expect(mocks.createWork).not.toHaveBeenCalled(); + expect(mocks.backendCall).toHaveBeenCalledWith( + 'runtime-host', + 'deckEngine.attachWorkObject', + { sourceWorkId: 'work-source' }, + expect.objectContaining({ + workspacePath: 'D:/workspace/project', + idempotencyKey: 'attach-work-object-work-source-work-shared-object-deck-engine', + }), + ); + expect(mocks.openRuntimeHost).toHaveBeenCalledAfter(mocks.backendCall); + }); + + it('rolls back the new Work when the Product App cannot attach its existing WorkObject', async () => { + const createdWork = work( + 'work-shared-incomplete', + { kind: 'workspace', workspaceId: 'ws_project' }, + 'D:/workspace/project', + ); + mocks.createWorkForObject.mockResolvedValueOnce(createdWork); + + await expect(openProductAppRuntime(app('multiple'), { + workMode: 'existing_object', + sourceWorkLocator: { + scope: { kind: 'workspace', workspaceId: 'ws_project' }, + workId: 'work-source', + }, + scope: { + kind: 'workspace', + workspaceId: 'ws_project', + workspacePath: 'D:/workspace/project', + }, + })).rejects.toThrow('cannot attach another Work to an existing WorkObject'); + + expect(mocks.deleteWork).toHaveBeenCalledWith( + { + scope: { kind: 'workspace', workspaceId: 'ws_project' }, + workId: 'work-shared-incomplete', + }, + { deleteLinkedSessions: true }, + ); + }); + it('resolves the existing Work for a singleton application surface', async () => { await openProductAppRuntime(app('singleton')); diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.ts b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.ts index 56b7ca13..7d6b20c7 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.ts +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/productAppRuntimeService.ts @@ -2,6 +2,7 @@ import { requestWorkRefresh, useWorkStore } from '@/app/agentic-os/work/data/wor import { agenticOsWorkApi } from '@/app/agentic-os/work/data/workApi'; import { productAppWorkRef } from '@/app/agentic-os/work/domain/productAppRefs'; import type { + CreateWorkRequest, WorkAppRef, WorkLocator, WorkRecord, @@ -134,6 +135,41 @@ async function initializeCreatedProductAppWork( } } +async function attachCreatedProductAppWorkToExistingObject( + target: ProductAppRuntimeHostTarget, + work: WorkRecord, + sourceWorkLocator: WorkLocator, +): Promise { + const attachers = (target.hostSurface.backends ?? []) + .filter(backend => backend.actions.some(action => action.name === 'attachWorkObject')); + if (attachers.length === 0) { + throw new Error( + `Product App ${target.intelligentApp.appId} cannot attach another Work to an existing WorkObject`, + ); + } + for (const backend of attachers) { + const backendAlias = backend.role?.trim() || backend.id; + const result = await productAppRuntimeHostAPI.backendCall( + target.hostSurface.id, + `${backendAlias}.attachWorkObject`, + { + sourceWorkId: sourceWorkLocator.workId, + }, + { + runtimeContext: target.runtimeContext, + workspacePath: workspacePathFromAppScope(target.scope), + idempotencyKey: `attach-work-object-${sourceWorkLocator.workId}-${work.id}-${backend.id}`, + }, + ); + const bridgeResult = result.bridgeResult as { status?: string; stderr?: string } | undefined; + if (result.status === 'failed' || bridgeResult?.status === 'failed') { + throw new Error( + bridgeResult?.stderr || `Failed to attach Product App Work ${work.id} to its WorkObject`, + ); + } + } +} + async function rollbackCreatedProductAppWork( work: WorkRecord, creationError: unknown, @@ -214,21 +250,32 @@ export async function openProductAppRuntime( }; const createExplicitMultipleWork = app.runtime.workMultiplicity === 'multiple' && options.workMode === 'create'; - let created = createExplicitMultipleWork; - const work = createExplicitMultipleWork - ? await useWorkStore.getState().createWork({ - kind: 'app_workflow', - title, - objective, - subject: { kind: 'app', app: appRef, intent: 'use' }, - appRefs: [{ app: appRef, role: 'executor' }], - scope: request.scope, - workspacePath: request.workspacePath, - visibility: request.visibility, - primarySurfacePolicy: request.primarySurfacePolicy, - primarySurface: request.primarySurface, - assignment: request.assignment, - }) + const existingObjectExplicitMultipleWork = app.runtime.workMultiplicity === 'multiple' + && options.workMode === 'existing_object'; + if (options.workMode === 'existing_object' && !existingObjectExplicitMultipleWork) { + throw new Error(`App ${app.appId} does not support multiple Works for one WorkObject`); + } + if (existingObjectExplicitMultipleWork && !options.sourceWorkLocator) { + throw new Error(`A source Work is required to reuse an existing WorkObject for App ${app.appId}`); + } + const createRequest: CreateWorkRequest = { + kind: 'app_workflow', + title, + objective, + subject: { kind: 'app', app: appRef, intent: 'use' }, + appRefs: [{ app: appRef, role: 'executor' }], + scope: request.scope, + workspacePath: request.workspacePath, + visibility: request.visibility, + primarySurfacePolicy: request.primarySurfacePolicy, + primarySurface: request.primarySurface, + assignment: request.assignment, + }; + let created = createExplicitMultipleWork || existingObjectExplicitMultipleWork; + const work = existingObjectExplicitMultipleWork + ? await useWorkStore.getState().createWorkForObject(options.sourceWorkLocator!, createRequest) + : createExplicitMultipleWork + ? await useWorkStore.getState().createWork(createRequest) : await useWorkStore.getState().resolveAppWork(request).then((resolved) => { created = resolved.created; return resolved.work; @@ -236,7 +283,11 @@ export async function openProductAppRuntime( try { const target = await resolveRuntimeTarget(work, appRef, scope, options); if (created) { - await initializeCreatedProductAppWork(target, work); + if (existingObjectExplicitMultipleWork) { + await attachCreatedProductAppWorkToExistingObject(target, work, options.sourceWorkLocator!); + } else { + await initializeCreatedProductAppWork(target, work); + } } const context: WorkspaceSurfaceContext = options.context ?? { kind: 'work', workId: work.id }; await openProductAppRuntimeHost(target, { diff --git a/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts b/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts index f781fbae..6b519cc4 100644 --- a/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts +++ b/src/web-ui/src/app/scenes/apps/product-app-runtime/useProductAppRuntimeBridge.ts @@ -30,7 +30,6 @@ import { buildSpreadsheetFocusContext, useExcelLiveFocusStore, } from '@/app/agentic-os/excel-live/excelLiveFocusStore'; -import { useContextStore } from '@/shared/stores/contextStore'; import type { ProductAppRuntimeHostedViewBridge } from './productAppRuntimeHostedViews'; import { resizeActiveAuxiliarySurface } from '@/app/auxiliary-surface'; @@ -548,7 +547,6 @@ export function useProductAppRuntimeBridge( sessionId: trustedSessionIdRef.current, } as any, 'pinned'); if (context) { - useContextStore.getState().addContext(context); window.dispatchEvent(new CustomEvent('insert-context-tag', { detail: { context }, })); diff --git a/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.scss b/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.scss index 0415eda0..22766edd 100644 --- a/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.scss +++ b/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.scss @@ -77,19 +77,6 @@ justify-content: center; } -.sparo-files-scene__sidebar-state-icon { - color: currentColor; -} - -.sparo-files-scene__sidebar-state-fill { - opacity: 0; - transition: opacity var(--ds-motion-fast) var(--ds-easing-standard); -} - -.sparo-files-scene__sidebar-state-icon.is-expanded .sparo-files-scene__sidebar-state-fill { - opacity: 1; -} - .sparo-files-scene__collapsed-rail { width: var(--files-sidebar-collapsed-width); display: flex; diff --git a/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.tsx b/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.tsx index 49b98c4e..ea0665fc 100644 --- a/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.tsx +++ b/src/web-ui/src/app/scenes/file-viewer/FileViewerScene.tsx @@ -22,13 +22,21 @@ import { List as ListIcon, MessageSquarePlus, Music, - PanelLeft, Pencil, Search, Star, Video, } from 'lucide-react'; -import { Button, EmptyState, IconButton, Input, SegmentedControl } from '@/design-system'; +import { + Button, + EmptyState, + IconButton, + Input, + PanelLeftClosedIcon, + PanelLeftOpenIcon, + SegmentedControl, + SPARO_ICON_OPTICAL_STROKE_WIDTH, +} from '@/design-system'; import FilesPanel from '../../components/panels/FilesPanel'; import { ContentCanvas } from '../../components/panels/content-canvas'; import { CanvasStoreModeContext } from '../../components/panels/content-canvas/stores'; @@ -1883,24 +1891,21 @@ const FileViewerScene: React.FC = ({ workspacePath, scopeK variant="ghost" onClick={() => setSidebarCollapsed((collapsed) => !collapsed)} > - - + )} {t('brand')} diff --git a/src/web-ui/src/app/scenes/session/AuxPane.tsx b/src/web-ui/src/app/scenes/session/AuxPane.tsx index 953f50ac..f9588058 100644 --- a/src/web-ui/src/app/scenes/session/AuxPane.tsx +++ b/src/web-ui/src/app/scenes/session/AuxPane.tsx @@ -9,6 +9,7 @@ const log = createLogger('AuxPane'); interface AuxPaneProps { workspacePath?: string; isSceneActive?: boolean; + isSceneFocused?: boolean; } /** @@ -18,6 +19,7 @@ interface AuxPaneProps { export default function AuxPane({ workspacePath, isSceneActive = true, + isSceneFocused = false, }: AuxPaneProps) { const activeHostKey = useAuxiliarySurfaceStore(state => state.activeHostKey); const collapse = useAuxiliarySurfaceStore(state => state.collapse); @@ -26,9 +28,23 @@ export default function AuxPane({ log.debug('Panel interaction', { itemId, userInput }); }, []); + const restoreToggleFocus = useCallback(() => { + document.querySelector( + '[data-testid="flowchat-header-right-panel-toggle"]', + )?.focus(); + }, []); + const handleRequestClose = useCallback(() => { - if (activeHostKey) collapse(activeHostKey, 'user'); - }, [activeHostKey, collapse]); + if (!activeHostKey) return; + restoreToggleFocus(); + collapse(activeHostKey, 'user'); + }, [activeHostKey, collapse, restoreToggleFocus]); + + const handleLastVisibleTabClosed = useCallback(() => { + if (!activeHostKey) return; + restoreToggleFocus(); + collapse(activeHostKey, 'empty'); + }, [activeHostKey, collapse, restoreToggleFocus]); return (
@@ -36,8 +52,11 @@ export default function AuxPane({ workspacePath={workspacePath} mode="agent" isSceneActive={isSceneActive} + isSceneFocused={isSceneFocused} onInteraction={handleInteraction} - onRequestClose={handleRequestClose} + disablePopOut={isSceneFocused} + onRequestClose={isSceneFocused ? undefined : handleRequestClose} + onLastVisibleTabClosed={handleLastVisibleTabClosed} />
); diff --git a/src/web-ui/src/app/scenes/session/SessionScene.scss b/src/web-ui/src/app/scenes/session/SessionScene.scss index b09d1019..81264f2d 100644 --- a/src/web-ui/src/app/scenes/session/SessionScene.scss +++ b/src/web-ui/src/app/scenes/session/SessionScene.scss @@ -68,6 +68,14 @@ .sparo-dual-column__header::after, .sparo-dual-column__header-two-row::after { display: none !important; } } + + &--auxiliary-focus { + .sparo-session-scene__chat-pane { + opacity: 0; + visibility: hidden; + pointer-events: none; + } + } } @@ -90,6 +98,7 @@ .sparo-session-scene__aux-pane { display: flex; + flex-direction: column; flex-shrink: 0; height: 100%; overflow: hidden; @@ -107,6 +116,19 @@ opacity: 0; } + &--scene-focus { + position: absolute; + inset: 0; + z-index: var(--ds-z-raised); + flex: none; + width: 100%; + height: 100%; + max-width: none; + min-width: 0; + background: var(--sparo-session-surface); + transition: opacity var(--ds-motion-fast) var(--ds-easing-standard); + } + &--no-animation { transition: none; // functional override: used by programmatic layout jumps where descendant @@ -178,6 +200,56 @@ } } +.sparo-session-scene__scene-focus-layout-placeholder { + flex: 0 0 auto; + height: 100%; + min-width: 0; + pointer-events: none; +} + +.sparo-session-scene__scene-focus-header { + display: flex; + align-items: center; + flex: 0 0 44px; + min-width: 0; + gap: var(--ds-space-2); + padding: 0 var(--ds-space-3); + box-sizing: border-box; + border-bottom: 1px solid var(--ds-color-border-subtle); + background: var(--sparo-session-surface); +} + +.sparo-session-scene__scene-focus-divider { + width: 1px; + height: 16px; + flex: 0 0 1px; + background: var(--ds-color-border-subtle); +} + +.sparo-session-scene__scene-focus-title { + min-width: 0; + overflow: hidden; + color: var(--ds-color-text-secondary); + font-size: var(--ds-font-size-sm); + font-weight: var(--ds-font-weight-medium); + line-height: var(--ds-line-height-tight); + text-overflow: ellipsis; + white-space: nowrap; +} + +.sparo-session-scene__aux-content { + position: relative; + display: flex; + flex: 1 1 auto; + min-width: 0; + min-height: 0; + overflow: hidden; +} + +.sparo-pane-resizer--scene-focus { + display: none; +} + .sparo-session-scene__aux-loading { position: absolute; inset: 0; diff --git a/src/web-ui/src/app/scenes/session/SessionScene.tsx b/src/web-ui/src/app/scenes/session/SessionScene.tsx index f5ccebcb..3e5111ff 100644 --- a/src/web-ui/src/app/scenes/session/SessionScene.tsx +++ b/src/web-ui/src/app/scenes/session/SessionScene.tsx @@ -12,6 +12,7 @@ import React, { useRef, useState, useCallback, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { ArrowLeft } from 'lucide-react'; import { useSessionProfile } from '../../session-profiles'; import { useSessionGoalSnapshot } from '@/flow_chat/store/sessionGoalStore'; import ChatPane from './ChatPane'; @@ -31,9 +32,9 @@ import { isSessionTranscriptLoading, isSessionTranscriptReady, } from '@/flow_chat/domain/sessionLoadPhase'; -import { DotMatrixLoader } from '@/design-system'; -import { useCanvasStore } from '@/app/components/panels/content-canvas'; +import { DotMatrixLoader, IconButton } from '@/design-system'; import { + exitActiveAuxiliarySceneFocus, selectActiveAuxiliaryHostState, useAuxiliarySurfaceStore, } from '@/app/auxiliary-surface'; @@ -61,17 +62,11 @@ const SessionScene: React.FC = ({ const updateAuxiliaryWidth = useAuxiliarySurfaceStore(store => store.setWidth); const auxiliaryCollapsed = !activeAuxiliaryHost || activeAuxiliaryHost.presentation === 'closed'; + const auxiliarySceneFocused = activeAuxiliaryHost?.presentation === 'scene-focus'; + const preserveDockedLayoutDuringSceneFocus = auxiliarySceneFocused + && activeAuxiliaryHost?.sceneFocusReturnPresentation === 'docked'; const activeSession = useActiveSession(); const [auxPaneReleasedSessionId, setAuxPaneReleasedSessionId] = useState(null); - const hasBoundProductAppTab = useCanvasStore(state => ( - [state.primaryGroup, state.secondaryGroup, state.tertiaryGroup].some(group => ( - group.tabs.some(tab => ( - tab.content.type === 'product-app-runtime' && - tab.content.metadata?.boundSessionId === surfaceSessionId - )) - )) - )); - const productAppId = activeSession?.customMetadata?.productAppRuntime?.appId; const isTranscriptLoading = Boolean(surfaceSessionId) && ( activeSession?.sessionId !== surfaceSessionId || isSessionTranscriptLoading(activeSession) @@ -86,9 +81,7 @@ const SessionScene: React.FC = ({ } }, [isTranscriptLoading, surfaceSessionId]); const auxPaneReleased = !surfaceSessionId || auxPaneReleasedSessionId === surfaceSessionId; - const isSessionSurfaceLoading = !auxPaneReleased || ( - Boolean(productAppId) && !hasBoundProductAppTab - ); + const isSessionSurfaceLoading = !auxPaneReleased; const goalSnapshot = useSessionGoalSnapshot(surfaceSessionId); // Once the goal is completed the session returns to its normal look: drop the // focus frame. The banner stays (neutral) so the result is still visible/clearable. @@ -99,6 +92,7 @@ const SessionScene: React.FC = ({ const auxiliaryConfig = AUXILIARY_SURFACE_CONFIG; const containerRef = useRef(null); + const chatPaneRef = useRef(null); const resizerRef = useRef(null); const auxPaneElementRef = useRef(null); const animationFrameRef = useRef(null); @@ -201,6 +195,24 @@ const SessionScene: React.FC = ({ if (animationFrameRef.current !== null) cancelAnimationFrame(animationFrameRef.current); }, []); + useEffect(() => { + if (!auxiliarySceneFocused) return; + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key !== 'Escape') return; + event.preventDefault(); + exitActiveAuxiliarySceneFocus('previous'); + }; + document.addEventListener('keydown', handleKeyDown); + return () => document.removeEventListener('keydown', handleKeyDown); + }, [auxiliarySceneFocused]); + + useEffect(() => { + const chatPane = chatPaneRef.current; + if (!chatPane) return; + if (auxiliarySceneFocused) chatPane.setAttribute('inert', ''); + else chatPane.removeAttribute('inert'); + }, [auxiliarySceneFocused]); + const panelModeLabels = useMemo(() => ({ collapsed: t('layout.panelMode.collapsed'), compact: t('layout.panelMode.compact'), @@ -227,6 +239,7 @@ const SessionScene: React.FC = ({ 'sparo-session-scene', isDragging && 'sparo-session-scene--dragging', hasGoalMode && 'sparo-session-scene--goal-mode', + auxiliarySceneFocused && 'sparo-session-scene--auxiliary-focus', isEntering && 'layout-entering', ].filter(Boolean).join(' ')} data-agent={profile.theme.dataAgent} @@ -236,7 +249,9 @@ const SessionScene: React.FC = ({ > {/* ChatPane �?FlowChat conversation */}
= ({ />
+ {auxiliarySceneFocused ? ( +