diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60e55fc..c30d73d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,11 @@ jobs: steps: - uses: actions/checkout@v7 + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + cache-dependency-path: go.sum + - uses: pnpm/action-setup@v6 with: version: 11.17.0 @@ -110,3 +115,11 @@ jobs: - name: Build working-directory: frontend run: pnpm run build + + - name: Install browser + working-directory: frontend + run: pnpm exec playwright install --with-deps chromium + + - name: Wails E2E + working-directory: frontend + run: pnpm run test:e2e diff --git a/Taskfile.yml b/Taskfile.yml index 162ed97..f9d9278 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -8,7 +8,7 @@ vars: # cross-compile (only windows supports cross-compilation, see build/*/Taskfile.yml). GOOS: '{{.GOOS | default OS}}' WAILS_MODULE: github.com/wailsapp/wails/v3 - WAILS_VERSION: v3.0.0-beta.3 + WAILS_VERSION: v3.0.0-beta.4 # Pinned Wails CLI (see build/tool-versions.env); never rely on a global wails3. WAILS3: go run {{.WAILS_MODULE}}/cmd/wails3@{{.WAILS_VERSION}} diff --git a/build/tool-versions.env b/build/tool-versions.env index f34e638..299c500 100644 --- a/build/tool-versions.env +++ b/build/tool-versions.env @@ -2,7 +2,7 @@ # and binding-diff checks have been rerun on all four supported targets. GO_VERSION=1.26 NODE_VERSION=22 -WAILS_VERSION=v3.0.0-beta.3 -WAILS_CLI_VERSION=v3.0.0-beta.3 -WAILS_RUNTIME_VERSION=3.0.0-alpha2.117 +WAILS_VERSION=v3.0.0-beta.4 +WAILS_CLI_VERSION=v3.0.0-beta.4 +WAILS_RUNTIME_VERSION=3.0.0-beta.1 TASK_VERSION=v3.40.1-patched3 diff --git a/docs/decisions/ADR-007-wails-v3-go-migration.md b/docs/decisions/ADR-007-wails-v3-go-migration.md index d3fd326..0e82859 100644 --- a/docs/decisions/ADR-007-wails-v3-go-migration.md +++ b/docs/decisions/ADR-007-wails-v3-go-migration.md @@ -7,16 +7,16 @@ ## Context The migration plan called for a Wails v3 desktop shell, a transport-independent -Go core, and a separate headless CLI. Wails v3 is still Alpha, so the shipped -channel remains an unsigned technical preview. +Go core, and a separate headless CLI. Wails v3 is still pre-release, so the +shipped channel remains an unsigned technical preview. ## Decision 1. The migration line uses Go 1.26+ and pins Wails v3 to - `v3.0.0-beta.3` for the initial native spike. The matching CLI uses the - same module version. The browser runtime candidate is pinned separately to - `3.0.0-alpha2.117`, the version shipped by that Wails module and present in - the frontend lockfile used by the production bundle. + `v3.0.0-beta.4` for the initial native spike. The matching CLI uses the + same module version. The browser runtime is pinned separately to + `3.0.0-beta.1`, the version embedded in that Wails module and present in the + frontend lockfile used by the production bundle. 2. `agents.lock.json` remains the only hand-edited Agent catalog source. The root Go package embeds that file once, and `internal/catalog` parses the embedded bytes for both the CLI and desktop shell. diff --git a/docs/superpowers/plans/2026-08-06-ota-updater.md b/docs/superpowers/plans/2026-08-06-ota-updater.md index 586248e..62799f7 100644 --- a/docs/superpowers/plans/2026-08-06-ota-updater.md +++ b/docs/superpowers/plans/2026-08-06-ota-updater.md @@ -6,7 +6,7 @@ **Architecture:** Wails' `pkg/updater` owns release comparison, GitHub asset selection, checksum verification, archive extraction, staging, swapping, and relaunch. A narrow `internal/binding.UpdateService` adapts that concrete updater to three cancellable Wails methods. A frontend-only `AppUpdater` checks once at startup, uses `@wailsio/runtime`'s native `Dialogs.Question` for consent, and drives the existing task-center state and progress event pipeline. -**Tech Stack:** Go 1.26, Wails v3.0.0-beta.3 `pkg/updater`, GitHub Releases API, React 19, TypeScript, Vitest, pnpm, GitHub Actions. +**Tech Stack:** Go 1.26, Wails v3.0.0-beta.4 `pkg/updater`, GitHub Releases API, React 19, TypeScript, Vitest, pnpm, GitHub Actions. --- diff --git a/frontend/e2e/wails-server.mjs b/frontend/e2e/wails-server.mjs index 2f6e196..b896287 100644 --- a/frontend/e2e/wails-server.mjs +++ b/frontend/e2e/wails-server.mjs @@ -11,6 +11,9 @@ const child = spawn("go", ["run", "-tags", "wails,server,e2e", "./cmd/oneagent-d cwd: root, env: { ...process.env, + // Server-mode tests do not use a native WebView; keep Linux CI independent + // of GTK/WebKitGTK development packages. + CGO_ENABLED: "0", ONEAGENT_HOME: home, }, stdio: "inherit", diff --git a/frontend/e2e/wails.spec.ts b/frontend/e2e/wails.spec.ts index c8125b1..0a6996c 100644 --- a/frontend/e2e/wails.spec.ts +++ b/frontend/e2e/wails.spec.ts @@ -66,7 +66,7 @@ test("every sidebar control at the bottom is actually clickable", async ({ page test("a machine with no OneAgent state opens onboarding from the landing route", async ({ page }) => { await page.goto("/#/"); - await expect(page.getByRole("heading", { name: "选择命令行 Agent" })).toBeVisible(); + await expect(page.getByRole("heading", { name: "选择 Agent", level: 1 })).toBeVisible(); }); test("onboarding installs one Agent end to end and writes its Profile", async ({ page }) => { @@ -88,10 +88,10 @@ test("onboarding installs one Agent end to end and writes its Profile", async ({ await expect(page.getByTestId("provider-ppio")).toContainText("已保存 Key"); await page.goto("/#/overview"); - await expect(page.getByText("尚未安装任何 Agent")).toBeVisible(); - await page.getByRole("button", { name: "安装 Agent" }).click(); + await expect(page.getByText("尚未安装任何命令行 Agent")).toBeVisible(); + await page.getByRole("button", { name: "安装命令行 Agent" }).click(); - await expect(page.getByRole("heading", { name: "选择命令行 Agent" })).toBeVisible(); + await expect(page.getByRole("heading", { name: "选择 Agent", level: 1 })).toBeVisible(); await page.getByLabel("选择 Codex").check(); await page.getByRole("button", { name: "继续" }).click(); @@ -119,8 +119,8 @@ test("onboarding installs one Agent end to end and writes its Profile", async ({ // The Profile the install wrote is editable from the Agent row, without any // credential or endpoint fields on the edit page. - await page.getByRole("link", { name: "编辑配置" }).click(); - await expect(page.getByText("团队默认")).toBeVisible(); + await page.getByRole("link", { name: "配置", exact: true }).click(); + await expect(page.getByRole("heading", { name: "选择配置模板" })).toBeVisible(); await expect(page.getByLabel("API Key")).toHaveCount(0); await expect(page.getByText("Base URL")).toHaveCount(0); expect(bindingMethodIDs.size).toBeGreaterThanOrEqual(3); diff --git a/frontend/package.json b/frontend/package.json index 59b559b..e57193d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,25 +15,25 @@ "test:e2e": "playwright test" }, "dependencies": { - "@wailsio/runtime": "3.0.0-alpha2.117", - "lucide-react": "1.25.0", + "@wailsio/runtime": "3.0.0-beta.1", + "lucide-react": "1.28.0", "react": "19.2.8", "react-dom": "19.2.8", - "react-router-dom": "7.18.1" + "react-router-dom": "7.18.2" }, "devDependencies": { - "@playwright/test": "1.61.1", + "@playwright/test": "1.62.1", "@testing-library/jest-dom": "7.0.0", "@testing-library/react": "16.3.2", - "@testing-library/user-event": "14.6.1", - "@types/node": "26.1.1", - "@types/react": "19.2.17", - "@types/react-dom": "19.2.3", - "@vitejs/plugin-react": "6.0.3", + "@testing-library/user-event": "14.6.3", + "@types/node": "26.1.2", + "@types/react": "19.2.18", + "@types/react-dom": "19.2.4", + "@vitejs/plugin-react": "6.0.5", "@vitest/coverage-v8": "4.1.10", - "jsdom": "29.1.1", + "jsdom": "30.0.1", "typescript": "7.0.2", - "vite": "8.1.5", + "vite": "8.2.0", "vitest": "4.1.10" } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 8415685..36217b0 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: dependencies: '@wailsio/runtime': - specifier: 3.0.0-alpha2.117 - version: 3.0.0-alpha2.117 + specifier: 3.0.0-beta.1 + version: 3.0.0-beta.1 lucide-react: - specifier: 1.25.0 - version: 1.25.0(react@19.2.8) + specifier: 1.28.0 + version: 1.28.0(react@19.2.8) react: specifier: 19.2.8 version: 19.2.8 @@ -21,68 +21,61 @@ importers: specifier: 19.2.8 version: 19.2.8(react@19.2.8) react-router-dom: - specifier: 7.18.1 - version: 7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: 7.18.2 + version: 7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) devDependencies: '@playwright/test': - specifier: 1.61.1 - version: 1.61.1 + specifier: 1.62.1 + version: 1.62.1 '@testing-library/jest-dom': specifier: 7.0.0 version: 7.0.0(@testing-library/dom@10.4.1) '@testing-library/react': specifier: 16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@testing-library/user-event': - specifier: 14.6.1 - version: 14.6.1(@testing-library/dom@10.4.1) + specifier: 14.6.3 + version: 14.6.3(@testing-library/dom@10.4.1) '@types/node': - specifier: 26.1.1 - version: 26.1.1 + specifier: 26.1.2 + version: 26.1.2 '@types/react': - specifier: 19.2.17 - version: 19.2.17 + specifier: 19.2.18 + version: 19.2.18 '@types/react-dom': - specifier: 19.2.3 - version: 19.2.3(@types/react@19.2.17) + specifier: 19.2.4 + version: 19.2.4(@types/react@19.2.18) '@vitejs/plugin-react': - specifier: 6.0.3 - version: 6.0.3(vite@8.1.5(@types/node@26.1.1)) + specifier: 6.0.5 + version: 6.0.5(vite@8.2.0(@types/node@26.1.2)) '@vitest/coverage-v8': specifier: 4.1.10 version: 4.1.10(vitest@4.1.10) jsdom: - specifier: 29.1.1 - version: 29.1.1 + specifier: 30.0.1 + version: 30.0.1 typescript: specifier: 7.0.2 version: 7.0.2 vite: - specifier: 8.1.5 - version: 8.1.5(@types/node@26.1.1) + specifier: 8.2.0 + version: 8.2.0(@types/node@26.1.2) vitest: specifier: 4.1.10 - version: 4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(jsdom@29.1.1)(vite@8.1.5(@types/node@26.1.1)) + version: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(jsdom@30.0.1)(vite@8.2.0(@types/node@26.1.2)) packages: '@adobe/css-tools@4.5.0': resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==} - '@asamuzakjp/css-color@5.1.11': - resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/dom-selector@7.1.1': - resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + '@asamuzakjp/css-color@6.0.5': + resolution: {integrity: sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==} + engines: {node: ^22.13.0 || >=24.0.0} - '@asamuzakjp/generational-cache@1.0.1': - resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/nwsapi@2.3.9': - resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@asamuzakjp/dom-selector@8.3.2': + resolution: {integrity: sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q==} + engines: {node: ^22.13.0 || >=24.0.0} '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} @@ -96,8 +89,8 @@ packages: resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.7': - resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} hasBin: true @@ -105,8 +98,8 @@ packages: resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} - '@babel/types@7.29.7': - resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@1.0.2': @@ -153,15 +146,6 @@ packages: resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - '@exodus/bytes@1.15.1': resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -188,112 +172,100 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@napi-rs/wasm-runtime@1.2.0': - resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - peerDependencies: - '@emnapi/core': ^2.0.0-alpha.3 - '@emnapi/runtime': ^2.0.0-alpha.3 - - '@oxc-project/types@0.139.0': - resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + '@oxc-project/types@0.142.0': + resolution: {integrity: sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==} - '@playwright/test@1.61.1': - resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} - engines: {node: '>=18'} + '@playwright/test@1.62.1': + resolution: {integrity: sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==} + engines: {node: '>=20'} hasBin: true - '@rolldown/binding-android-arm64@1.1.5': - resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} + '@rolldown/binding-android-arm64@1.2.2': + resolution: {integrity: sha512-l7x215OGvo1s52JWmR8U/DAVzEDWBCIbTm28aeJV/WDTSHgcKXaZTuBT0hJMs5NggilfJTW3clZVvd24yfKJxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.1.5': - resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} + '@rolldown/binding-darwin-arm64@1.2.2': + resolution: {integrity: sha512-9u9Xv6c1AJZT0FfwH5vrMG5Jjcwhc1MlyrPu0XfTqkzsmqfks2M6W/o5XwAJgVVN/jHpqqngC1WevHKKTIUtIA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.1.5': - resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} + '@rolldown/binding-darwin-x64@1.2.2': + resolution: {integrity: sha512-9W1mbGZAfW3oqd85bhBkmpyHCCzL1TeG/zFFP3vg7b0rlly8cxOcre5nXwz+LHazCwac2MNWgPdPCHndABjpWQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.1.5': - resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} + '@rolldown/binding-freebsd-x64@1.2.2': + resolution: {integrity: sha512-0p1lhiCSCyaerFwtrdZQUx7NqGk6LQnaRKWX7tFQqwQgvX0rjM15cIkm3pax1UpEakK14C4mOxx/jSqCBdBRqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.1.5': - resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.2': + resolution: {integrity: sha512-e+cOJXrJ2L3zx6YzqPg+f6Wbk3V1cKB8bOhbaYdVYN3DdquzNdRAmrbETz1qnt5yp/c7JNlNjmITiA2cVneQ7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.1.5': - resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} + '@rolldown/binding-linux-arm64-gnu@1.2.2': + resolution: {integrity: sha512-JsSMsj6sNat/MuhG5fnBD7QgbtpHKVe30x5/bAVirDHdhoQRXJkF6xc0Jqk8O4fiCUQAzMOoH9wZi3m60c8wtg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.1.5': - resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} + '@rolldown/binding-linux-arm64-musl@1.2.2': + resolution: {integrity: sha512-B5G/zJdHaoJn9vD50eGHWkiWfmq8Uhi3IiLPJTzmZTrAalk1bztUikSXo0qga18ibE0IXboyeMUnhPjhAJ45wQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.1.5': - resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} + '@rolldown/binding-linux-ppc64-gnu@1.2.2': + resolution: {integrity: sha512-6mC/awzKka8W6EoekjegpfGkjz8jXWDX63pqu/HYVpyKtZfu65Jsh4QAH3Kej3CAv/c1oGX7psTmFEbr0mDxLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.1.5': - resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} + '@rolldown/binding-linux-s390x-gnu@1.2.2': + resolution: {integrity: sha512-412MX9fJLdA1IK28EZnc8jYv2HRTleOZgfLQumJ5zy7OeJLZlg/CETwFaXjNmGVxG51cFHpKLqb5LKvBC+HsHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.1.5': - resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} + '@rolldown/binding-linux-x64-gnu@1.2.2': + resolution: {integrity: sha512-Q/+HI/ToJafZ1iCqGgVQXUEkIjufHCTF0gBQ2a5o3cg7GJ2h0qyq3nvvSmU+bGda2/7ygXpTY4TM6gO9OhQ0ZA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.1.5': - resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} + '@rolldown/binding-linux-x64-musl@1.2.2': + resolution: {integrity: sha512-ZKp/w41n6wCvxzxQHtQSbuphfX3Y4cCvbjkKHusrLx4lh+JWLTU7StSltO/DKARISzbj368d+qUaCjI8K2wzXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.1.5': - resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} + '@rolldown/binding-openharmony-arm64@1.2.2': + resolution: {integrity: sha512-pxE6xD4KS3eAROkKK5yrhB9/3+vhlhVGMvlQLbdpzrBGDbKrnzx3RLwPaHvasLo6jgaiBLn7e04Df9C4tYhjmA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.1.5': - resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.1.5': - resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} + '@rolldown/binding-win32-arm64-msvc@1.2.2': + resolution: {integrity: sha512-4MqEue5re+xIZzAWsB8sj0P1kqZySWqIuN4t6QaIO/YA6SFwySOLruvWQFzfmqk8LBK2P30KCSJwf6mJCZZ5/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.1.5': - resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} + '@rolldown/binding-win32-x64-msvc@1.2.2': + resolution: {integrity: sha512-NweNxxD0Nf9t8v7kodun45Ijp3EIwYY+uydPP6qBEYvfBqhIjN6dZMzlQja3tqX/aLs3F3Uz+AxDpKgRhpOZQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -329,15 +301,12 @@ packages: '@types/react-dom': optional: true - '@testing-library/user-event@14.6.1': - resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + '@testing-library/user-event@14.6.3': + resolution: {integrity: sha512-6dBq67jT8lE+JTE8Exm02Kt6ze43hz1jdiSpSJwtTZiT1xQQ6b7nZYTTQ9njdArdU8XklOwaDp/AbT/eYSKF4g==} engines: {node: '>=12', npm: '>=6'} peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -359,16 +328,16 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/node@26.1.1': - resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} + '@types/node@26.1.2': + resolution: {integrity: sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==} - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + '@types/react-dom@19.2.4': + resolution: {integrity: sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==} peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.17': - resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + '@types/react@19.2.18': + resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -496,8 +465,8 @@ packages: cpu: [x64] os: [win32] - '@vitejs/plugin-react@6.0.3': - resolution: {integrity: sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==} + '@vitejs/plugin-react@6.0.5': + resolution: {integrity: sha512-BOVzne/NL162sMdResB25mUv+vWMF5NoAjNf09TeGlE7ZpszZWSD3winycicLJw72yeVsoCn/2kOhEuCvEShMA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 @@ -547,8 +516,8 @@ packages: '@vitest/utils@4.1.10': resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} - '@wailsio/runtime@3.0.0-alpha2.117': - resolution: {integrity: sha512-RZr6cncIXjdTbn2IqJ6AZXPm9WooaZEsNlNfaUH+Ru/YlH5sKDDeRdWpbcvsgoMLh4AJ+O8aBzZEiTYWDipGxw==} + '@wailsio/runtime@3.0.0-beta.1': + resolution: {integrity: sha512-y0FFOONsaWyRbQItjERV9sjUFmO4M5XGrHE8aX+rdYQG3YclTfYkMrpalMQcdxEh1CUrrpyvLabHt/2zCFnv+Q==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -701,11 +670,11 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - jsdom@29.1.1: - resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} + jsdom@30.0.1: + resolution: {integrity: sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==} + engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} peerDependencies: - canvas: ^3.0.0 + canvas: ^3.2.3 peerDependenciesMeta: canvas: optional: true @@ -788,8 +757,8 @@ packages: resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} - lucide-react@1.25.0: - resolution: {integrity: sha512-/mdJTRbiwcLOQ1NZZK1amZF9rIZyvO18D6r9TngE6TG1NmqHgFuT4eE7Xrkm9UsXMbBJD1NlfwHVltCDWHrOTw==} + lucide-react@1.28.0: + resolution: {integrity: sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -800,8 +769,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + magicast@0.5.4: + resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -814,8 +783,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - nanoid@3.3.16: - resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} + nanoid@3.3.17: + resolution: {integrity: sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -836,18 +805,18 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} - playwright-core@1.61.1: - resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} - engines: {node: '>=18'} + playwright-core@1.62.1: + resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==} + engines: {node: '>=20'} hasBin: true - playwright@1.61.1: - resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} - engines: {node: '>=18'} + playwright@1.62.1: + resolution: {integrity: sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==} + engines: {node: '>=20'} hasBin: true - postcss@8.5.24: - resolution: {integrity: sha512-8RyVklq0owXUTa4xlpzu4l9AaVKIdQvAcOHZWaMh98HgySsUtxRVf/chRe3dsSLqb6i40BzGRzEUddRaI+9TSw==} + postcss@8.5.25: + resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} engines: {node: ^10 || ^12 || >=14} pretty-format@27.0.2: @@ -866,15 +835,15 @@ packages: react-is@17.0.1: resolution: {integrity: sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==} - react-router-dom@7.18.1: - resolution: {integrity: sha512-KaZh+X/6UtEp28x51AUYZDMg9NGoz2ja3dNHa+ta/tk40vCzKhQ/RypCWBMLbmDr6//E24Vv5uPsrqXFozdkAg==} + react-router-dom@7.18.2: + resolution: {integrity: sha512-AIKJ/jgGlFb3EbfCXk5Gzshiwt+l3mqbCrNjmEWMMjqQxNJ3svBa6bgzFyCC2Sw3RA0VWF1kg3uQf2OFhxb8hw==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' react-dom: '>=18' - react-router@7.18.1: - resolution: {integrity: sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==} + react-router@7.18.2: + resolution: {integrity: sha512-aUVMjFm3GAPTTZL7oYr5E7ETiqfQCHRLH+B+5afnICvf0r7kkK4eR6SMuwbSTJw/7t+12khT/Kahij49fqOCIg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -895,8 +864,8 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - rolldown@1.1.5: - resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} + rolldown@1.2.2: + resolution: {integrity: sha512-opwpo1tQBAcpSUJDt94B7hhLNGOKjCdE//XXjeLrnx9b83bjnw45tXdg1b09yEw/VLFBJGZpwRULMmOZo7ol+A==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -942,8 +911,8 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} engines: {node: '>=18'} tinyglobby@0.2.17: @@ -954,11 +923,11 @@ packages: resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} engines: {node: '>=14.0.0'} - tldts-core@7.4.9: - resolution: {integrity: sha512-DxKfPBI52p2msTEu7MPhdpdDTBhhVQg1a/8PjQckeyAvO13eMYElX545grIp6nnTGIMZlRvFZPvFhvI/WIz2Vg==} + tldts-core@7.4.10: + resolution: {integrity: sha512-KnQjp53ZekKgm/r3l+u8kJGGzYgrWdP8+Mql7a4vijh2WE0IrZWspQj/TpTxDho/YxO+AnOZnIjQcCD+q6iJsw==} - tldts@7.4.9: - resolution: {integrity: sha512-3kZ8wQQ/k5DrChD4X4FVvr2D7E5uoRgAqkPyLpSCGUvqOvqu+JEdr3mwMUaVWb+vMHZaKhF5fp2PBigKsui7hA==} + tldts@7.4.10: + resolution: {integrity: sha512-GgouD1B+sWwvkaEq8vXC15DjQitxbvs12oIXELpconwm+Tg3zfcEv4jgzq3vtKverDXsg3VI8aRgNL2Nra0Iog==} hasBin: true tough-cookie@6.0.2: @@ -969,9 +938,6 @@ packages: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - typescript@7.0.2: resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} engines: {node: '>=16.20.0'} @@ -980,17 +946,17 @@ packages: undici-types@8.3.0: resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} - undici@7.29.0: - resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} - engines: {node: '>=20.18.1'} + undici@8.10.0: + resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} + engines: {node: '>=22.19.0'} - vite@8.1.5: - resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==} + vite@8.2.0: + resolution: {integrity: sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.3.0 + '@vitejs/devtools': ^0.4.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -1084,6 +1050,10 @@ packages: resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + whatwg-url@17.1.0: + resolution: {integrity: sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==} + engines: {node: ^22.14.0 || >=24.0.0} + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -1100,25 +1070,20 @@ snapshots: '@adobe/css-tools@4.5.0': {} - '@asamuzakjp/css-color@5.1.11': + '@asamuzakjp/css-color@6.0.5': dependencies: - '@asamuzakjp/generational-cache': 1.0.1 '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-color-parser': 4.1.10(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 + lru-cache: 11.5.2 - '@asamuzakjp/dom-selector@7.1.1': + '@asamuzakjp/dom-selector@8.3.2': dependencies: - '@asamuzakjp/generational-cache': 1.0.1 - '@asamuzakjp/nwsapi': 2.3.9 bidi-js: 1.0.3 css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 - - '@asamuzakjp/generational-cache@1.0.1': {} - - '@asamuzakjp/nwsapi@2.3.9': {} + lru-cache: 11.5.2 '@babel/code-frame@7.29.7': dependencies: @@ -1130,13 +1095,13 @@ snapshots: '@babel/helper-validator-identifier@7.29.7': {} - '@babel/parser@7.29.7': + '@babel/parser@7.29.8': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@babel/runtime@7.29.7': {} - '@babel/types@7.29.7': + '@babel/types@7.29.8': dependencies: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 @@ -1171,29 +1136,13 @@ snapshots: '@csstools/css-tokenizer@4.0.0': {} - '@emnapi/core@1.11.1': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - '@exodus/bytes@1.15.1': {} '@jest/types@27.0.2': dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 26.1.1 + '@types/node': 26.1.2 '@types/yargs': 16.0.11 chalk: 4.0.0 @@ -1208,66 +1157,52 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.14 - '@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@oxc-project/types@0.139.0': {} + '@oxc-project/types@0.142.0': {} - '@playwright/test@1.61.1': + '@playwright/test@1.62.1': dependencies: - playwright: 1.61.1 + playwright: 1.62.1 - '@rolldown/binding-android-arm64@1.1.5': + '@rolldown/binding-android-arm64@1.2.2': optional: true - '@rolldown/binding-darwin-arm64@1.1.5': + '@rolldown/binding-darwin-arm64@1.2.2': optional: true - '@rolldown/binding-darwin-x64@1.1.5': + '@rolldown/binding-darwin-x64@1.2.2': optional: true - '@rolldown/binding-freebsd-x64@1.1.5': + '@rolldown/binding-freebsd-x64@1.2.2': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + '@rolldown/binding-linux-arm-gnueabihf@1.2.2': optional: true - '@rolldown/binding-linux-arm64-gnu@1.1.5': + '@rolldown/binding-linux-arm64-gnu@1.2.2': optional: true - '@rolldown/binding-linux-arm64-musl@1.1.5': + '@rolldown/binding-linux-arm64-musl@1.2.2': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.1.5': + '@rolldown/binding-linux-ppc64-gnu@1.2.2': optional: true - '@rolldown/binding-linux-s390x-gnu@1.1.5': + '@rolldown/binding-linux-s390x-gnu@1.2.2': optional: true - '@rolldown/binding-linux-x64-gnu@1.1.5': + '@rolldown/binding-linux-x64-gnu@1.2.2': optional: true - '@rolldown/binding-linux-x64-musl@1.1.5': + '@rolldown/binding-linux-x64-musl@1.2.2': optional: true - '@rolldown/binding-openharmony-arm64@1.1.5': - optional: true - - '@rolldown/binding-wasm32-wasi@1.1.5': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.2.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + '@rolldown/binding-openharmony-arm64@1.2.2': optional: true - '@rolldown/binding-win32-arm64-msvc@1.1.5': + '@rolldown/binding-win32-arm64-msvc@1.2.2': optional: true - '@rolldown/binding-win32-x64-msvc@1.1.5': + '@rolldown/binding-win32-x64-msvc@1.2.2': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -1295,25 +1230,20 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 '@testing-library/dom': 10.4.1 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: - '@types/react': 19.2.17 - '@types/react-dom': 19.2.3(@types/react@19.2.17) + '@types/react': 19.2.18 + '@types/react-dom': 19.2.4(@types/react@19.2.18) - '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + '@testing-library/user-event@14.6.3(@testing-library/dom@10.4.1)': dependencies: '@testing-library/dom': 10.4.1 - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - '@types/aria-query@5.0.4': {} '@types/chai@5.2.3': @@ -1335,15 +1265,15 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/node@26.1.1': + '@types/node@26.1.2': dependencies: undici-types: 8.3.0 - '@types/react-dom@19.2.3(@types/react@19.2.17)': + '@types/react-dom@19.2.4(@types/react@19.2.18)': dependencies: - '@types/react': 19.2.17 + '@types/react': 19.2.18 - '@types/react@19.2.17': + '@types/react@19.2.18': dependencies: csstype: 3.2.3 @@ -1413,10 +1343,10 @@ snapshots: '@typescript/typescript-win32-x64@7.0.2': optional: true - '@vitejs/plugin-react@6.0.3(vite@8.1.5(@types/node@26.1.1))': + '@vitejs/plugin-react@6.0.5(vite@8.2.0(@types/node@26.1.2))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.1.5(@types/node@26.1.1) + vite: 8.2.0(@types/node@26.1.2) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -1426,11 +1356,11 @@ snapshots: istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 - magicast: 0.5.3 + magicast: 0.5.4 obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(jsdom@29.1.1)(vite@8.1.5(@types/node@26.1.1)) + vitest: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(jsdom@30.0.1)(vite@8.2.0(@types/node@26.1.2)) '@vitest/expect@4.1.10': dependencies: @@ -1441,13 +1371,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@26.1.1))': + '@vitest/mocker@4.1.10(vite@8.2.0(@types/node@26.1.2))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.1.5(@types/node@26.1.1) + vite: 8.2.0(@types/node@26.1.2) '@vitest/pretty-format@4.1.10': dependencies: @@ -1473,7 +1403,7 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.1 - '@wailsio/runtime@3.0.0-alpha2.117': {} + '@wailsio/runtime@3.0.0-beta.1': {} ansi-regex@5.0.1: {} @@ -1595,10 +1525,10 @@ snapshots: js-tokens@4.0.0: {} - jsdom@29.1.1: + jsdom@30.0.1: dependencies: - '@asamuzakjp/css-color': 5.1.11 - '@asamuzakjp/dom-selector': 7.1.1 + '@asamuzakjp/css-color': 6.0.5 + '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 '@csstools/css-syntax-patches-for-csstree': 1.1.7(css-tree@3.2.1) '@exodus/bytes': 1.15.1 @@ -1612,11 +1542,11 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.2 - undici: 7.29.0 + undici: 8.10.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 + whatwg-url: 17.1.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' @@ -1672,7 +1602,7 @@ snapshots: lru-cache@11.5.2: {} - lucide-react@1.25.0(react@19.2.8): + lucide-react@1.28.0(react@19.2.8): dependencies: react: 19.2.8 @@ -1682,10 +1612,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.5.3: + magicast@0.5.4: dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 source-map-js: 1.2.1 make-dir@4.0.0: @@ -1696,7 +1626,7 @@ snapshots: min-indent@1.0.1: {} - nanoid@3.3.16: {} + nanoid@3.3.17: {} obug@2.1.4: {} @@ -1710,17 +1640,17 @@ snapshots: picomatch@4.0.5: {} - playwright-core@1.61.1: {} + playwright-core@1.62.1: {} - playwright@1.61.1: + playwright@1.62.1: dependencies: - playwright-core: 1.61.1 + playwright-core: 1.62.1 optionalDependencies: fsevents: 2.3.2 - postcss@8.5.24: + postcss@8.5.25: dependencies: - nanoid: 3.3.16 + nanoid: 3.3.17 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -1740,13 +1670,13 @@ snapshots: react-is@17.0.1: {} - react-router-dom@7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + react-router-dom@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - react-router: 7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react-router: 7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react-router@7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: cookie: 1.0.1 react: 19.2.8 @@ -1763,26 +1693,25 @@ snapshots: require-from-string@2.0.2: {} - rolldown@1.1.5: + rolldown@1.2.2: dependencies: - '@oxc-project/types': 0.139.0 + '@oxc-project/types': 0.142.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.5 - '@rolldown/binding-darwin-arm64': 1.1.5 - '@rolldown/binding-darwin-x64': 1.1.5 - '@rolldown/binding-freebsd-x64': 1.1.5 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 - '@rolldown/binding-linux-arm64-gnu': 1.1.5 - '@rolldown/binding-linux-arm64-musl': 1.1.5 - '@rolldown/binding-linux-ppc64-gnu': 1.1.5 - '@rolldown/binding-linux-s390x-gnu': 1.1.5 - '@rolldown/binding-linux-x64-gnu': 1.1.5 - '@rolldown/binding-linux-x64-musl': 1.1.5 - '@rolldown/binding-openharmony-arm64': 1.1.5 - '@rolldown/binding-wasm32-wasi': 1.1.5 - '@rolldown/binding-win32-arm64-msvc': 1.1.5 - '@rolldown/binding-win32-x64-msvc': 1.1.5 + '@rolldown/binding-android-arm64': 1.2.2 + '@rolldown/binding-darwin-arm64': 1.2.2 + '@rolldown/binding-darwin-x64': 1.2.2 + '@rolldown/binding-freebsd-x64': 1.2.2 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.2 + '@rolldown/binding-linux-arm64-gnu': 1.2.2 + '@rolldown/binding-linux-arm64-musl': 1.2.2 + '@rolldown/binding-linux-ppc64-gnu': 1.2.2 + '@rolldown/binding-linux-s390x-gnu': 1.2.2 + '@rolldown/binding-linux-x64-gnu': 1.2.2 + '@rolldown/binding-linux-x64-musl': 1.2.2 + '@rolldown/binding-openharmony-arm64': 1.2.2 + '@rolldown/binding-win32-arm64-msvc': 1.2.2 + '@rolldown/binding-win32-x64-msvc': 1.2.2 saxes@6.0.0: dependencies: @@ -1814,7 +1743,7 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.2.4: {} + tinyexec@1.3.0: {} tinyglobby@0.2.17: dependencies: @@ -1823,23 +1752,20 @@ snapshots: tinyrainbow@3.1.1: {} - tldts-core@7.4.9: {} + tldts-core@7.4.10: {} - tldts@7.4.9: + tldts@7.4.10: dependencies: - tldts-core: 7.4.9 + tldts-core: 7.4.10 tough-cookie@6.0.2: dependencies: - tldts: 7.4.9 + tldts: 7.4.10 tr46@6.0.0: dependencies: punycode: 2.3.1 - tslib@2.8.1: - optional: true - typescript@7.0.2: optionalDependencies: '@typescript/typescript-aix-ppc64': 7.0.2 @@ -1865,23 +1791,23 @@ snapshots: undici-types@8.3.0: {} - undici@7.29.0: {} + undici@8.10.0: {} - vite@8.1.5(@types/node@26.1.1): + vite@8.2.0(@types/node@26.1.2): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 - postcss: 8.5.24 - rolldown: 1.1.5 + postcss: 8.5.25 + rolldown: 1.2.2 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.1.1 + '@types/node': 26.1.2 fsevents: 2.3.3 - vitest@4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(jsdom@29.1.1)(vite@8.1.5(@types/node@26.1.1)): + vitest@4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(jsdom@30.0.1)(vite@8.2.0(@types/node@26.1.2)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.1)) + '@vitest/mocker': 4.1.10(vite@8.2.0(@types/node@26.1.2)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -1895,15 +1821,15 @@ snapshots: picomatch: 4.0.5 std-env: 4.2.0 tinybench: 2.9.0 - tinyexec: 1.2.4 + tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.1.5(@types/node@26.1.1) + vite: 8.2.0(@types/node@26.1.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 26.1.1 + '@types/node': 26.1.2 '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) - jsdom: 29.1.1 + jsdom: 30.0.1 transitivePeerDependencies: - msw @@ -1923,6 +1849,14 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + whatwg-url@17.1.0: + dependencies: + '@exodus/bytes': 1.15.1 + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 diff --git a/frontend/src/backend/wails.test.ts b/frontend/src/backend/wails.test.ts index 823efba..85a7ecc 100644 --- a/frontend/src/backend/wails.test.ts +++ b/frontend/src/backend/wails.test.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import type { DesktopAgentActionResult, DesktopAgentProfileResult, DesktopAgentStatus, InstallResponse, ModelsResponse, ProbeResponse, ProfileSummary, ProviderEntry, StatusResponse } from "../types/api"; import { LOCALE_STORAGE_KEY } from "../i18n"; +import type { DesktopAgentActionResult, DesktopAgentProfileResult, DesktopAgentStatus, InstallResponse, ModelsResponse, ProbeResponse, ProfileSummary, ProviderEntry, StatusResponse } from "../types/api"; const bridge = vi.hoisted(() => ({ status: vi.fn(), @@ -28,7 +28,15 @@ const bridge = vi.hoisted(() => ({ })); vi.mock("@wailsio/runtime", async (importOriginal) => ({ - ...(await importOriginal()), + ...await (async () => { + const domWindow = globalThis.window; + vi.stubGlobal("window", undefined); + try { + return await importOriginal(); + } finally { + vi.stubGlobal("window", domWindow); + } + })(), Events: { On: bridge.eventsOn }, })); vi.mock("../../bindings/github.com/MaimoryLab/OneAgent/internal/binding/statusservice.js", () => ({ GetStatus: bridge.status })); diff --git a/frontend/src/components/AdvancedSection.test.tsx b/frontend/src/components/AdvancedSection.test.tsx index 47c07f3..47d49e9 100644 --- a/frontend/src/components/AdvancedSection.test.tsx +++ b/frontend/src/components/AdvancedSection.test.tsx @@ -5,7 +5,7 @@ import { AdvancedSection } from "./AdvancedSection"; function renderSection() { render( - + , diff --git a/frontend/src/components/AgentManageRow.tsx b/frontend/src/components/AgentManageRow.tsx index 095a5e9..fa52774 100644 --- a/frontend/src/components/AgentManageRow.tsx +++ b/frontend/src/components/AgentManageRow.tsx @@ -50,7 +50,7 @@ export function isBehind(installed: string, locked: string): boolean { return compareVersions(installed, locked) < 0; } -export function versionNote(status: AgentStatus, t: Translate = sourceTranslate): { text: string; behind: boolean } | null { +function versionNote(status: AgentStatus, t: Translate = sourceTranslate): { text: string; behind: boolean } | null { if (!status.installed || !status.version) return null; if (!status.lockedVersion || status.version === status.lockedVersion) { // Being current is the normal case and needs no words: the bare version is diff --git a/frontend/src/components/MirrorSetting.tsx b/frontend/src/components/MirrorSetting.tsx index 3e601c4..9d7f3a8 100644 --- a/frontend/src/components/MirrorSetting.tsx +++ b/frontend/src/components/MirrorSetting.tsx @@ -64,10 +64,10 @@ export function MirrorSetting({ label }: { label?: string }) { // on a machine that is about to use the mirror would be worse than saying // nothing. const hint = fromRegion - ? t("已根据系统地区设置默认使用镜像。可以改回官方源。") + ? t("已根据系统地区设置默认使用镜像。可以改回官方源") : preferMirror - ? t("正在优先使用国内镜像。") - : t("默认使用官方源。国内网络较慢时可以改用镜像。"); + ? t("正在优先使用国内镜像") + : t("默认使用官方源。国内网络较慢时可以改用镜像"); return ( @@ -77,8 +77,8 @@ export function MirrorSetting({ label }: { label?: string }) { {t("优先使用国内镜像")} {fromRegion - ? t("已根据系统语言/地区自动开启。运行时仍校验固定哈希,npm 使用镜像 registry 的包元数据。") - : t("同时作用于运行时下载和 npm 安装的 Agent;运行时仍校验固定哈希并在下载失败时回退。Aider(uv)不受影响。")} + ? t("已根据系统语言/地区自动开启。运行时仍校验固定哈希,npm 使用镜像 registry 的包元数据") + : t("同时作用于运行时下载和 npm 安装的 Agent;运行时仍校验固定哈希并在下载失败时回退。Aider(uv)不受影响")} {t("需要先安装运行时")}
- {t("所选 Agent 通过 {runtimes} 安装,本机还没有。现在安装,或在激活时自动安装。", { runtimes: required.map((runtime) => runtime.name).join("、") })} + {t("所选 Agent 通过 {runtimes} 安装,本机还没有。现在安装,或在激活时自动安装", { runtimes: required.map((runtime) => runtime.name).join("、") })}
{required.map((runtime) => (
- {t("密钥只发送到当前本机服务,并保存在本机私有配置中。")} + {t("密钥只发送到当前本机服务,并保存在本机私有配置中")}
); } diff --git a/frontend/src/components/SelectField.tsx b/frontend/src/components/SelectField.tsx index dbae470..270cb8f 100644 --- a/frontend/src/components/SelectField.tsx +++ b/frontend/src/components/SelectField.tsx @@ -1,7 +1,7 @@ import { Check, ChevronDown } from "lucide-react"; import { useEffect, useId, useLayoutEffect, useRef, useState } from "react"; -export interface SelectOption { +interface SelectOption { value: string; label: string; disabled?: boolean; diff --git a/frontend/src/i18n.tsx b/frontend/src/i18n.tsx index 6072a27..420258e 100644 --- a/frontend/src/i18n.tsx +++ b/frontend/src/i18n.tsx @@ -65,7 +65,7 @@ const english = { "粘贴你的 API Key": "Paste your API key", "隐藏密钥": "Hide API key", "显示密钥": "Show API key", - "密钥只发送到当前本机服务,并保存在本机私有配置中。": "The key is sent only to the local service and stored in private local configuration.", + "密钥只发送到当前本机服务,并保存在本机私有配置中": "The key is sent only to the local service and stored in private local configuration", "激活步骤": "Setup steps", "已跳过": "Skipped", "配置": "Configure", @@ -108,8 +108,8 @@ const english = { "未配置": "Not configured", "{version}(锁定 {lockedVersion})": "{version} (locked to {lockedVersion})", "选择 Agent": "Select agents", - "选择要安装的桌面 Agent,每次安装一个。": "Choose the desktop agent to install. One per run.", - "安装应用后,会把选定的 Profile 应用到对应的配置。": "After installation, the selected profile is applied to the matching configuration.", + "选择要安装的桌面 Agent,每次安装一个": "Choose the desktop agent to install. One per run", + "安装应用后,会把选定的 Profile 应用到对应的配置": "After installation, the selected profile is applied to the matching configuration", "不支持": "Unsupported", "与 {name} 共用配置": "Shares configuration with {name}", "已安装,可直接应用 Profile": "Installed; a profile can be applied now", @@ -117,7 +117,7 @@ const english = { "检测到本机已有此应用": "This application is already installed", "选择配置模板": "Select a profile", "Profile选择": "Select profile", - "选择一个已有 Profile,或新建 Profile。": "Choose an existing profile or create a new one.", + "选择一个已有 Profile,或新建 Profile": "Choose an existing profile or create a new one", "新建 Profile": "Create profile", "创建 Profile": "Create profile", "选择一个 Profile": "Select a profile", @@ -126,37 +126,37 @@ const english = { "按引导安装桌面 Agent": "Follow the guide to install a desktop Agent", "确认安装": "Review installation", "将重新检查": "Recheck", - "选择这次要安装并配置的开发工具,每次安装一个。": "Choose the development tool to install and configure. One per run.", + "选择这次要安装并配置的开发工具,每次安装一个": "Choose the development tool to install and configure. One per run", "选择一个 Agent": "Select one agent", "正在检测本机环境": "Detecting the local environment", "常用 Agent": "Popular agents", - "可一键配置的默认安装最新版本,仅引导的只显示官方步骤。": "One-click agents install the latest version by default; guide-only agents show official steps.", + "可一键配置的默认安装最新版本,仅引导的只显示官方步骤": "One-click agents install the latest version by default; guide-only agents show official steps", "更多 Agent({count})": "More agents ({count})", "网关、平台账号与 IDE 扩展": "Gateways, platform accounts, and IDE extensions", "无法读取已保存的 API Key": "Could not read the saved API key", "连接测试失败": "Connection test failed", "无法打开注册页面": "Could not open the registration page", "连接模型服务": "Connect a model provider", - "Key 不会进入日志、URL 或前端持久化状态。": "The key is never written to logs, URLs, or persistent frontend state.", + "Key 不会进入日志、URL 或前端持久化状态": "The key is never written to logs, URLs, or persistent frontend state", "继续选择模型": "Continue to model selection", "注册并获取 Key": "Register and get a key", "自定义模型名称(可选)": "Custom model name (optional)", - "填写后将用此模型测试连接;留空时自动选择。": "When provided, this model is used for the connection test. Leave blank to select automatically.", - "可选,仅用于测试连接;实际配置模型在下一步选择。": "Optional; used only for the connection test. Choose the configured model in the next step.", + "填写后将用此模型测试连接;留空时自动选择": "When provided, this model is used for the connection test. Leave blank to select automatically", + "可选,仅用于测试连接;实际配置模型在下一步选择": "Optional; used only for the connection test. Choose the configured model in the next step", "测试连接": "Test connection", "修改这个 Agent 指向的 Provider 与模型": "Change which Provider and model this agent points at", - "留空则使用该 Provider 已保存的 Key。": "Leave blank to use the key already saved for this Provider.", - "未测试连接也可以应用,配置文件会先备份。": "You can apply without testing. The configuration file is backed up first.", - "连接测试通过后才能继续选择模型。": "Pass the connection test before selecting a model.", - "连接测试是可选的,可以直接继续选择模型。": "Connection testing is optional; you can continue to select a model directly.", + "留空则使用该 Provider 已保存的 Key": "Leave blank to use the key already saved for this Provider", + "未测试连接也可以应用,配置文件会先备份": "You can apply without testing. The configuration file is backed up first", + "连接测试通过后才能继续选择模型": "Pass the connection test before selecting a model", + "连接测试是可选的,可以直接继续选择模型": "Connection testing is optional; you can continue to select a model directly", "无法获取模型列表": "Could not load the model list", - "找到 {count} 个模型": "Found {count} models.", + "找到 {count} 个模型": "Found {count} models", "选择模型": "Select a model", - "从当前 Key 可访问的模型中选择,接口不支持时可直接输入模型 ID。": "Choose a model accessible with this key, or enter a model ID when discovery is unavailable.", + "从当前 Key 可访问的模型中选择,接口不支持时可直接输入模型 ID": "Choose a model accessible with this key, or enter a model ID when discovery is unavailable", "刷新列表": "Refresh list", "正在读取模型列表": "Loading models", "确认激活": "Review activation", - "核对安装、配置和备份范围。API Key 不会显示在此页。": "Review the installation, configuration, and backup scope. The API key is not shown here.", + "核对安装、配置和备份范围。API Key 不会显示在此页": "Review the installation, configuration, and backup scope. The API key is not shown here", "开始安装": "Start installation", "配置模板名称": "Profile name", "这次安装会保存为一个配置模板,之后可以直接应用": "This run is saved as a profile you can apply", @@ -181,17 +181,17 @@ const english = { "安装 Agent": "Install agent", "尚未安装任何 Agent": "No agents installed yet", "需要处理部分问题": "Some items need attention", - "安装请求同步执行,完成后将显示每个 Agent 的最终状态。": "Installation runs synchronously. Each agent's final status appears when it completes.", - "每个 Agent 的结果彼此独立,失败项可以单独重试。": "Each agent has an independent result. Failed items can be retried individually.", + "安装请求同步执行,完成后将显示每个 Agent 的最终状态": "Installation runs synchronously. Each agent's final status appears when it completes", + "每个 Agent 的结果彼此独立,失败项可以单独重试": "Each agent has an independent result. Failed items can be retried individually", "进入总览": "Open overview", "请保持此窗口打开": "Keep this window open", "下一步命令": "Next command", "环境总览": "Environment overview", "正在读取环境状态": "Loading environment status", - "本机已安装 Agent 及其当前配置。": "Installed agents and their current local configuration.", + "本机已安装 Agent 及其当前配置": "Installed agents and their current local configuration", "无法读取环境状态": "Could not load environment status", - "请刷新后重试。": "Refresh and try again.", - "本机已安装 Agent 及其当前 Provider、Profile 与模型。": "Installed agents and their current providers, profiles, and models.", + "请刷新后重试": "Refresh and try again", + "本机已安装 Agent 及其当前 Provider、Profile 与模型": "Installed agents and their current providers, profiles, and models", "刷新状态": "Refresh status", "桌面 Agent": "Desktop Agent", "与 {name} 共用配置文件 {path};安装和启动不会改动配置": "Shares the {path} configuration file with {name}; installation and launch do not modify it", @@ -221,8 +221,8 @@ const english = { "有新版本 {version},点击更新": "Version {version} is available; click to update", "无法更新 Agent": "Could not update the agent", "运行时": "Runtimes", - "缺少 {count} 个运行时,安装后即可自动安装对应 Agent。": "{count} runtime(s) missing. Install them to enable automatic agent installation.", - "Agent 安装所需的运行时都已就绪。": "Every runtime needed to install agents is ready.", + "缺少 {count} 个运行时,安装后即可自动安装对应 Agent": "{count} runtime(s) missing. Install them to enable automatic agent installation", + "Agent 安装所需的运行时都已就绪": "Every runtime needed to install agents is ready", "运行时安装失败": "Could not install the runtime", "版本 {version}": "Version {version}", "版本未知": "Version unknown", @@ -234,26 +234,26 @@ const english = { "安装": "Install", "安装 {name}": "Install {name}", "安装中": "Installing", - "运行时会安装到 {dir},并写入登录 PATH,不需要管理员权限。": "Runtimes install into {dir} and are added to your login PATH. No administrator rights needed.", - "运行时会安装到 OneAgent 的托管目录,并写入登录 PATH,不需要管理员权限。": "Runtimes install into OneAgent's managed directory and are added to your login PATH. No administrator rights needed.", + "运行时会安装到 {dir},并写入登录 PATH,不需要管理员权限": "Runtimes install into {dir} and are added to your login PATH. No administrator rights needed", + "运行时会安装到 OneAgent 的托管目录,并写入登录 PATH,不需要管理员权限": "Runtimes install into OneAgent's managed directory and are added to your login PATH. No administrator rights needed", "运行时下载": "Runtime downloads", "下载源": "Download source", "Agent 安装源": "Agent install source", - "默认使用官方源。国内网络较慢时可以改用镜像。": "Uses the official source by default. Switch to a mirror if it is slow from your network.", - "正在优先使用国内镜像。": "Downloading from a regional mirror first.", - "已根据系统地区设置默认使用镜像。可以改回官方源。": "A mirror is the default here based on your system region. You can switch back to the official source.", + "默认使用官方源。国内网络较慢时可以改用镜像": "Uses the official source by default. Switch to a mirror if it is slow from your network", + "正在优先使用国内镜像": "Downloading from a regional mirror first", + "已根据系统地区设置默认使用镜像。可以改回官方源": "A mirror is the default here based on your system region. You can switch back to the official source", "优先使用国内镜像": "Prefer a regional mirror", - "同时作用于运行时下载和 npm 安装的 Agent;运行时仍校验固定哈希并在下载失败时回退。Aider(uv)不受影响。": "Applies to runtime downloads and npm-installed agents. Runtime downloads still verify their pinned hash and fall back after a failed download. Aider (uv) is unaffected.", - "已根据系统语言/地区自动开启。运行时仍校验固定哈希,npm 使用镜像 registry 的包元数据。": "Enabled automatically from your system language and region. Runtimes still verify their pinned hash; npm uses package metadata from the mirror registry.", + "同时作用于运行时下载和 npm 安装的 Agent;运行时仍校验固定哈希并在下载失败时回退。Aider(uv)不受影响": "Applies to runtime downloads and npm-installed agents. Runtime downloads still verify their pinned hash and fall back after a failed download. Aider (uv) is unaffected", + "已根据系统语言/地区自动开启。运行时仍校验固定哈希,npm 使用镜像 registry 的包元数据": "Enabled automatically from your system language and region. Runtimes still verify their pinned hash; npm uses package metadata from the mirror registry", "无法保存下载设置": "Could not save the download setting", "需要先安装运行时": "A runtime is needed first", - "所选 Agent 通过 {runtimes} 安装,本机还没有。现在安装,或在激活时自动安装。": "The selected agents install through {runtimes}, which is not on this machine yet. Install it now, or let activation install it.", + "所选 Agent 通过 {runtimes} 安装,本机还没有。现在安装,或在激活时自动安装": "The selected agents install through {runtimes}, which is not on this machine yet. Install it now, or let activation install it", "安装 {name} {version}": "Install {name} {version}", "按引导安装命令行 Agent": "Follow the guide to install your first command-line agent", "找不到可配置的 Agent": "Configurable agent not found", "找不到 Agent": "Agent not found", - "{id} 不在可一键配置的范围内。": "{id} is not available for one-click setup.", - "未指定 Agent。": "No agent specified.", + "{id} 不在可一键配置的范围内": "{id} is not available for one-click setup", + "未指定 Agent": "No agent specified", "应用配置失败": "Could not apply configuration", "应用中": "Applying", "应用": "Apply", @@ -267,7 +267,7 @@ const english = { "当前指向 {target}。应用后会被替换,原文件会先备份到同目录的": "Currently points to {target}. Applying will replace it; the original file will first be backed up in the same directory as", "时间戳": "timestamp", "将测试 {protocol} 协议": "Testing the {protocol} protocol", - "可以指定具体模型。留空时由端点的模型列表自动选择,多数情况保持默认即可。": "Optionally choose a specific model. Leave blank for endpoint discovery; the default works in most cases.", + "可以指定具体模型。留空时由端点的模型列表自动选择,多数情况保持默认即可": "Optionally choose a specific model. Leave blank for endpoint discovery; the default works in most cases", "留空则由端点的模型列表自动选择": "Leave blank to select from the endpoint's model list", "快速小模型": "Fast small model", "找不到桌面 Agent": "Desktop agent not found", @@ -283,7 +283,7 @@ const english = { "{agents} 重新应用失败:{message}": "Could not reapply to {agents}: {message}", "删除 Provider“{name}”?": "Delete provider \"{name}\"?", "无法删除 Provider": "Could not delete provider", - "管理模型服务、端点与本机保存的 API Key。": "Manage model providers, endpoints, and locally saved API keys.", + "管理模型服务、端点与本机保存的 API Key": "Manage model providers, endpoints, and locally saved API keys", "编辑 {name}": "Edit {name}", "用户添加": "User added", "官网": "Website", @@ -297,27 +297,27 @@ const english = { "暂无 Agent 使用": "Not used by any agent", "已保存 Key": "Key saved", "未保存 Key": "No saved key", - "用户 Provider 的协议兼容性由你自己保证,OneAgent 不会为它降级或改写请求。": "You are responsible for custom provider protocol compatibility. OneAgent does not downgrade or rewrite requests.", + "用户 Provider 的协议兼容性由你自己保证,OneAgent 不会为它降级或改写请求": "You are responsible for custom provider protocol compatibility. OneAgent does not downgrade or rewrite requests", "无法保存 Profile": "Could not save profile", "应用 Profile 失败": "Could not apply profile", "{name} 已应用到 {count} 个 Agent": "Applied {name} to {count} agents", "无法应用 Profile": "Could not apply profile", - "在这里创建 Profile,再将它应用到所选 Agent。": "Create profiles here, then apply them to selected agents.", + "在这里创建 Profile,再将它应用到所选 Agent": "Create profiles here, then apply them to selected agents", "新增 Profile": "Add profile", - "将使用 Provider 已保存的 Key。": "Uses the provider's saved key.", - "这个 Provider 还没有 Key,先到 Provider 页面填写。": "This provider has no key yet. Add one on the Provider page.", + "将使用 Provider 已保存的 Key": "Uses the provider's saved key", + "这个 Provider 还没有 Key,先到 Provider 页面填写": "This provider has no key yet. Add one on the Provider page", "前往 Provider": "Open Provider", "保存 Profile": "Save profile", "删除 Profile": "Delete profile", "编辑 Profile": "Edit profile", - "为 {name} 选择关联的 Profile。": "Choose the profile linked to {name}.", - "这个 Provider 还没有 Key,请先到 Provider 页面填写。": "This provider has no key yet. Add one on the Provider page.", + "为 {name} 选择关联的 Profile": "Choose the profile linked to {name}", + "这个 Provider 还没有 Key,请先到 Provider 页面填写": "This provider has no key yet. Add one on the Provider page", "这个 Profile 还缺少 Provider Key 或模型": "This profile is missing a provider key or model", - "创建一个 Profile 后即可应用到这个 Agent。": "Create a profile, then apply it to this agent.", + "创建一个 Profile 后即可应用到这个 Agent": "Create a profile, then apply it to this agent", "未指定": "Not specified", "应用完成": "Applied", "还没有 Profile": "No profiles yet", - "走一遍安装引导,它会保存 Provider、模型和 API mode。": "Run the install guide; it saves the provider, model, and API mode.", + "走一遍安装引导,它会保存 Provider、模型和 API mode": "Run the install guide; it saves the provider, model, and API mode", "Provider 已有 Key": "Provider key saved", "Provider 缺少 Key": "Provider key missing", "未指定模型": "No model specified", diff --git a/frontend/src/pages/ActivationPage.tsx b/frontend/src/pages/ActivationPage.tsx index 26e725d..10bc2bb 100644 --- a/frontend/src/pages/ActivationPage.tsx +++ b/frontend/src/pages/ActivationPage.tsx @@ -8,8 +8,8 @@ import { DownloadProgress } from "../components/DownloadProgress"; import { LogDisclosure } from "../components/LogDisclosure"; import { PageScaffold } from "../components/PageScaffold"; import { useI18n } from "../i18n"; -import { taskCanceller, taskKey, type TaskCanceller, useTaskCenter, useTaskRoute } from "../state/TaskCenterContext"; import { desktopProtocol, profileAgentIdForDesktop, selectedDesktopApp } from "../state/desktopSetup"; +import { taskCanceller, taskKey, useTaskCenter, useTaskRoute, type TaskCanceller } from "../state/TaskCenterContext"; import { useWizard } from "../state/WizardContext"; import type { AgentInstallResult, InstallRequest } from "../types/api"; @@ -263,7 +263,7 @@ export function ActivationPage() { return ( navigate("/overview")} footerNote={loading ? t("请保持此窗口打开") : undefined} @@ -288,7 +288,7 @@ export function ActivationPage() { return ( navigate("/setup/review")} primaryLabel={allDone ? t("进入总览") : undefined} diff --git a/frontend/src/pages/AgentProfilePage.tsx b/frontend/src/pages/AgentProfilePage.tsx index 059b140..ce805a0 100644 --- a/frontend/src/pages/AgentProfilePage.tsx +++ b/frontend/src/pages/AgentProfilePage.tsx @@ -7,9 +7,9 @@ import { PageScaffold } from "../components/PageScaffold"; import { ProviderSegment } from "../components/ProviderSegment"; import { useI18n } from "../i18n"; import { desktopApps, desktopProfileUsable, desktopProfiles, desktopProtocol, profileAgentIdForDesktop } from "../state/desktopSetup"; -import { useWizard } from "../state/WizardContext"; import { byProfileCreatedAt, byProviderCreatedAt } from "../state/ranking"; -import type { ProfileSummary, ProviderId, ProtocolId } from "../types/api"; +import { useWizard } from "../state/WizardContext"; +import type { ProfileSummary, ProtocolId, ProviderId } from "../types/api"; interface ProfileDraft { id: string; @@ -166,7 +166,7 @@ export function AgentProfilePage() { return ( navigate("/overview")} primaryLabel={busy ? t("应用中") : t("应用")} @@ -216,9 +216,9 @@ export function AgentProfilePage() {

{status.providers[draft.provider]?.has_key - ? t("将使用 Provider 已保存的 Key。") + ? t("将使用 Provider 已保存的 Key") : <> - {t("这个 Provider 还没有 Key,请先到 Provider 页面填写。")} {" "} + {t("这个 Provider 还没有 Key,请先到 Provider 页面填写")} {" "} }

@@ -251,7 +251,7 @@ export function AgentProfilePage() { ) : (
{t("还没有可用的 Profile")} - {t("创建一个 Profile 后即可应用到这个 Agent。")} + {t("创建一个 Profile 后即可应用到这个 Agent")}
)}
diff --git a/frontend/src/pages/AgentSelectionPage.tsx b/frontend/src/pages/AgentSelectionPage.tsx index 51da82a..355ab2f 100644 --- a/frontend/src/pages/AgentSelectionPage.tsx +++ b/frontend/src/pages/AgentSelectionPage.tsx @@ -8,8 +8,8 @@ import { PageScaffold } from "../components/PageScaffold"; import { RuntimePrompt } from "../components/RuntimePrompt"; import { useI18n } from "../i18n"; import { byRank } from "../state/ranking"; -import type { AgentCatalogItem } from "../types/api"; import { useWizard } from "../state/WizardContext"; +import type { AgentCatalogItem } from "../types/api"; import { DesktopAgentSelectionPage } from "./DesktopAgentSelectionPage"; export function AgentSelectionPage() { @@ -52,7 +52,7 @@ export function AgentSelectionPage() { return (

{t("选择 Agent")}

-

{t("选择这次要安装并配置的开发工具,每次安装一个。")}

+

{t("选择这次要安装并配置的开发工具,每次安装一个")}

{/* Guide-only rows stay selectable: install_many answers them with a guide-only result and writes nothing. */}
diff --git a/frontend/src/pages/DesktopAgentSelectionPage.tsx b/frontend/src/pages/DesktopAgentSelectionPage.tsx index f06cd22..7efcacc 100644 --- a/frontend/src/pages/DesktopAgentSelectionPage.tsx +++ b/frontend/src/pages/DesktopAgentSelectionPage.tsx @@ -37,7 +37,7 @@ export function DesktopAgentSelectionPage() { return (

{t("桌面 Agent")}

-

{t("安装应用后,会把选定的 Profile 应用到对应的配置。")}

+

{t("安装应用后,会把选定的 Profile 应用到对应的配置")}