Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot] 16415fc73a chore(deps): bump the frontend-deps group across 1 directory with 54 updates
Bumps the frontend-deps group with 54 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/lang-javascript](https://github.com/codemirror/lang-javascript) | `6.2.4` | `6.2.5` |
| [@codemirror/lang-markdown](https://github.com/codemirror/lang-markdown) | `6.5.0` | `6.5.1` |
| [@codemirror/lint](https://github.com/codemirror/lint) | `6.8.5` | `6.9.7` |
| [@codemirror/state](https://github.com/codemirror/state) | `6.5.2` | `6.7.1` |
| [@codemirror/view](https://github.com/codemirror/view) | `6.38.2` | `6.43.7` |
| [@hookform/resolvers](https://github.com/react-hook-form/resolvers) | `5.2.2` | `5.5.7` |
| [@radix-ui/react-accordion](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/accordion) | `1.2.12` | `1.2.20` |
| [@radix-ui/react-checkbox](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/checkbox) | `1.3.3` | `1.3.11` |
| [@radix-ui/react-collapsible](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/collapsible) | `1.1.12` | `1.1.20` |
| [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.1.15` | `1.1.23` |
| [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.16` | `2.1.24` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.7` | `2.1.15` |
| [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.15` | `1.1.23` |
| [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.10` | `1.2.18` |
| [@radix-ui/react-select](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/select) | `2.2.6` | `2.3.7` |
| [@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot) | `1.2.4` | `1.3.3` |
| [@radix-ui/react-switch](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/switch) | `1.2.6` | `1.3.7` |
| [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.13` | `1.1.21` |
| [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tooltip) | `1.2.8` | `1.2.16` |
| [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.90.3` | `5.101.4` |
| [@tanstack/react-virtual](https://github.com/TanStack/virtual/tree/HEAD/packages/react-virtual) | `3.13.23` | `3.14.9` |
| [@tauri-apps/api](https://github.com/tauri-apps/tauri) | `2.8.0` | `2.11.1` |
| [@tauri-apps/plugin-dialog](https://github.com/tauri-apps/plugins-workspace) | `2.4.0` | `2.7.2` |
| [@tauri-apps/plugin-log](https://github.com/tauri-apps/plugins-workspace) | `2.8.0` | `2.9.0` |
| [@tauri-apps/plugin-process](https://github.com/tauri-apps/plugins-workspace) | `2.3.0` | `2.3.1` |
| [@tauri-apps/plugin-updater](https://github.com/tauri-apps/plugins-workspace) | `2.9.0` | `2.10.1` |
| [framer-motion](https://github.com/motiondivision/motion) | `12.23.25` | `12.43.0` |
| [i18next](https://github.com/i18next/i18next) | `25.5.2` | `26.3.6` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.542.0` | `1.28.0` |
| [react](https://github.com/react/react/tree/HEAD/packages/react) | `18.3.1` | `19.2.8` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `18.3.23` | `19.2.17` |
| [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) | `18.3.1` | `19.2.8` |
| [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) | `18.3.7` | `19.2.3` |
| [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.65.0` | `7.83.0` |
| [react-i18next](https://github.com/i18next/react-i18next) | `16.0.0` | `17.0.11` |
| [recharts](https://github.com/recharts/recharts) | `3.5.1` | `3.10.1` |
| [smol-toml](https://github.com/squirrelchat/smol-toml) | `1.4.2` | `1.7.1` |
| [tailwind-merge](https://github.com/dcastil/tailwind-merge) | `3.3.1` | `3.6.0` |
| [zod](https://github.com/colinhacks/zod) | `4.1.12` | `4.4.3` |
| [@tauri-apps/cli](https://github.com/tauri-apps/tauri) | `2.8.1` | `2.11.4` |
| [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) | `6.9.1` | `7.0.0` |
| [@testing-library/react](https://github.com/testing-library/react-testing-library) | `16.3.0` | `16.3.2` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.19.9` | `26.1.2` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `4.7.0` | `6.0.5` |
| [autoprefixer](https://github.com/postcss/autoprefixer) | `10.4.22` | `10.5.4` |
| [code-inspector-plugin](https://github.com/zh-lx/code-inspector) | `1.3.3` | `2.0.6` |
| [jsdom](https://github.com/jsdom/jsdom) | `25.0.1` | `30.0.1` |
| [msw](https://github.com/mswjs/msw) | `2.11.6` | `2.15.0` |
| [postcss](https://github.com/postcss/postcss) | `8.5.6` | `8.5.25` |
| [prettier](https://github.com/prettier/prettier) | `3.6.2` | `3.9.6` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `3.4.18` | `4.3.3` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.2` | `7.0.2` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.3.0` | `8.2.0` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `2.1.9` | `4.1.10` |



Updates `@codemirror/lang-javascript` from 6.2.4 to 6.2.5
- [Changelog](https://github.com/codemirror/lang-javascript/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-javascript/compare/6.2.4...6.2.5)

Updates `@codemirror/lang-markdown` from 6.5.0 to 6.5.1
- [Changelog](https://github.com/codemirror/lang-markdown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-markdown/commits)

Updates `@codemirror/lint` from 6.8.5 to 6.9.7
- [Changelog](https://github.com/codemirror/lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lint/commits)

Updates `@codemirror/state` from 6.5.2 to 6.7.1
- [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/state/commits)

Updates `@codemirror/view` from 6.38.2 to 6.43.7
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/commits)

Updates `@hookform/resolvers` from 5.2.2 to 5.5.7
- [Release notes](https://github.com/react-hook-form/resolvers/releases)
- [Commits](https://github.com/react-hook-form/resolvers/compare/v5.2.2...v5.5.7)

Updates `@radix-ui/react-accordion` from 1.2.12 to 1.2.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/accordion/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/accordion)

Updates `@radix-ui/react-checkbox` from 1.3.3 to 1.3.11
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/checkbox/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/checkbox)

Updates `@radix-ui/react-collapsible` from 1.1.12 to 1.1.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/collapsible/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/collapsible)

Updates `@radix-ui/react-dialog` from 1.1.15 to 1.1.23
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dialog)

Updates `@radix-ui/react-dropdown-menu` from 2.1.16 to 2.1.24
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu)

Updates `@radix-ui/react-label` from 2.1.7 to 2.1.15
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/label/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/label)

Updates `@radix-ui/react-popover` from 1.1.15 to 1.1.23
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/popover/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/popover)

Updates `@radix-ui/react-scroll-area` from 1.2.10 to 1.2.18
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/scroll-area)

Updates `@radix-ui/react-select` from 2.2.6 to 2.3.7
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/select/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/select)

Updates `@radix-ui/react-slot` from 1.2.4 to 1.3.3
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot)

Updates `@radix-ui/react-switch` from 1.2.6 to 1.3.7
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/switch/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/switch)

Updates `@radix-ui/react-tabs` from 1.1.13 to 1.1.21
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tabs/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tabs)

Updates `@radix-ui/react-tooltip` from 1.2.8 to 1.2.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tooltip/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tooltip)

Updates `@tanstack/react-query` from 5.90.3 to 5.101.4
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.4/packages/react-query)

Updates `@tanstack/react-virtual` from 3.13.23 to 3.14.9
- [Release notes](https://github.com/TanStack/virtual/releases)
- [Changelog](https://github.com/TanStack/virtual/blob/main/packages/react-virtual/CHANGELOG.md)
- [Commits](https://github.com/TanStack/virtual/commits/@tanstack/react-virtual@3.14.9/packages/react-virtual)

Updates `@tauri-apps/api` from 2.8.0 to 2.11.1
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/api-v2.8.0...@tauri-apps/api-v2.11.1)

Updates `@tauri-apps/plugin-dialog` from 2.4.0 to 2.7.2
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/fs-v2.4.0...dialog-v2.7.2)

Updates `@tauri-apps/plugin-log` from 2.8.0 to 2.9.0
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/log-v2.8.0...log-v2.9.0)

Updates `@tauri-apps/plugin-process` from 2.3.0 to 2.3.1
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/os-v2.3.0...os-v2.3.1)

Updates `@tauri-apps/plugin-updater` from 2.9.0 to 2.10.1
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/log-v2.9.0...updater-v2.10.1)

Updates `framer-motion` from 12.23.25 to 12.43.0
- [Changelog](https://github.com/motiondivision/motion/blob/main/CHANGELOG.md)
- [Commits](https://github.com/motiondivision/motion/compare/v12.23.25...v12.43.0)

Updates `i18next` from 25.5.2 to 26.3.6
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v25.5.2...v26.3.6)

Updates `lucide-react` from 0.542.0 to 1.28.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.28.0/packages/lucide-react)

Updates `react` from 18.3.1 to 19.2.8
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.2.8/packages/react)

Updates `@types/react` from 18.3.23 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 18.3.1 to 19.2.8
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.2.8/packages/react-dom)

Updates `@types/react-dom` from 18.3.7 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `react-hook-form` from 7.65.0 to 7.83.0
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.65.0...v7.83.0)

Updates `react-i18next` from 16.0.0 to 17.0.11
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v16.0.0...v17.0.11)

Updates `recharts` from 3.5.1 to 3.10.1
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](https://github.com/recharts/recharts/compare/v3.5.1...v3.10.1)

Updates `smol-toml` from 1.4.2 to 1.7.1
- [Release notes](https://github.com/squirrelchat/smol-toml/releases)
- [Commits](https://github.com/squirrelchat/smol-toml/compare/v1.4.2...v1.7.1)

Updates `tailwind-merge` from 3.3.1 to 3.6.0
- [Release notes](https://github.com/dcastil/tailwind-merge/releases)
- [Commits](https://github.com/dcastil/tailwind-merge/compare/v3.3.1...v3.6.0)

Updates `zod` from 4.1.12 to 4.4.3
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.1.12...v4.4.3)

Updates `@tauri-apps/cli` from 2.8.1 to 2.11.4
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v2.8.1...@tauri-apps/cli-v2.11.4)

Updates `@testing-library/jest-dom` from 6.9.1 to 7.0.0
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/jest-dom/compare/v6.9.1...v7.0.0)

Updates `@testing-library/react` from 16.3.0 to 16.3.2
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.0...v16.3.2)

Updates `@types/node` from 20.19.9 to 26.1.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/react` from 18.3.23 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 18.3.7 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@vitejs/plugin-react` from 4.7.0 to 6.0.5
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.5/packages/plugin-react)

