From 9a79ca4f3edc6f55e37a3998975d91bcbd8efd34 Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Thu, 23 Apr 2026 17:46:30 +0200 Subject: [PATCH 01/13] Update README.en.md to latest README.md. --- README.en.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/README.en.md b/README.en.md index 5564d142..b12eca0c 100644 --- a/README.en.md +++ b/README.en.md @@ -165,6 +165,10 @@ LS_PORT=42100 DASHBOARD_PASSWORD= EOF +# Note: Inline comments are supported in .env for unquoted values: +# PORT=3003 # Service port +# Quoted values preserve everything inside the quotes. + node src/index.js ``` @@ -181,16 +185,16 @@ Open `http://YOUR_IP:3003/dashboard` → Login to get token → Click **Sign in Go to [windsurf.com/show-auth-token](https://windsurf.com/show-auth-token) to copy your token: ```bash -curl -X POST http://localhost:3003/auth/login - -H "Content-Type: application/json" +curl -X POST http://localhost:3003/auth/login + -H "Content-Type: application/json" -d '{"token": "YOUR_TOKEN"}' ``` **Method 3: Batch** ```bash -curl -X POST http://localhost:3003/auth/login - -H "Content-Type: application/json" +curl -X POST http://localhost:3003/auth/login + -H "Content-Type: application/json" -d '{"accounts": [{"token": "t1"}, {"token": "t2"}]}' ``` @@ -218,9 +222,9 @@ claude # Use Claude Code as usual ```bash # Raw curl test -curl http://localhost:3003/v1/messages - -H "Authorization: Bearer YOUR_KEY" - -H "anthropic-version: 2023-06-01" +curl http://localhost:3003/v1/messages + -H "Authorization: Bearer YOUR_KEY" + -H "anthropic-version: 2023-06-01" -d '{"model":"claude-opus-4.6","max_tokens":100,"messages":[{"role":"user","content":"Hello"}]}' ``` @@ -250,12 +254,21 @@ In your client's settings for **Custom OpenAI Compatible**: | `PORT` | `3003` | Service port | | `API_KEY` | empty | API key required for requests. Leave empty to disable validation. | | `DATA_DIR` | project root | Directory for persisted JSON state and `logs/`. Docker deployments should usually use `/data`. | +| `CODEIUM_API_KEY` | empty | Direct API key from Windsurf (alternative to token-based auth). | +| `CODEIUM_AUTH_TOKEN` | empty | Token from [windsurf.com/show-auth-token](https://windsurf.com/show-auth-token). | +| `CODEIUM_EMAIL` | empty | Email for Windsurf account authentication. | +| `CODEIUM_PASSWORD` | empty | Password for Windsurf account authentication. | +| `CODEIUM_API_URL` | `https://server.self-serve.windsurf.com` | Windsurf cloud API endpoint. | | `DEFAULT_MODEL` | `claude-4.5-sonnet-thinking` | The model to use if `model` is not specified. | | `MAX_TOKENS` | `8192` | Default maximum number of response tokens. | | `LOG_LEVEL` | `info` | debug / info / warn / error | | `LS_BINARY_PATH` | `/opt/windsurf/language_server_linux_x64` | Path to the LS binary. | | `LS_PORT` | `42100` | LS gRPC port. | +| `LS_DATA_DIR` | `/opt/windsurf` | Per-proxy LS data directory root. | | `DASHBOARD_PASSWORD` | empty | Dashboard password. Leave empty for no password. | +| `CASCADE_REUSE_STRICT` | `0` | Set to `1` for strict conversation reuse mode (waits for same fingerprint). | +| `CASCADE_REUSE_STRICT_RETRY_MS` | `60000` | Retry delay in ms for strict reuse mode. | +| `CASCADE_REUSE_HASH_SYSTEM` | `0` | Set to `1` to include system messages in conversation reuse hash. | ## Dashboard Features @@ -306,6 +319,10 @@ deepseek-v3 / v3-2 / r1 · grok-3 / mini / mini-thinking / code-fast-1 · qwen-3 > **Free accounts** can only use `gpt-4o-mini` and `gemini-2.5-flash`. Others require Windsurf Pro. +### Language-Following for CJK Users + +The service automatically detects Chinese, Japanese, or Korean characters in your messages and injects a language-following hint to ensure the model responds in the same language. This fixes the issue where Claude Code's large English system prompt would override the communication language. + ## Architecture Highlights - **Zero npm dependencies** Everything uses `node:*` built-ins · Protobuf is handcrafted (`src/proto.js`) · Download and run. From 6853d7f8630f6c2e033487e6196ae06568168ac9 Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Thu, 23 Apr 2026 17:49:09 +0200 Subject: [PATCH 02/13] docs: replace ASCII diagrams with Mermaid flowchart and sequence diagram --- README.en.md | 78 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/README.en.md b/README.en.md index b12eca0c..d540fabd 100644 --- a/README.en.md +++ b/README.en.md @@ -25,21 +25,26 @@ Turns [Windsurf](https://windsurf.com) (formerly Codeium)'s AI models into **two ## What is it doing? -``` - ┌─────────────┐ /v1/chat/completions ┌────────────┐ - │ OpenAI SDK │ ──────────────────────→ │ │ - │ curl / Frontend │ ←────────────────────── │ │ - └─────────────┘ OpenAI JSON + SSE │ WindsurfAPI│ - │ Node.js │ ┌──────────────┐ ┌─────────────────┐ - ┌─────────────┐ /v1/messages │ (This Service) │ gRPC │ Language │ HTTPS │ Windsurf Cloud │ - │ Claude Code │ ──────────────────────→ │ │ ───→ │ Server (LS) │ ────→ │ server.self- │ - │ Cline │ ←────────────────────── │ │ ←─── │ (Windsurf │ ←─── │ serve.windsurf │ - │ Cursor │ Anthropic SSE │ │ │ binary) │ │ .com │ - └─────────────┘ └────────────┘ └──────────────┘ └─────────────────┘ - ↑ - Account Pool Round-Robin - Rate Limit Isolation - Failover +```mermaid +flowchart LR + subgraph Clients + A[OpenAI SDK
curl / Frontend] + B[Claude Code
Cline
Cursor] + end + + subgraph WindsurfAPI["WindsurfAPI (Node.js)"] + C[HTTP Service
Port 3003] + D[Account Pool
Round-Robin
Rate Limit
Failover] + end + + E[Language Server
(Windsurf binary)] + F[Windsurf Cloud
server.self-serve.windsurf.com] + + A -->|"/v1/chat/completions"
OpenAI JSON + SSE| C + B -->|"/v1/messages"
Anthropic SSE| C + C <-->|gRPC| E + E <-->|HTTPS| F + D -.-> C ``` **What it does**: @@ -52,29 +57,26 @@ Turns [Windsurf](https://windsurf.com) (formerly Codeium)'s AI models into **two The model itself does **not** operate on files — file operations are executed locally by the IDE Agent client (Claude Code, Cline, etc.): -``` - You "Help me fix a bug" Claude Code WindsurfAPI Windsurf Cloud - │ │ │ │ - │────────────────────────────→ │ │ │ - │ │ POST /v1/messages │ │ - │ │ messages + tools + system │ │ - │ │ ─────────────────────────────→│ Package into Cascade request │ - │ │ │ ──────────────────────→ │ - │ │ │ │ - │ │ │ Model thinks → returns - │ │ │ tool_use(edit_file) - │ │ │ ←────────────────────── │ - │ │ ←── Anthropic SSE ────────────│ │ - │ │ content_block=tool_use │ │ - │ │ │ │ - │ │ Execute edit_file() locally │ │ - │ │ (Read/write local files) │ │ - │ │ │ │ - │ │ Send another turn with tool_result │ │ - │ │ ─────────────────────────────→│ ──────────────────────→ │ - │ │ ... (loop) ... - │ │ │ │ - │ ← Final answer │ │ │ +```mermaid +sequenceDiagram + actor U as You + participant CC as Claude Code + participant WA as WindsurfAPI + participant WC as Windsurf Cloud + + U->>CC: "Help me fix a bug" + CC->>WA: POST /v1/messages
messages + tools + system + WA->>WC: Package into Cascade request + WC-->>WA: Model thinks → returns
tool_use(edit_file) + WA-->>CC: Anthropic SSE
content_block=tool_use + CC->>CC: Execute edit_file() locally
(Read/write local files) + CC->>WA: Send tool_result + WA->>WC: Continue conversation... + loop Conversation Loop + WC-->>WA: Response + WA-->>CC: SSE stream + end + CC-->>U: Final answer ``` **Key Point**: WindsurfAPI is only responsible for **passing** `tool_use` / `tool_result`. The client CLI is what actually modifies the files. From 3343dc7e6bf864ce72acdc6e627af95893256d32 Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Thu, 23 Apr 2026 17:53:06 +0200 Subject: [PATCH 03/13] docs: replace `
` with `
` in Mermaid diagrams for consistency --- README.en.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.en.md b/README.en.md index d540fabd..c8a201bb 100644 --- a/README.en.md +++ b/README.en.md @@ -28,20 +28,20 @@ Turns [Windsurf](https://windsurf.com) (formerly Codeium)'s AI models into **two ```mermaid flowchart LR subgraph Clients - A[OpenAI SDK
curl / Frontend] - B[Claude Code
Cline
Cursor] + A[OpenAI SDK
curl / Frontend] + B[Claude Code
Cline
Cursor] end subgraph WindsurfAPI["WindsurfAPI (Node.js)"] - C[HTTP Service
Port 3003] - D[Account Pool
Round-Robin
Rate Limit
Failover] + C[HTTP Service
Port 3003] + D[Account Pool
Round-Robin
Rate Limit
Failover] end - E[Language Server
(Windsurf binary)] - F[Windsurf Cloud
server.self-serve.windsurf.com] + E[Language Server
(Windsurf binary)] + F[Windsurf Cloud
server.self-serve.windsurf.com] - A -->|"/v1/chat/completions"
OpenAI JSON + SSE| C - B -->|"/v1/messages"
Anthropic SSE| C + A -->|"/v1/chat/completions"
OpenAI JSON + SSE| C + B -->|"/v1/messages"
Anthropic SSE| C C <-->|gRPC| E E <-->|HTTPS| F D -.-> C @@ -65,11 +65,11 @@ sequenceDiagram participant WC as Windsurf Cloud U->>CC: "Help me fix a bug" - CC->>WA: POST /v1/messages
messages + tools + system + CC->>WA: POST /v1/messages
messages + tools + system WA->>WC: Package into Cascade request - WC-->>WA: Model thinks → returns
tool_use(edit_file) - WA-->>CC: Anthropic SSE
content_block=tool_use - CC->>CC: Execute edit_file() locally
(Read/write local files) + WC-->>WA: Model thinks → returns
tool_use(edit_file) + WA-->>CC: Anthropic SSE
content_block=tool_use + CC->>CC: Execute edit_file() locally
(Read/write local files) CC->>WA: Send tool_result WA->>WC: Continue conversation... loop Conversation Loop From 675e98ce1a49a0eef6f85c56d7ab005ad395d55b Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Thu, 23 Apr 2026 17:56:10 +0200 Subject: [PATCH 04/13] docs: quote Language Server node label in Mermaid flowchart for syntax consistency --- README.en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.en.md b/README.en.md index c8a201bb..620a56b4 100644 --- a/README.en.md +++ b/README.en.md @@ -37,7 +37,7 @@ flowchart LR D[Account Pool
Round-Robin
Rate Limit
Failover] end - E[Language Server
(Windsurf binary)] + E["Language Server
(Windsurf binary)"] F[Windsurf Cloud
server.self-serve.windsurf.com] A -->|"/v1/chat/completions"
OpenAI JSON + SSE| C From 97bc4e026078a7ae37a5aaa3da11411d3a4acb79 Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Thu, 23 Apr 2026 19:13:03 +0200 Subject: [PATCH 05/13] feat: add English (en) i18n translation for dashboard UI --- src/dashboard/i18n/en.json | 632 +++++++++++++++++++++++++++++++++ src/dashboard/i18n/zh-CN.json | 651 ++++++++++++++++++++++++++++++++++ src/dashboard/index.html | 504 +++++++++++++++----------- src/server.js | 17 + 4 files changed, 1589 insertions(+), 215 deletions(-) create mode 100644 src/dashboard/i18n/en.json create mode 100644 src/dashboard/i18n/zh-CN.json diff --git a/src/dashboard/i18n/en.json b/src/dashboard/i18n/en.json new file mode 100644 index 00000000..b7d68d89 --- /dev/null +++ b/src/dashboard/i18n/en.json @@ -0,0 +1,632 @@ +{ + "_meta": { + "name": "English", + "code": "en" + }, + + "brand": { + "sub": "Control Panel" + }, + + "nav": { + "group": { + "overview": "Overview", + "account": "Accounts", + "system": "System", + "about": "About" + }, + "overview": "Dashboard", + "stats": "Statistics", + "windsurf-login": "Account Login", + "accounts": "Account Pool", + "bans": "Health Check", + "models": "Model Control", + "proxy": "Proxy", + "logs": "Logs", + "experimental": "Experimental", + "credits": "Credits" + }, + + "page": { + "overview": "Dashboard", + "stats": "Statistics", + "windsurf-login": "Account Login", + "accounts": "Account Pool", + "bans": "Health Check", + "models": "Model Control", + "proxy": "Proxy Config", + "logs": "Runtime Logs", + "experimental": "Experimental Features", + "credits": "Credits" + }, + + "pageTitle": { + "main": "WindsurfAPI bydwgx1337 Control Panel" + }, + + "pageSubtitle": { + "overview": "System status and key metrics overview", + "windsurf-login": "Login to Windsurf via Google / GitHub / Email to get API Key", + "accounts": "Manage account pool, probe subscription tiers and available models", + "models": "Configure model access policies, limit available model scope", + "proxy": "Configure global or per-account exit proxies; each dedicated proxy spawns an independent Language Server instance", + "logs": "Receive server logs in real-time via SSE streaming", + "stats": "Request volume, success rate, latency percentiles and account/model dimension stats", + "bans": "Track error accounts and abnormal status", + "experimental": "Unstable optimizations; disable anytime if issues occur", + "credits": "Thanks to contributors who submitted PRs / audited code / reported issues" + }, + + "button": { + "cancel": "Cancel", + "confirm": "Confirm", + "forceOverride": "Force Overwrite & Update" + }, + + "action": { + "checkUpdate": "Check Update", + "applyUpdate": "Update & Restart", + "restart": "Restart", + "login": "Login", + "save": "Save", + "clear": "Clear", + "cancel": "Cancel", + "confirm": "Confirm", + "delete": "Delete", + "reset": "Reset", + "refresh": "Refresh", + "probe": "Probe", + "enable": "Enable", + "disable": "Disable", + "copy": "Copy", + "configure": "Configure", + "test": "Test", + "readClipboard": "Read Clipboard", + "batchImport": "Batch Import & Login", + "paste": "Paste", + "add": "Add", + "close": "Close", + "edit": "Edit", + "selectAll": "Select All", + "selectNone": "Select None", + "invert": "Invert", + "showPassword": "Show/Hide Password" + }, + + "status": { + "active": "Active", + "disabled": "Disabled", + "error": "Error", + "running": "Running", + "stopped": "Stopped", + "success": "Success", + "failed": "Failed", + "pending": "Pending", + "unknown": "Unknown", + "rateLimited": "Rate Limited", + "loading": "Loading...", + "testing": "Testing...", + "proxySuccess": "✓ Connected. Egress IP {{ip}} · {{latency}}ms", + "proxyFailed": "✗ Failed: {{error}} · {{latency}}ms", + "checkingUpdate": "Checking for updates...", + "updateAvailable": "Update available", + "currentVersion": "Current:", + "remoteVersion": "Remote:", + "upToDate": "✓ Up to date ({{commit}}) · {{message}}", + "pullingRestarting": "Pulling + restarting...", + "cancelled": "Cancelled", + "noUpdateNeeded": "Already up to date, no update needed", + "updateComplete": "Update complete {{before}} → {{after}}", + "restarting": "Service restarting in background, page will auto-refresh in ~8 seconds...", + "notGitRepo": "Not a git repository", + "notGitRepoHint": "Ensure .git directory is present for one-click updates", + "workingDirDirty": "Working directory has local changes", + "workingDirDirtyHint": "The following files have local changes:
{{files}}
Continue will overwrite with remote version." + }, + + "tier": { + "pro": "PRO", + "free": "FREE", + "expired": "Expired", + "unknown": "Unknown" + }, + + "section": { + "lsStatus": { + "title": "Language Server", + "desc": "Language Server instance status" + }, + "oauthLogin": { + "title": "Quick Login (Recommended)", + "desc": "Login to Windsurf directly with your Google or GitHub account — no password needed" + }, + "emailLogin": { + "title": "Email & Password Login", + "desc": "For accounts registered with email+password only. Third-party login please use buttons above. Supports single login or batch import in \"[proxy] email password\" format." + }, + "loginProxy": { + "title": "Login Proxy (Optional)", + "desc": "Specify a proxy for this login session; leave empty to use global proxy. When proxy takes effect, subsequent chat requests will also egress through this proxy." + }, + "loginHistory": { + "title": "Login History", + "desc": "Local record of last 50 login operations" + }, + "addAccount": { + "title": "Add Account", + "desc": "Supports both API Key and Auth Token methods" + }, + "accountList": { + "title": "Account List", + "desc": "Click probe button to update capability info for a specific account" + }, + "modelPolicy": { + "title": "Access Policy", + "desc": "Choose \"Allow All\" for no restrictions; \"Allowlist\" only permits listed models; \"Blocklist\" blocks listed models" + }, + "modelList": { + "title": "Model List", + "titleAllow": "Allowed Models", + "titleBlock": "Blocked Models", + "descAllow": "Only selected models are allowed; unselected models return 403 error", + "descBlock": "Selected models will be blocked; unselected models work normally", + "search": "Search models...", + "provider": "Provider" + }, + "globalProxy": { + "title": "Global Proxy", + "desc": "Accounts without dedicated proxy will use this configuration" + }, + "accountProxy": { + "title": "Per-Account Proxy", + "desc": "Set dedicated proxy for specific accounts; each dedicated proxy spawns an independent LS instance" + }, + "identityInjection": { + "title": "Model Identity Injection", + "desc": "When enabled, injects a system prompt at the start of each request, overriding Cascade's built-in Windsurf identity; each provider's template below can be customized and takes effect immediately after saving." + }, + "systemPrompts": { + "title": "System Prompts", + "desc": "Tool injection, conversation mode and other built-in prompt templates. Changes take effect immediately; click \"Reset\" to restore defaults." + }, + "lsPool": { + "title": "Language Server Pool", + "desc": "{{count}} LS instances · one process per dedicated proxy" + }, + "modelStats": { + "title": "Model Usage Statistics", + "desc": "Aggregated by model: requests, success count, error count, success rate, avg duration and p50/p95 latency percentiles" + }, + "accountStats": { + "title": "Account Dimension Statistics", + "desc": "Request volume and success rate per account ID (first 8 chars)" + }, + "accountHealth": { + "title": "Account Health Status" + }, + "requestChart": { + "title": "Request Volume Time Series" + } + }, + + "help": { + "token": "Recommended: Use Token method. Visit {{link}} after logging in, copy the Token and paste below. Works with all login methods (Email/Google/GitHub).", + "tokenGuide": "Recommended: Use Token method. Visit ", + "tokenGuideEnd": " after logging in, copy the Token and paste below. Works with all login methods (Email/Google/GitHub)." + }, + + "field": { + "email": { + "label": "Email", + "placeholder": "your-email@example.com" + }, + "password": { + "label": "Password", + "placeholder": "••••••••" + }, + "type": { + "label": "Type" + }, + "provider": { + "label": "Provider", + "all": "All Providers" + }, + "searchModel": { + "label": "Search Model", + "placeholder": "Enter model name to filter..." + }, + "proxyUser": { + "placeholder": "Proxy auth username" + }, + "proxyPass": { + "placeholder": "Proxy auth password" + }, + "searchProvider": { + "placeholder": "Search providers..." + }, + "host": { + "label": "Host", + "placeholder": "proxy.example.com" + }, + "port": { + "label": "Port", + "placeholder": "8080" + }, + "username": { + "label": "Username", + "placeholder": "Optional" + }, + "passwordProxy": { + "label": "Password", + "placeholder": "Optional" + }, + "key": { + "label": "Key / Token", + "placeholder": "Paste Auth Token (from windsurf.com/show-auth-token)" + }, + "label": { + "label": "Label", + "placeholder": "Optional" + }, + "batchInput": { + "label": "Batch Import", + "hint": "One account per line. Format: [proxy] email password. Proxy is optional, supports http/socks5. Proxy will be automatically bound to corresponding account." + }, + "proxyType": { + "label": "Type" + }, + "proxyHost": { + "label": "Host", + "placeholder": "Leave empty = use global" + }, + "providerFilter": { + "label": "Provider" + }, + "logLevel": { + "label": "Log Level" + }, + "autoScroll": "Auto-scroll", + "autoAdd": "Auto-add to pool after login" + }, + + "table": { + "header": { + "time": "Time", + "email": "Email", + "status": "Status", + "proxy": "Proxy", + "action": "Action", + "id": "ID", + "label": "Label", + "tier": "Tier", + "rpm": "RPM", + "credits": "Credits", + "models": "Available Models", + "error": "Error", + "lastUsed": "Last Used", + "key": "Key", + "account": "Account", + "requests": "Requests", + "success": "Success", + "errors": "Errors", + "successRate": "Success Rate", + "avg": "Avg", + "p50": "p50", + "p95": "p95", + "errorCount": "Error Count", + "model": "Model" + }, + "empty": { + "loginHistory": "No login records", + "accounts": "No accounts yet, please add one first", + "accountsProxy": "No accounts", + "modelStats": "No model statistics available", + "accountStats": "No account statistics available", + "banList": "No abnormal accounts", + "models": "No matching models", + "credits": "Loading..." + } + }, + + "card": { + "activeAccounts": { + "title": "Active Accounts", + "subtitle": "{{total}} total · {{error}} abnormal" + }, + "totalRequests": { + "title": "Total Requests", + "subtitle": "{{rate}}% success rate" + }, + "uptime": { + "title": "Uptime", + "subtitle": "Started at {{time}}" + }, + "languageServer": { + "title": "Language Server", + "running": "Running", + "stopped": "Stopped", + "subtitle": "{{count}} instances · Port {{port}}" + }, + "responseCache": { + "title": "Response Cache", + "subtitle": "{{hits}} hit / {{misses}} miss · {{size}}/{{max}} entries" + }, + "banStats": { + "title": "Health Overview" + } + }, + + "login": { + "title": "Control Panel Login", + "subtitle": "Please enter the admin password to continue", + "passwordPlaceholder": "Dashboard Password", + "button": "Login" + }, + + "range": { + "6h": "Last 6h", + "24h": "Last 24h", + "72h": "Last 72h" + }, + + "credits": { + "contributors": "Core Contributors", + "cta": "Want to join this list?", + "ctaDesc": "Open an issue or pull request on GitHub — bug fixes, new models, UI improvements, or security findings all get recognised here.", + "openIssue": "Open Issue", + "openPR": "Open PR" + }, + + "experimental": { + "enable": "Enable", + "disable": "Disable", + "cascadeReuse": { + "title": "Enable Cascade Conversation Reuse", + "desc": "Disabled by default. When enabled, takes effect immediately on current conversation pool." + }, + "identityPrompt": { + "title": "Enable Model Identity Injection", + "desc": "Enabled by default; templates below won't work when disabled." + }, + "templateHint": "Each provider's template is editable. {{model}} placeholder will be replaced with the requested model name (e.g., claude-opus-4.6).", + "clearPool": "Clear Conversation Pool", + "refresh": "Refresh" + }, + + "modal": { + "blockedModels": { + "title": "Edit Available Models — {{email}}", + "hint": "Checked = available; Uncheck = disabled for this account", + "enabled": "Enabled", + "saving": "Saving...", + "total": "Total" + }, + "restartLS": { + "title": "Restart Language Server", + "desc": "In-progress requests will fail. Continue?" + }, + "deleteAccount": { + "title": "Delete Account", + "desc": "This action cannot be undone. Delete this account?" + }, + "resetStats": { + "title": "Reset Statistics", + "desc": "Clear all statistics data?" + }, + "overrideTier": { + "title": "Manually Set Account Tier", + "desc": "Current: {{current}}. Windsurf Pro trial sometimes fails auto-detection (issue #8 side effect), manually change to pro to unlock all Pro models.", + "options": { + "pro": "Pro (unlock all models)", + "free": "Free (gpt-4o-mini and gemini-2.5-flash only)", + "unknown": "Unknown (let system re-evaluate)" + } + }, + "applyUpdate": { + "title": "Update & Restart", + "desc": "Will execute git pull and restart PM2. Dashboard will be briefly unavailable during restart (about 5-10 seconds). Continue?" + }, + "dirtyWorktree": { + "title": "Local Changes in Working Directory", + "desc": "The following files have been modified but not committed:

{{files}}
Continuing will overwrite local changes with remote version. For non-git deployments (SFTP / zip), click force overwrite.", + "forceUpdate": "Force Overwrite & Update" + }, + "configureProxy": { + "title": "Configure Account Proxy", + "desc": "Set dedicated proxy for account {{label}}" + } + }, + + "oauth": { + "google": "Google Login", + "github": "GitHub Login", + "status": { + "loading": "Logging in via {{provider}}...", + "success": "Login successful! {{email}} added to pool", + "codeium": "{{provider}} auth successful, registering with Codeium...", + "firebaseError": "Firebase SDK failed to load, please refresh and retry" + } + }, + + "update": { + "checking": "Checking for updates...", + "newVersion": "New version found", + "current": "Current", + "remote": "Remote", + "latest": "Already up to date", + "applying": "Pulling + restarting...", + "complete": "Update complete", + "restarting": "Service restarting in background, page will auto-refresh in ~8 seconds...", + "cancelled": "Cancelled", + "notGit": "Not a git deployment — one-click update unavailable", + "notGitDesc": "If you deployed via git clone, ensure .git directory is with WindsurfAPI source. For SFTP / zip uploads, manually replace files and pm2 restart.", + "upToDate": "Already up to date, no update needed" + }, + + "proxy": { + "test": { + "button": "Test Proxy", + "result": "Result" + }, + "none": "None (use global)", + "direct": "Direct", + "global": "Global", + "current": "Current", + "notConfigured": "No global proxy configured", + "placeholderSaved": "Saved (leave empty to keep)", + "placeholderPassword": "Proxy auth password" + }, + + "account": { + "addSuccess": "Account added", + "deleteSuccess": "Account deleted", + "enableSuccess": "Account enabled", + "disableSuccess": "Account disabled", + "resetErrors": "Errors reset", + "tierSet": "Tier set to {{tier}}", + "probe": { + "doing": "Probing, takes about 10-30 seconds...", + "complete": "Probe complete: {{result}}", + "allDoing": "Probing all accounts, takes 1-3 minutes depending on count...", + "allComplete": "Probe complete: {{summary}}" + }, + "credits": { + "refreshed": "Credits refreshed", + "refreshFailed": "Refresh failed", + "allRefreshed": "All account credits refreshed: {{ok}} success / {{fail}} failed", + "refreshing": "Refreshing all account credits..." + }, + "ls": { + "restarting": "Language Server restarting..." + } + }, + + "batch": { + "importing": "Importing...", + "importingDesc": "{{count}} lines, please wait", + "complete": "Batch import complete", + "success": "Success", + "fail": "Fail", + "formatError": "Line {{line}} format error" + }, + + "toast": { + "copied": "Copied", + "saved": "Saved", + "cleared": "Cleared", + "refresh": "Refresh", + "error": "Error", + "loading": "Loading...", + "enterHostPort": "Please enter host and port first", + "experimentalEnabled": "Experimental feature enabled", + "experimentalDisabled": "Experimental feature disabled", + "toggleFailed": "Toggle failed: {{error}}", + "loginSuccess": "{{label}} login successful", + "loginFailed": "{{label}} login failed: {{error}}", + "loginSuccessAdded": "Login successful, account added to pool", + "clipboardRead": "Clipboard read", + "clipboardEmpty": "Clipboard is empty", + "clipboardUnsupported": "Current environment doesn't support auto clipboard read, please paste manually", + "clipboardError": "Failed to read clipboard: {{error}}", + "enterEmailPassword": "Please enter email and password", + "restarting": "Language Server restarting..." + }, + + "log": { + "level": { + "all": "All Levels", + "debug": "Debug", + "info": "Info", + "warn": "Warn", + "error": "Error" + }, + "searchPlaceholder": "Search log content...", + "clearView": "Clear View", + "viaSSE": "via SSE real-time streaming" + }, + + "model": { + "mode": { + "all": "Allow All", + "allowlist": "Allowlist", + "blocklist": "Blocklist" + }, + "provider": { + "all": "All Providers", + "anthropic": "Anthropic", + "openai": "OpenAI", + "google": "Google", + "deepseek": "DeepSeek", + "xai": "xAI", + "alibaba": "Alibaba", + "moonshot": "Moonshot", + "windsurf": "Windsurf" + }, + "list": { + "current": "Current List ({{count}})", + "empty": "List is empty" + } + }, + + "error": { + "generic": "An error occurred", + "unknown": "Unknown error", + "updateFailed": "Update failed", + "apiError": "API error", + "loadFailed": "Failed to load", + "saveFailed": "Save failed", + "deleteFailed": "Delete failed", + "networkError": "Network error", + "authRequired": "Please login first", + "clipboardNotSupported": "Current environment doesn't support clipboard auto-read, please paste manually", + "clipboardEmpty": "Clipboard is empty", + "clipboardReadFailed": "Failed to read clipboard" + }, + + "footer": { + "version": "Version", + "langToggle": "Switch language" + }, + + "placeholder": { + "noProxy": "No proxy" + }, + + "loginResult": { + "success": "✓ Login Successful", + "apiKeyGenerated": "API Key generated{{autoAdd}}", + "fail": "✗ Login Failed", + "batchComplete": "Batch Import Complete", + "batchDesc": "Total {{total}} accounts, {{success}} success, {{fail}} fail{{autoAdd}}", + "tryOther": "Try Another Way", + "oauthHint": "If Google/GitHub OAuth was used to register, password login won't work. Use the Google/GitHub buttons above, or visit {{link}} to copy Auth Token then manually add in Account Pool page.", + "fields": { + "email": "Email", + "name": "Name", + "apiKey": "API Key", + "accountId": "Account ID" + } + }, + + "timeRange": { + "minutesAgo": "{{count}}m ago", + "hoursAgo": "{{count}}h ago", + "daysAgo": "{{count}}d ago" + }, + + "prompt": { + "editor": { + "reset": "Reset", + "search": "Search providers...", + "templateHint": "{{model}} placeholder will be replaced with the requested model name." + } + }, + + "ls": { + "defaultInstance": "Default Instance", + "noProxy": "No proxy", + "port": "Port", + "pid": "PID", + "restartCount": "Restarts" + } +} diff --git a/src/dashboard/i18n/zh-CN.json b/src/dashboard/i18n/zh-CN.json new file mode 100644 index 00000000..236a17ad --- /dev/null +++ b/src/dashboard/i18n/zh-CN.json @@ -0,0 +1,651 @@ +{ + "_meta": { + "name": "简体中文", + "code": "zh-CN" + }, + + "brand": { + "sub": "管理控制台" + }, + + "nav": { + "group": { + "overview": "概览", + "account": "账号", + "system": "系统", + "about": "关于" + }, + "overview": "仪表盘", + "stats": "统计分析", + "windsurf-login": "登录取号", + "accounts": "账号管理", + "bans": "异常监测", + "models": "模型控制", + "proxy": "代理配置", + "logs": "运行日志", + "experimental": "实验性功能", + "credits": "致谢" + }, + + "pageTitle": { + "main": "WindsurfAPI bydwgx1337 控制台" + }, + + "page": { + "overview": "仪表盘", + "stats": "统计分析", + "windsurf-login": "登录取号", + "accounts": "账号管理", + "bans": "异常监测", + "models": "模型控制", + "proxy": "代理配置", + "logs": "运行日志", + "experimental": "实验性功能", + "credits": "致谢" + }, + + "pageSubtitle": { + "overview": "系统运行状态与关键指标概览", + "windsurf-login": "支持 Google / GitHub / 邮箱密码 三种方式登录 Windsurf 获取 API Key", + "accounts": "维护账号池,探测各账号订阅层级与可用模型", + "models": "配置模型访问策略,限制可用模型范围", + "proxy": "全局或按账号配置出口代理,独立代理将启动独立的语言服务器实例", + "logs": "通过 SSE 实时流式接收服务端日志", + "stats": "请求量、成功率、延迟分位数与账号/模型维度统计", + "bans": "追踪错误账号和异常状态", + "experimental": "尚未稳定的优化项;如果发现异常可以随时关闭", + "credits": "感谢以下朋友为项目提交 PR / 审计代码 / 修复问题" + }, + + "button": { + "cancel": "取消", + "confirm": "确认", + "forceOverride": "强制覆盖并更新" + }, + + "action": { + "checkUpdate": "检查更新", + "applyUpdate": "一键更新并重启", + "restart": "重启", + "login": "登录", + "save": "保存", + "clear": "清除", + "cancel": "取消", + "confirm": "确认", + "delete": "删除", + "reset": "重置", + "refresh": "刷新", + "probe": "探测", + "enable": "启用", + "disable": "停用", + "copy": "复制", + "configure": "配置", + "test": "测试", + "readClipboard": "读取剪贴板", + "batchImport": "批量导入并登录", + "paste": "粘贴", + "add": "添加", + "close": "关闭", + "edit": "编辑", + "selectAll": "全选", + "selectNone": "全不选", + "invert": "反选", + "showPassword": "显示/隐藏密码" + }, + + "status": { + "active": "正常", + "disabled": "已禁用", + "error": "错误", + "running": "运行中", + "stopped": "已停止", + "success": "成功", + "failed": "失败", + "pending": "待处理", + "unknown": "未知", + "rateLimited": "限速中", + "loading": "加载中…", + "testing": "测试中…", + "proxySuccess": "✓ 连通成功 出口 IP {{ip}} · 耗时 {{latency}}ms", + "proxyFailed": "✗ 失败: {{error}} · {{latency}}ms", + "checkingUpdate": "正在检查更新…", + "updateAvailable": "发现新版本", + "currentVersion": "当前版本", + "remoteVersion": "远程版本", + "upToDate": "✓ 已是最新 ({{commit}}) · {{message}}", + "pullingRestarting": "正在拉取 + 重启…", + "cancelled": "已取消", + "noUpdateNeeded": "已是最新,无需更新", + "updateComplete": "更新完成 {{before}} → {{after}}", + "restarting": "服务正在后台重启 约 8 秒后自动刷新页面…", + "notGitRepo": "非 git 部署 — 一键更新不可用", + "notGitRepoHint": "如果你是通过 git clone 部署的,请确保 .git 目录随 WindsurfAPI 源码一起上传", + "workingDirDirty": "工作区有本地修改", + "workingDirDirtyHint": "以下文件已被修改但未提交:
{{files}}
继续将用远程版本覆盖这些修改。" + }, + + "tier": { + "pro": "PRO", + "free": "FREE", + "expired": "已过期", + "unknown": "未知" + }, + + "section": { + "lsStatus": { + "title": "Language Server", + "desc": "语言服务器实例状态" + }, + "oauthLogin": { + "title": "快捷登录(推荐)", + "desc": "用你的 Google 或 GitHub 账号直接登录 Windsurf 无需密码" + }, + "emailLogin": { + "title": "邮箱密码登录", + "desc": "仅限邮箱+密码注册的账号 第三方登录请用上面的按钮;支持单个登录或按「邮箱 密码」格式批量导入" + }, + "loginProxy": { + "title": "登录代理(可选)", + "desc": "为本次登录指定代理;留空则使用全局代理设置。代理生效后账号的后续聊天请求也会经此代理出站" + }, + "loginHistory": { + "title": "登录历史", + "desc": "本地记录最近 50 条登录操作" + }, + "addAccount": { + "title": "添加账号", + "desc": "支持 API Key 或 Auth Token 两种方式", + "hint": "推荐用 Token 方式添加账号 点 {{link}} 登录后复制 Token 粘贴到下面就行 所有登录方式(邮箱/Google/GitHub)都能用" + }, + "accountList": { + "title": "账号列表", + "desc": "点击探测按钮可单独更新某个账号的能力信息" + }, + "modelPolicy": { + "title": "访问策略", + "desc": "选择「全部允许」不限制;「白名单」只允许列出的模型;「黑名单」屏蔽列出的模型" + }, + "modelList": { + "title": "模型清单", + "titleAllow": "允许的模型", + "titleBlock": "屏蔽的模型", + "descAllow": "只有选中的模型可以使用,未选中的模型将返回 403 错误", + "descBlock": "选中的模型将被屏蔽,未选中的模型可正常使用", + "search": "搜索模型...", + "provider": "供应商" + }, + "globalProxy": { + "title": "全局代理", + "desc": "未配置独立代理的账号将使用此配置" + }, + "accountProxy": { + "title": "账号独立代理", + "desc": "为特定账号设置专属代理;每个独立代理会启动独立 LS 实例" + }, + "cascadeReuse": { + "title": "Cascade 对话复用", + "desc": "多轮对话时复用同一个 cascade_id,只把最新一条 user 消息发给 Windsurf,让服务端维持上下文缓存。命中时可显著降低 TTFB 与上传体积;未命中或账号/LS 变更会自动回退到新会话。需要客户端保留完整历史并按顺序追加(如 new-api、OpenWebUI)。", + "enable": "启用 Cascade 对话复用", + "hint": "默认关闭。开启后对当前对话池立即生效。" + }, + "identityPrompt": { + "enable": "启用模型身份注入", + "hint": "默认开启;关闭后下面的模板不起作用", + "templateHint": "每个厂商的模板可编辑,{{model}} 占位符会被替换成请求的模型名(例如 claude-opus-4.6)。" + }, + "identityInjection": { + "title": "模型身份注入", + "desc": "开启后在每个请求最前面注入一条系统提示词,覆盖 Cascade 自带的 Windsurf 身份;下面每个厂商的模板可自定义,保存后立即生效" + }, + "systemPrompts": { + "title": "系统提示词", + "desc": "工具注入、对话模式等内置提示词模板。修改后立即生效,点「重置」恢复默认。" + }, + "lsPool": { + "title": "语言服务器池", + "desc": "{{count}} 个 LS 实例 · 每个独立代理对应一个进程" + }, + "modelStats": { + "title": "模型使用统计", + "desc": "按模型聚合:请求量、成功率、平均耗时与 p50 / p95 延迟分位数" + }, + "accountStats": { + "title": "账号维度统计", + "desc": "每个账号 ID 前 8 位的请求量与成功率" + }, + "accountHealth": { + "title": "账号健康状况" + }, + "requestChart": { + "title": "请求量时间序列" + } + }, + + "help": { + "token": "推荐用 Token 方式添加账号 点 {{link}} 登录后复制 Token 粘贴到下面就行 所有登录方式(邮箱/Google/GitHub)都能用", + "tokenGuide": "推荐用 Token 方式添加账号 点 ", + "tokenGuideEnd": " 登录后复制 Token 粘贴到下面就行 所有登录方式(邮箱/Google/GitHub)都能用" + }, + + "field": { + "email": { + "label": "邮箱", + "placeholder": "your-email@example.com" + }, + "password": { + "label": "密码", + "placeholder": "••••••••" + }, + "type": { + "label": "类型" + }, + "host": { + "label": "主机", + "placeholder": "proxy.example.com" + }, + "port": { + "label": "端口", + "placeholder": "8080" + }, + "username": { + "label": "用户名", + "placeholder": "可选" + }, + "passwordProxy": { + "label": "密码", + "placeholder": "可选" + }, + "key": { + "label": "Key / Token", + "placeholder": "粘贴 Auth Token(从 windsurf.com/show-auth-token 获取)" + }, + "label": { + "label": "标签", + "placeholder": "可选" + }, + "batchInput": { + "label": "批量导入", + "hint": "每行一个账号。格式:[代理] 邮箱 密码。代理可选,支持 http/socks5。会自动绑定代理到对应账号。" + }, + "proxyType": { + "label": "类型" + }, + "proxyHost": { + "label": "主机", + "placeholder": "留空=使用全局" + }, + "provider": { + "label": "供应商", + "all": "全部供应商" + }, + "proxyUser": { + "placeholder": "代理认证用户名" + }, + "proxyPass": { + "placeholder": "代理认证密码" + }, + "searchProvider": { + "placeholder": "搜索提供商..." + }, + "search": { + "label": "搜索", + "placeholder": "搜索..." + }, + "searchModel": { + "label": "搜索模型", + "placeholder": "输入模型名称筛选..." + }, + "providerFilter": { + "label": "供应商" + }, + "logLevel": { + "label": "日志级别" + }, + "identitySearch": { + "placeholder": "搜索提供商..." + }, + "autoScroll": "自动滚动", + "autoAdd": "登录成功自动加入账号池" + }, + + "table": { + "header": { + "time": "时间", + "email": "邮箱", + "status": "状态", + "proxy": "代理", + "action": "操作", + "id": "ID", + "label": "标签", + "tier": "层级", + "rpm": "RPM", + "credits": "余额", + "models": "可用模型", + "error": "错误", + "lastUsed": "最后使用", + "key": "Key", + "account": "账号", + "requests": "请求", + "success": "成功", + "errors": "错误", + "successRate": "成功率", + "avg": "平均", + "p50": "p50", + "p95": "p95", + "errorCount": "错误数", + "model": "模型" + }, + "empty": { + "loginHistory": "暂无登录记录", + "accounts": "暂无账号,请先添加", + "accountsProxy": "暂无账号", + "modelStats": "暂无模型统计数据", + "accountStats": "暂无账号统计数据", + "banList": "暂无异常账号", + "models": "没有符合的模型", + "credits": "加载中…" + } + }, + + "card": { + "activeAccounts": { + "title": "活跃账号", + "subtitle": "{{total}} 个总账号 · {{error}} 异常" + }, + "totalRequests": { + "title": "总请求数", + "subtitle": "成功率 {{rate}}%" + }, + "uptime": { + "title": "运行时间", + "subtitle": "启动于 {{time}}" + }, + "languageServer": { + "title": "Language Server", + "running": "运行中", + "stopped": "已停止", + "subtitle": "{{count}} 个实例 · 端口 {{port}}" + }, + "responseCache": { + "title": "响应缓存", + "subtitle": "{{hits}} 命中 / {{misses}} 未命中 · {{size}}/{{max}} 条" + }, + "banStats": { + "title": "健康概览" + } + }, + + "login": { + "title": "控制台登录", + "subtitle": "请输入管理密码以继续", + "passwordPlaceholder": "Dashboard 密码", + "button": "登 录" + }, + + "range": { + "6h": "近 6h", + "24h": "近 24h", + "72h": "近 72h" + }, + + "credits": { + "contributors": "核心贡献者", + "cta": "想加入这份名单?", + "ctaDesc": "欢迎到 GitHub 提 issue 或 pull request — 不管是修 bug、加模型、改 UI 还是发现安全问题,都会被记录在这里。", + "openIssue": "提 issue", + "openPR": "提 PR" + }, + + "experimental": { + "enable": "启用", + "disable": "禁用", + "cascadeReuse": { + "title": "启用 Cascade 对话复用", + "desc": "默认关闭。开启后对当前对话池立即生效。" + }, + "identityPrompt": { + "title": "启用模型身份注入", + "desc": "默认开启;关闭后下面的模板不起作用。" + }, + "templateHint": "每个厂商的模板可编辑,{{model}} 占位符会被替换成请求的模型名(例如 claude-opus-4.6)。", + "clearPool": "清空对话池", + "refresh": "刷新" + }, + + "modal": { + "blockedModels": { + "title": "编辑可用模型 — {{email}}", + "hint": "勾选 = 可用;取消 = 对该账号禁用", + "enabled": "已启用", + "saving": "保存中...", + "total": "总计" + }, + "restartLS": { + "title": "重启 Language Server", + "desc": "进行中的请求将会失败,确定要继续吗?" + }, + "deleteAccount": { + "title": "删除账号", + "desc": "此操作不可撤销,确定要删除该账号吗?" + }, + "resetStats": { + "title": "重置统计", + "desc": "清空所有统计数据?" + }, + "overrideTier": { + "title": "手动设置账号层级", + "desc": "当前:{{current}}。Windsurf Pro 试用有时自动探测失败(issue #8 的连锁影响),手动改成 pro 即可解锁所有 Pro 模型。", + "options": { + "pro": "Pro(解锁所有模型)", + "free": "Free(仅 gpt-4o-mini 和 gemini-2.5-flash)", + "unknown": "Unknown(让系统重新判定)" + } + }, + "applyUpdate": { + "title": "一键更新并重启", + "desc": "将执行 git pull 并重启 PM2。重启期间 dashboard 会短暂不可用(约 5-10 秒)。确定继续?" + }, + "dirtyWorktree": { + "title": "工作区有本地修改", + "desc": "以下文件已被修改但未提交:

{{files}}
继续将用远程版本覆盖这些修改。非 git 部署(SFTP / 压缩包)请点强制覆盖。", + "forceUpdate": "强制覆盖并更新" + }, + "configureProxy": { + "title": "配置账号代理", + "desc": "为账号 {{label}} 设置独立代理" + } + }, + + "oauth": { + "google": "Google 登录", + "github": "GitHub 登录", + "status": { + "loading": "正在通过 {{provider}} 登录...", + "success": "登录成功 {{email}} 已加入账号池", + "codeium": "{{provider}} 认证成功 正在注册 Codeium...", + "firebaseError": "Firebase SDK 加载失败 请刷新页面重试" + } + }, + + "update": { + "checking": "正在检查更新...", + "newVersion": "发现新版本", + "current": "当前", + "remote": "远程", + "latest": "已是最新", + "applying": "正在拉取 + 重启...", + "complete": "更新完成", + "restarting": "服务正在后台重启 约 8 秒后自动刷新页面...", + "cancelled": "已取消", + "notGit": "此实例不是 git 部署 一键更新不可用", + "notGitDesc": "如果你用 git clone 部署的 需要确保 .git 目录和 WindsurfAPI 源代码目录在一起。SFTP / 压缩包上传的部署请手动替换文件后 pm2 重启", + "upToDate": "已是最新,无需更新" + }, + + "proxy": { + "test": { + "button": "测试代理", + "result": "结果" + }, + "none": "无(使用全局)", + "direct": "直连", + "global": "全局", + "current": "当前", + "notConfigured": "未配置全局代理", + "placeholderSaved": "已保存(留空保持原值)", + "placeholderPassword": "代理认证密码" + }, + + "account": { + "addSuccess": "账号已添加", + "deleteSuccess": "账号已删除", + "enableSuccess": "账号已启用", + "disableSuccess": "账号已停用", + "resetErrors": "错误已重置", + "tierSet": "层级已设为 {{tier}}", + "probe": { + "doing": "探测中,约需 10-30 秒...", + "complete": "探测完成:{{result}}", + "allDoing": "全部探测中,依账号数量约需 1-3 分钟...", + "allComplete": "探测完成:{{summary}}" + }, + "credits": { + "refreshed": "余额已刷新", + "refreshFailed": "刷新失败", + "allRefreshed": "余额刷新完成:{{ok}} 成功 / {{fail}} 失败", + "refreshing": "正在刷新所有账号余额..." + }, + "ls": { + "restarting": "Language Server 重启中..." + } + }, + + "batch": { + "importing": "批量导入中...", + "importingDesc": "共 {{count}} 行,请稍候", + "complete": "批量导入完成", + "success": "成功", + "fail": "失败", + "formatError": "第 {{line}} 行格式错误" + }, + + "toast": { + "copied": "已复制", + "saved": "已保存", + "cleared": "已清空", + "refresh": "已刷新", + "error": "错误", + "loading": "加载中...", + "enterHostPort": "请先填主机和端口", + "experimentalEnabled": "已启用实验性功能", + "experimentalDisabled": "已关闭实验性功能", + "toggleFailed": "切换失败:{{error}}", + "loginSuccess": "{{label}} 登录成功", + "loginFailed": "{{label}} 登录失败:{{error}}", + "loginSuccessAdded": "登录成功,账号已加入账号池", + "clipboardRead": "已读取剪贴板", + "clipboardEmpty": "剪贴板为空", + "clipboardUnsupported": "当前环境不支持自动读取剪贴板,请手动粘贴", + "clipboardError": "读取剪贴板失败:{{error}}", + "enterEmailPassword": "请输入邮箱和密码", + "restarting": "Language Server 重启中..." + }, + + "log": { + "level": { + "all": "所有级别", + "debug": "Debug", + "info": "Info", + "warn": "Warn", + "error": "Error" + }, + "searchPlaceholder": "搜索日志内容...", + "clearView": "清空视图", + "viaSSE": "通过 SSE 实时流式接收" + }, + + "model": { + "mode": { + "all": "全部允许", + "allowlist": "白名单", + "blocklist": "黑名单" + }, + "provider": { + "all": "全部供应商", + "anthropic": "Anthropic", + "openai": "OpenAI", + "google": "Google", + "deepseek": "DeepSeek", + "xai": "xAI", + "alibaba": "Alibaba", + "moonshot": "Moonshot", + "windsurf": "Windsurf" + }, + "list": { + "current": "当前清单 ({{count}})", + "empty": "清单为空" + } + }, + + "error": { + "generic": "发生错误", + "unknown": "未知错误", + "updateFailed": "更新失败", + "apiError": "API 错误", + "loadFailed": "加载失败", + "saveFailed": "保存失败", + "deleteFailed": "删除失败", + "networkError": "网络错误", + "authRequired": "请先登录", + "clipboardNotSupported": "当前环境不支持自动读取剪贴板,请手动粘贴", + "clipboardEmpty": "剪贴板为空", + "clipboardReadFailed": "读取剪贴板失败" + }, + + "footer": { + "version": "版本", + "langToggle": "切换语言" + }, + + "placeholder": { + "noProxy": "无代理" + }, + + "loginResult": { + "success": "✓ 登录成功", + "apiKeyGenerated": "API Key 已生成{{autoAdd}}", + "fail": "✗ 登录失败", + "batchComplete": "批量导入完成", + "batchDesc": "共 {{total}} 个账号,成功 {{success}} 个,失败 {{fail}} 个{{autoAdd}}", + "tryOther": "换个方式试试", + "oauthHint": "若你用 Google/GitHub 注册的 Windsurf 账号 此处密码登录不适用 请用页面顶部的 Google / GitHub 登录按钮 或访问 {{link}} 复制 Auth Token 后在「账号管理」页手动添加", + "fields": { + "email": "邮箱", + "name": "姓名", + "apiKey": "API Key", + "accountId": "账号 ID" + } + }, + + "timeRange": { + "minutesAgo": "{{count}}分钟前", + "hoursAgo": "{{count}}小时前", + "daysAgo": "{{count}}天前" + }, + + "prompt": { + "editor": { + "reset": "重置", + "search": "搜索提供商...", + "templateHint": "{{model}} 占位符会被替换成请求的模型名。" + } + }, + + "ls": { + "defaultInstance": "默认实例", + "noProxy": "无代理", + "port": "端口", + "pid": "PID", + "restartCount": "重启次数" + } +} diff --git a/src/dashboard/index.html b/src/dashboard/index.html index a4fe3fc0..86b99f09 100644 --- a/src/dashboard/index.html +++ b/src/dashboard/index.html @@ -3,7 +3,7 @@ -WindsurfAPI bydwgx1337 控制台 +WindsurfAPI bydwgx1337 控制台