Updates `autoprefixer` from 10.4.22 to 10.5.4
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/autoprefixer/compare/10.4.22...10.5.4)

Updates `code-inspector-plugin` from 1.3.3 to 2.0.6
- [Commits](https://github.com/zh-lx/code-inspector/commits)

Updates `jsdom` from 25.0.1 to 30.0.1
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](https://github.com/jsdom/jsdom/compare/v25.0.1...v30.0.1)

Updates `msw` from 2.11.6 to 2.15.0
- [Release notes](https://github.com/mswjs/msw/releases)
- [Changelog](https://github.com/mswjs/msw/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mswjs/msw/compare/v2.11.6...v2.15.0)

Updates `postcss` from 8.5.6 to 8.5.25
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.25)

Updates `prettier` from 3.6.2 to 3.9.6
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.6.2...3.9.6)

Updates `tailwindcss` from 3.4.18 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss)

Updates `typescript` from 5.9.2 to 7.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/commits)

Updates `vite` from 7.3.0 to 8.2.0
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@8.2.0/packages/vite)

Updates `vitest` from 2.1.9 to 4.1.10
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest)

---
updated-dependencies:
- dependency-name: "@codemirror/lang-javascript"
  dependency-version: 6.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@codemirror/lang-markdown"
  dependency-version: 6.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@codemirror/lint"
  dependency-version: 6.9.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@codemirror/state"
  dependency-version: 6.7.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@codemirror/view"
  dependency-version: 6.43.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@hookform/resolvers"
  dependency-version: 5.5.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-accordion"
  dependency-version: 1.2.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-checkbox"
  dependency-version: 1.3.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-collapsible"
  dependency-version: 1.1.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-dialog"
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-dropdown-menu"
  dependency-version: 2.1.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-popover"
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-version: 1.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-select"
  dependency-version: 2.3.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-slot"
  dependency-version: 1.3.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-switch"
  dependency-version: 1.3.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-tabs"
  dependency-version: 1.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@radix-ui/react-tooltip"
  dependency-version: 1.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.101.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tanstack/react-virtual"
  dependency-version: 3.14.9
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/api"
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/plugin-dialog"
  dependency-version: 2.7.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/plugin-log"
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/plugin-process"
  dependency-version: 2.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/plugin-updater"
  dependency-version: 2.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: framer-motion
  dependency-version: 12.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: i18next
  dependency-version: 26.3.6
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: lucide-react
  dependency-version: 1.28.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: react
  dependency-version: 19.2.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: react-dom
  dependency-version: 19.2.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: react-hook-form
  dependency-version: 7.83.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: react-i18next
  dependency-version: 17.0.11
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: recharts
  dependency-version: 3.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: smol-toml
  dependency-version: 1.7.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: tailwind-merge
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@tauri-apps/cli"
  dependency-version: 2.11.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: "@testing-library/jest-dom"
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: "@types/node"
  dependency-version: 26.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.5
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: autoprefixer
  dependency-version: 10.5.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: code-inspector-plugin
  dependency-version: 2.0.6
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: jsdom
  dependency-version: 30.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: msw
  dependency-version: 2.15.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: postcss
  dependency-version: 8.5.25
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: frontend-deps
- dependency-name: prettier
  dependency-version: 3.9.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: frontend-deps
- dependency-name: tailwindcss
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: typescript
  dependency-version: 7.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: vite
  dependency-version: 8.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
- dependency-name: vitest
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: frontend-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-30 14:45:41 +00:00
11 changed files with 2505 additions and 3144 deletions
+54 -54
View File
@@ -19,74 +19,74 @@
"author": "Jason Young",
"license": "MIT",
"devDependencies": {
"@tauri-apps/cli": "^2.8.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.0.1",
"@tauri-apps/cli": "^2.11.4",
"@testing-library/jest-dom": "^7.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.20",
"code-inspector-plugin": "^1.3.3",
"@types/node": "^26.1.2",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.5",
"autoprefixer": "^10.5.4",
"code-inspector-plugin": "^2.0.6",
"cross-fetch": "^4.1.0",
"jsdom": "^25.0.0",
"msw": "^2.11.6",
"postcss": "^8.4.49",
"prettier": "^3.6.2",
"tailwindcss": "^3.4.17",
"typescript": "^5.3.0",
"vite": "^7.3.0",
"vitest": "^2.0.5"
"jsdom": "^30.0.1",
"msw": "^2.15.0",
"postcss": "^8.5.25",
"prettier": "^3.9.6",
"tailwindcss": "^4.3.3",
"typescript": "^7.0.2",
"vite": "^8.2.0",
"vitest": "^4.1.10"
},
"dependencies": {
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-javascript": "^6.2.5",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/lint": "^6.8.5",
"@codemirror/state": "^6.5.2",
"@codemirror/lang-markdown": "^6.5.1",
"@codemirror/lint": "^6.9.7",
"@codemirror/state": "^6.7.1",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.38.2",
"@codemirror/view": "^6.43.7",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.3",
"@tanstack/react-virtual": "^3.13.23",
"@tauri-apps/api": "^2.8.0",
"@tauri-apps/plugin-dialog": "^2.4.0",
"@tauri-apps/plugin-log": "2.8.0",
"@tauri-apps/plugin-process": "^2.0.0",
"@tauri-apps/plugin-updater": "^2.0.0",
"@hookform/resolvers": "^5.5.7",
"@radix-ui/react-accordion": "^1.2.20",
"@radix-ui/react-checkbox": "^1.3.11",
"@radix-ui/react-collapsible": "^1.1.20",
"@radix-ui/react-dialog": "^1.1.23",
"@radix-ui/react-dropdown-menu": "^2.1.24",
"@radix-ui/react-label": "^2.1.15",
"@radix-ui/react-popover": "^1.1.23",
"@radix-ui/react-scroll-area": "^1.2.18",
"@radix-ui/react-select": "^2.3.7",
"@radix-ui/react-slot": "^1.3.3",
"@radix-ui/react-switch": "^1.3.7",
"@radix-ui/react-tabs": "^1.1.21",
"@radix-ui/react-tooltip": "^1.2.16",
"@tanstack/react-query": "^5.101.4",
"@tanstack/react-virtual": "^3.14.9",
"@tauri-apps/api": "^2.11.1",
"@tauri-apps/plugin-dialog": "^2.7.2",
"@tauri-apps/plugin-log": "2.9.0",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"codemirror": "^6.0.2",
"flexsearch": "^0.8.212",
"framer-motion": "^12.23.25",
"i18next": "^25.5.2",
"lucide-react": "^0.542.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.65.0",
"react-i18next": "^16.0.0",
"recharts": "^3.5.1",
"smol-toml": "^1.4.2",
"framer-motion": "^12.43.0",
"i18next": "^26.3.6",
"lucide-react": "^1.28.0",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"react-hook-form": "^7.83.0",
"react-i18next": "^17.0.11",
"recharts": "^3.10.1",
"smol-toml": "^1.7.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.3.1",
"zod": "^4.1.12"
"tailwind-merge": "^3.6.0",
"zod": "^4.4.3"
}
}
+2178 -3001
View File
File diff suppressed because it is too large Load Diff
+3 -5
View File
@@ -29,7 +29,7 @@ import {
import { getCurrentWindow } from "@tauri-apps/api/window";
import type { Provider, VisibleApps } from "@/types";
import type { EnvConflict } from "@/types/env";
import { proxyKeys, useProvidersQuery, useSettingsQuery } from "@/lib/query";
import { useProvidersQuery, useSettingsQuery } from "@/lib/query";
import {
providersApi,
settingsApi,
@@ -389,10 +389,8 @@ function App() {
await queryClient.invalidateQueries({ queryKey: ["profiles"] });
await queryClient.invalidateQueries({ queryKey: ["mcp", "all"] });
await queryClient.invalidateQueries({ queryKey: ["skills"] });
await queryClient.invalidateQueries({
queryKey: proxyKeys.takeoverStatus,
});
await queryClient.invalidateQueries({ queryKey: proxyKeys.status });
await queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
await queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
await queryClient.invalidateQueries({
queryKey: ["providers", "claude-desktop"],
});
+2 -3
View File
@@ -15,12 +15,12 @@ import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { ToggleRow } from "@/components/ui/toggle-row";
import { useProxyStatus } from "@/hooks/useProxyStatus";
import { toast } from "sonner";
import { useFailoverQueue } from "@/lib/query/failover";
import { ProviderHealthBadge } from "@/components/providers/ProviderHealthBadge";
import { useProviderHealth } from "@/lib/query/failover";
import {
useProxyStatusQuery,
useProxyTakeoverStatus,
useSetProxyTakeoverForApp,
useGlobalProxyConfig,
@@ -45,8 +45,7 @@ export function ProxyPanel({
isProxyPending,
}: ProxyPanelProps) {
const { t } = useTranslation();
const { data: status } = useProxyStatusQuery();
const isRunning = status?.running ?? false;
const { status, isRunning } = useProxyStatus();
// 获取应用接管状态
const { data: takeoverStatus } = useProxyTakeoverStatus();
+88 -19
View File
@@ -2,15 +2,15 @@
* 代理服务状态管理 Hook
*/
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { invoke } from "@tauri-apps/api/core";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { proxyApi } from "@/lib/api/proxy";
import {
proxyKeys,
useProxyStatusQuery,
useProxyTakeoverStatus,
} from "@/lib/query/proxy";
import type {
ProxyStatus,
ProxyServerInfo,
ProxyTakeoverStatus,
} from "@/types/proxy";
import { extractErrorMessage } from "@/utils/errorUtils";
/**
@@ -21,14 +21,25 @@ export function useProxyStatus() {
const { t } = useTranslation();
// 查询状态(自动轮询)
const { data: status } = useProxyStatusQuery();
const { data: status, isLoading } = useQuery({
queryKey: ["proxyStatus"],
queryFn: () => invoke<ProxyStatus>("get_proxy_status"),
// 仅在服务运行时轮询
refetchInterval: (query) => (query.state.data?.running ? 2000 : false),
// 保持之前的数据,避免闪烁
placeholderData: (previousData) => previousData,
});
// 查询各应用接管状态
const { data: takeoverStatus } = useProxyTakeoverStatus(false);
const { data: takeoverStatus } = useQuery({
queryKey: ["proxyTakeoverStatus"],
queryFn: () => invoke<ProxyTakeoverStatus>("get_proxy_takeover_status"),
placeholderData: (previousData) => previousData,
});
// 启动服务器(总开关:仅启动服务,不接管)
const startProxyServerMutation = useMutation({
mutationFn: () => proxyApi.startProxyServer(),
mutationFn: () => invoke<ProxyServerInfo>("start_proxy_server"),
onSuccess: (info) => {
toast.success(
t("proxy.server.started", {
@@ -38,7 +49,7 @@ export function useProxyStatus() {
}),
{ closeButton: true },
);
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
const detail =
@@ -55,7 +66,7 @@ export function useProxyStatus() {
// 停止服务器(仅停止服务,不改写/恢复其它应用接管状态)
const stopProxyServerMutation = useMutation({
mutationFn: () => proxyApi.stopProxyServer(),
mutationFn: () => invoke("stop_proxy_server"),
onSuccess: () => {
toast.success(
t("proxy.server.stopped", {
@@ -63,7 +74,7 @@ export function useProxyStatus() {
}),
{ closeButton: true },
);
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
const detail =
@@ -80,7 +91,7 @@ export function useProxyStatus() {
// 停止服务器(总开关关闭:强制恢复所有已接管的 Live 配置)
const stopWithRestoreMutation = useMutation({
mutationFn: () => proxyApi.stopProxyWithRestore(),
mutationFn: () => invoke("stop_proxy_with_restore"),
onSuccess: () => {
toast.success(
t("proxy.stoppedWithRestore", {
@@ -88,8 +99,8 @@ export function useProxyStatus() {
}),
{ closeButton: true },
);
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: proxyKeys.takeoverStatus });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
// 彻底删除所有供应商健康状态缓存(后端已清空数据库记录)
queryClient.removeQueries({ queryKey: ["providerHealth"] });
// 彻底删除所有熔断器统计缓存(代理停止后熔断器状态已重置)
@@ -112,7 +123,7 @@ export function useProxyStatus() {
// 按应用开启/关闭接管
const setTakeoverForAppMutation = useMutation({
mutationFn: ({ appType, enabled }: { appType: string; enabled: boolean }) =>
proxyApi.setProxyTakeoverForApp(appType, enabled),
invoke("set_proxy_takeover_for_app", { appType, enabled }),
onSuccess: (_data, variables) => {
const appLabel =
variables.appType === "claude"
@@ -138,8 +149,8 @@ export function useProxyStatus() {
{ closeButton: true },
);
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: proxyKeys.takeoverStatus });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
},
onError: (error: Error) => {
const detail =
@@ -154,10 +165,60 @@ export function useProxyStatus() {
},
});
// 代理模式切换供应商(热切换)
const switchProxyProviderMutation = useMutation({
mutationFn: ({
appType,
providerId,
}: {
appType: string;
providerId: string;
}) => invoke("switch_proxy_provider", { appType, providerId }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
const detail =
extractErrorMessage(error) ||
t("common.unknown", { defaultValue: "未知错误" });
toast.error(
t("proxy.switchFailed", {
error: detail,
defaultValue: `切换失败: ${detail}`,
}),
);
},
});
// 检查是否运行中
const checkRunning = async () => {
try {
return await invoke<boolean>("is_proxy_running");
} catch {
return false;
}
};
// 检查接管状态
const checkTakeoverActive = async () => {
try {
return await invoke<boolean>("is_live_takeover_active");
} catch {
return false;
}
};
return {
status,
isLoading,
isRunning: status?.running || false,
takeoverStatus,
isTakeoverActive:
takeoverStatus?.claude ||
takeoverStatus?.codex ||
takeoverStatus?.gemini ||
takeoverStatus?.grokbuild ||
false,
// 启动/停止(总开关)
startProxyServer: startProxyServerMutation.mutateAsync,
@@ -167,9 +228,17 @@ export function useProxyStatus() {
// 按应用接管开关
setTakeoverForApp: setTakeoverForAppMutation.mutateAsync,
// 代理模式下切换供应商
switchProxyProvider: switchProxyProviderMutation.mutateAsync,
// 状态检查
checkRunning,
checkTakeoverActive,
// 加载状态
isStarting: startProxyServerMutation.isPending,
isStoppingServer: stopProxyServerMutation.isPending,
isStopping: stopWithRestoreMutation.isPending,
isPending:
startProxyServerMutation.isPending ||
stopProxyServerMutation.isPending ||
+31 -5
View File
@@ -1,5 +1,6 @@
import { invoke } from "@tauri-apps/api/core";
import type {
ProxyConfig,
ProxyStatus,
ProxyServerInfo,
ProxyTakeoverStatus,
@@ -15,11 +16,6 @@ export const proxyApi = {
return invoke("start_proxy_server");
},
// 停止代理服务器(不恢复已接管配置)
async stopProxyServer(): Promise<void> {
return invoke("stop_proxy_server");
},
// 停止代理服务器并恢复配置
async stopProxyWithRestore(): Promise<void> {
return invoke("stop_proxy_with_restore");
@@ -30,6 +26,24 @@ export const proxyApi = {
return invoke("get_proxy_status");
},
// 检查代理服务器是否正在运行
async isProxyRunning(): Promise<boolean> {
return invoke("is_proxy_running");
},
// 检查是否处于接管模式
async isLiveTakeoverActive(): Promise<boolean> {
return invoke("is_live_takeover_active");
},
// 代理模式下切换供应商
async switchProxyProvider(
appType: string,
providerId: string,
): Promise<void> {
return invoke("switch_proxy_provider", { appType, providerId });
},
// ========== 接管状态 API ==========
// 获取各应用接管状态
@@ -45,6 +59,18 @@ export const proxyApi = {
return invoke("set_proxy_takeover_for_app", { appType, enabled });
},
// ========== Legacy 代理配置 API (兼容) ==========
// 获取代理配置(旧版 v2 兼容接口)
async getProxyConfig(): Promise<ProxyConfig> {
return invoke("get_proxy_config");
},
// 更新代理配置(旧版 v2 兼容接口)
async updateProxyConfig(config: ProxyConfig): Promise<void> {
return invoke("update_proxy_config", { config });
},
// ========== v3+ 全局/应用级配置 API ==========
// 获取全局代理配置
+2 -3
View File
@@ -3,7 +3,6 @@ import { failoverApi } from "@/lib/api/failover";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { extractErrorMessage } from "@/utils/errorUtils";
import { proxyKeys } from "@/lib/query/proxy";
// ========== 熔断器 Hooks ==========
@@ -48,7 +47,7 @@ export function useResetCircuitBreaker() {
});
// 刷新代理状态(更新 active_targets
queryClient.invalidateQueries({
queryKey: proxyKeys.status,
queryKey: ["proxyStatus"],
});
},
});
@@ -284,7 +283,7 @@ export function useSetAutoFailoverEnabled() {
queryKey: ["providers", variables.appType],
});
queryClient.invalidateQueries({
queryKey: proxyKeys.status,
queryKey: ["proxyStatus"],
});
},
});
+1 -2
View File
@@ -9,7 +9,6 @@ import { extractErrorMessage } from "@/utils/errorUtils";
import { generateUUID } from "@/utils/uuid";
import { openclawKeys } from "@/hooks/useOpenClaw";
import { invalidateHermesProviderCaches } from "@/hooks/useHermes";
import { proxyKeys } from "@/lib/query/proxy";
import { usageKeys } from "@/lib/query/usage";
import {
CODEX_OFFICIAL_PROVIDER_ID,
@@ -287,7 +286,7 @@ export const useSwitchProviderMutation = (appId: AppId) => {
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ["providers", appId] });
if (appId === "claude-desktop") {
await queryClient.invalidateQueries({ queryKey: proxyKeys.status });
await queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
await queryClient.invalidateQueries({
queryKey: ["claudeDesktopStatus"],
});
+136 -34
View File
@@ -2,54 +2,90 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { proxyApi } from "@/lib/api/proxy";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import type {
GlobalProxyConfig,
AppProxyConfig,
ProxyTakeoverStatus,
} from "@/types/proxy";
export const proxyKeys = {
status: ["proxyStatus"] as const,
takeoverStatus: ["proxyTakeoverStatus"] as const,
globalConfig: ["globalProxyConfig"] as const,
appConfig: (appType: string) => ["appProxyConfig", appType] as const,
};
import type { GlobalProxyConfig, AppProxyConfig } from "@/types/proxy";
// ========== 代理服务器状态 Hooks ==========
/**
* 获取代理服务器状态
*/
export function useProxyStatusQuery() {
export function useProxyStatus() {
return useQuery({
queryKey: proxyKeys.status,
queryKey: ["proxyStatus"],
queryFn: () => proxyApi.getProxyStatus(),
// 仅在服务运行时轮询
refetchInterval: (query) => (query.state.data?.running ? 2000 : false),
// 保持之前的数据,避免闪烁
placeholderData: (previousData) => previousData,
refetchInterval: 5000, // 每 5 秒刷新一次
});
}
/**
* 检查代理服务器是否运行
*/
export function useIsProxyRunning() {
return useQuery({
queryKey: ["proxyRunning"],
queryFn: () => proxyApi.isProxyRunning(),
refetchInterval: 2000,
});
}
/**
* 检查是否处于接管模式
*/
export function useIsLiveTakeoverActive() {
return useQuery({
queryKey: ["liveTakeoverActive"],
queryFn: () => proxyApi.isLiveTakeoverActive(),
refetchInterval: 2000,
});
}
/**
* 获取各应用接管状态
*/
export function useProxyTakeoverStatus(poll = true) {
export function useProxyTakeoverStatus() {
return useQuery({
queryKey: proxyKeys.takeoverStatus,
queryKey: ["proxyTakeoverStatus"],
queryFn: () => proxyApi.getProxyTakeoverStatus(),
refetchInterval: poll ? 2000 : false,
...(poll
? {}
: {
placeholderData: (previousData: ProxyTakeoverStatus | undefined) =>
previousData,
}),
refetchInterval: 2000,
});
}
// ========== 代理服务器控制 Hooks ==========
/**
* 启动代理服务器
*/
export function useStartProxyServer() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => proxyApi.startProxyServer(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
queryClient.invalidateQueries({ queryKey: ["proxyRunning"] });
queryClient.invalidateQueries({ queryKey: ["liveTakeoverActive"] });
queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
},
});
}
/**
* 停止代理服务器
*/
export function useStopProxyServer() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => proxyApi.stopProxyWithRestore(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
queryClient.invalidateQueries({ queryKey: ["proxyRunning"] });
queryClient.invalidateQueries({ queryKey: ["liveTakeoverActive"] });
queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
},
});
}
/**
* 设置应用接管状态
*/
@@ -60,11 +96,75 @@ export function useSetProxyTakeoverForApp() {
mutationFn: ({ appType, enabled }: { appType: string; enabled: boolean }) =>
proxyApi.setProxyTakeoverForApp(appType, enabled),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: proxyKeys.takeoverStatus });
queryClient.invalidateQueries({ queryKey: ["proxyTakeoverStatus"] });
queryClient.invalidateQueries({ queryKey: ["liveTakeoverActive"] });
},
});
}
/**
* 代理模式下切换供应商
*/
export function useSwitchProxyProvider() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation({
mutationFn: ({
appType,
providerId,
}: {
appType: string;
providerId: string;
}) => proxyApi.switchProxyProvider(appType, providerId),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
queryClient.invalidateQueries({
queryKey: ["providers", variables.appType],
});
},
onError: (error: Error) => {
toast.error(t("proxy.switchFailed", { error: error.message }));
},
});
}
// ========== Legacy 代理配置 Hooks (兼容) ==========
/**
* 获取代理配置(旧版)
*/
export function useProxyConfig() {
const queryClient = useQueryClient();
const { t } = useTranslation();
const { data: config, isLoading } = useQuery({
queryKey: ["proxyConfig"],
queryFn: () => proxyApi.getProxyConfig(),
});
const updateMutation = useMutation({
mutationFn: proxyApi.updateProxyConfig,
onSuccess: () => {
toast.success(t("proxy.settings.toast.saved"), { closeButton: true });
queryClient.invalidateQueries({ queryKey: ["proxyConfig"] });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
toast.error(
t("proxy.settings.toast.saveFailed", { error: error.message }),
);
},
});
return {
config,
isLoading,
updateConfig: updateMutation.mutateAsync,
isUpdating: updateMutation.isPending,
};
}
// ========== v3+ 全局/应用级配置 Hooks ==========
/**
@@ -72,7 +172,7 @@ export function useSetProxyTakeoverForApp() {
*/
export function useGlobalProxyConfig() {
return useQuery({
queryKey: proxyKeys.globalConfig,
queryKey: ["globalProxyConfig"],
queryFn: () => proxyApi.getGlobalProxyConfig(),
});
}
@@ -89,8 +189,9 @@ export function useUpdateGlobalProxyConfig() {
proxyApi.updateGlobalProxyConfig(config),
onSuccess: () => {
toast.success(t("proxy.settings.toast.saved"), { closeButton: true });
queryClient.invalidateQueries({ queryKey: proxyKeys.globalConfig });
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: ["globalProxyConfig"] });
queryClient.invalidateQueries({ queryKey: ["proxyConfig"] });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
toast.error(
@@ -105,7 +206,7 @@ export function useUpdateGlobalProxyConfig() {
*/
export function useAppProxyConfig(appType: string) {
return useQuery({
queryKey: proxyKeys.appConfig(appType),
queryKey: ["appProxyConfig", appType],
queryFn: () => proxyApi.getProxyConfigForApp(appType),
enabled: !!appType,
});
@@ -124,13 +225,14 @@ export function useUpdateAppProxyConfig() {
onSuccess: (_, variables) => {
toast.success(t("proxy.settings.toast.saved"), { closeButton: true });
queryClient.invalidateQueries({
queryKey: proxyKeys.appConfig(variables.appType),
queryKey: ["appProxyConfig", variables.appType],
});
queryClient.invalidateQueries({
queryKey: ["autoFailoverEnabled", variables.appType],
});
queryClient.invalidateQueries({ queryKey: ["proxyConfig"] });
queryClient.invalidateQueries({ queryKey: ["circuitBreakerConfig"] });
queryClient.invalidateQueries({ queryKey: proxyKeys.status });
queryClient.invalidateQueries({ queryKey: ["proxyStatus"] });
},
onError: (error: Error) => {
toast.error(
+9 -2
View File
@@ -22,10 +22,17 @@ vi.mock("react-i18next", () => ({
vi.mock("@/hooks/useProxyStatus", () => ({
useProxyStatus: () => ({
status: null,
isLoading: false,
isRunning: false,
takeoverStatus: null,
startProxyServer: vi.fn(),
isTakeoverActive: false,
startWithTakeover: vi.fn(),
stopWithRestore: vi.fn(),
switchProxyProvider: vi.fn(),
checkRunning: vi.fn(),
checkTakeoverActive: vi.fn(),
isStarting: false,
isStopping: false,
isPending: false,
}),
}));
+1 -16
View File
@@ -3,7 +3,6 @@ import { renderHook, act, waitFor } from "@testing-library/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { useProxyStatus } from "@/hooks/useProxyStatus";
import { proxyKeys } from "@/lib/query/proxy";
import { createTestQueryClient } from "../utils/testQueryClient";
const toastSuccessMock = vi.fn();
@@ -100,19 +99,12 @@ describe("useProxyStatus", () => {
});
});
it("keeps the established proxy query key shapes", () => {
expect(proxyKeys.status).toEqual(["proxyStatus"]);
expect(proxyKeys.takeoverStatus).toEqual(["proxyTakeoverStatus"]);
expect(proxyKeys.globalConfig).toEqual(["globalProxyConfig"]);
expect(proxyKeys.appConfig("claude")).toEqual(["appProxyConfig", "claude"]);
});
it("shows interpolated address and port after proxy server starts", async () => {
const { wrapper } = createWrapper();
const { result } = renderHook(() => useProxyStatus(), { wrapper });
await waitFor(() => {
expect(result.current.status).toBeDefined();
expect(result.current.isLoading).toBe(false);
});
await act(async () => {
@@ -123,12 +115,5 @@ describe("useProxyStatus", () => {
"代理服务已启动 - 127.0.0.1:15721",
{ closeButton: true },
);
await act(async () => {
await result.current.stopProxyServer();
});
expect(invokeMock).toHaveBeenCalledWith("start_proxy_server");
expect(invokeMock).toHaveBeenCalledWith("stop_proxy_server");
});
});