@@ -25,21 +25,26 @@ Turns [Windsurf](https://windsurf.com) (formerly Codeium)'s AI models into **two
2525
2626## What is it doing?
2727
28- ```
29- ┌─────────────┐ /v1/chat/completions ┌────────────┐
30- │ OpenAI SDK │ ──────────────────────→ │ │
31- │ curl / Frontend │ ←────────────────────── │ │
32- └─────────────┘ OpenAI JSON + SSE │ WindsurfAPI│
33- │ Node.js │ ┌──────────────┐ ┌─────────────────┐
34- ┌─────────────┐ /v1/messages │ (This Service) │ gRPC │ Language │ HTTPS │ Windsurf Cloud │
35- │ Claude Code │ ──────────────────────→ │ │ ───→ │ Server (LS) │ ────→ │ server.self- │
36- │ Cline │ ←────────────────────── │ │ ←─── │ (Windsurf │ ←─── │ serve.windsurf │
37- │ Cursor │ Anthropic SSE │ │ │ binary) │ │ .com │
38- └─────────────┘ └────────────┘ └──────────────┘ └─────────────────┘
39- ↑
40- Account Pool Round-Robin
41- Rate Limit Isolation
42- Failover
28+ ``` mermaid
29+ flowchart LR
30+ subgraph Clients
31+ A[OpenAI SDK<br>curl / Frontend]
32+ B[Claude Code<br>Cline<br>Cursor]
33+ end
34+
35+ subgraph WindsurfAPI["WindsurfAPI (Node.js)"]
36+ C[HTTP Service<br>Port 3003]
37+ D[Account Pool<br>Round-Robin<br>Rate Limit<br>Failover]
38+ end
39+
40+ E["Language Server<br>(Windsurf binary)"]
41+ F[Windsurf Cloud<br>server.self-serve.windsurf.com]
42+
43+ A -->|"/v1/chat/completions"<br>OpenAI JSON + SSE| C
44+ B -->|"/v1/messages"<br>Anthropic SSE| C
45+ C <-->|gRPC| E
46+ E <-->|HTTPS| F
47+ D -.-> C
4348```
4449
4550** What it does** :
@@ -52,29 +57,26 @@ Turns [Windsurf](https://windsurf.com) (formerly Codeium)'s AI models into **two
5257
5358The model itself does ** not** operate on files — file operations are executed locally by the IDE Agent client (Claude Code, Cline, etc.):
5459
55- ```
56- You "Help me fix a bug" Claude Code WindsurfAPI Windsurf Cloud
57- │ │ │ │
58- │────────────────────────────→ │ │ │
59- │ │ POST /v1/messages │ │
60- │ │ messages + tools + system │ │
61- │ │ ─────────────────────────────→│ Package into Cascade request │
62- │ │ │ ──────────────────────→ │
63- │ │ │ │
64- │ │ │ Model thinks → returns
65- │ │ │ tool_use(edit_file)
66- │ │ │ ←────────────────────── │
67- │ │ ←── Anthropic SSE ────────────│ │
68- │ │ content_block=tool_use │ │
69- │ │ │ │
70- │ │ Execute edit_file() locally │ │
71- │ │ (Read/write local files) │ │
72- │ │ │ │
73- │ │ Send another turn with tool_result │ │
74- │ │ ─────────────────────────────→│ ──────────────────────→ │
75- │ │ ... (loop) ...
76- │ │ │ │
77- │ ← Final answer │ │ │
60+ ``` mermaid
61+ sequenceDiagram
62+ actor U as You
63+ participant CC as Claude Code
64+ participant WA as WindsurfAPI
65+ participant WC as Windsurf Cloud
66+
67+ U->>CC: "Help me fix a bug"
68+ CC->>WA: POST /v1/messages<br>messages + tools + system
69+ WA->>WC: Package into Cascade request
70+ WC-->>WA: Model thinks → returns<br>tool_use(edit_file)
71+ WA-->>CC: Anthropic SSE<br>content_block=tool_use
72+ CC->>CC: Execute edit_file() locally<br>(Read/write local files)
73+ CC->>WA: Send tool_result
74+ WA->>WC: Continue conversation...
75+ loop Conversation Loop
76+ WC-->>WA: Response
77+ WA-->>CC: SSE stream
78+ end
79+ CC-->>U: Final answer
7880```
7981
8082** Key Point** : WindsurfAPI is only responsible for ** passing** ` tool_use ` / ` tool_result ` . The client CLI is what actually modifies the files.
@@ -165,6 +167,10 @@ LS_PORT=42100
165167DASHBOARD_PASSWORD=
166168EOF
167169
170+ # Note: Inline comments are supported in .env for unquoted values:
171+ # PORT=3003 # Service port
172+ # Quoted values preserve everything inside the quotes.
173+
168174node src/index.js
169175```
170176
@@ -181,16 +187,16 @@ Open `http://YOUR_IP:3003/dashboard` → Login to get token → Click **Sign in
181187Go to [ windsurf.com/show-auth-token] ( https://windsurf.com/show-auth-token ) to copy your token:
182188
183189``` bash
184- curl -X POST http://localhost:3003/auth/login
185- -H " Content-Type: application/json"
190+ curl -X POST http://localhost:3003/auth/login
191+ -H " Content-Type: application/json"
186192 -d ' {"token": "YOUR_TOKEN"}'
187193```
188194
189195** Method 3: Batch**
190196
191197``` bash
192- curl -X POST http://localhost:3003/auth/login
193- -H " Content-Type: application/json"
198+ curl -X POST http://localhost:3003/auth/login
199+ -H " Content-Type: application/json"
194200 -d ' {"accounts": [{"token": "t1"}, {"token": "t2"}]}'
195201```
196202
@@ -218,9 +224,9 @@ claude # Use Claude Code as usual
218224
219225``` bash
220226# Raw curl test
221- curl http://localhost:3003/v1/messages
222- -H " Authorization: Bearer YOUR_KEY"
223- -H " anthropic-version: 2023-06-01"
227+ curl http://localhost:3003/v1/messages
228+ -H " Authorization: Bearer YOUR_KEY"
229+ -H " anthropic-version: 2023-06-01"
224230 -d ' {"model":"claude-opus-4.6","max_tokens":100,"messages":[{"role":"user","content":"Hello"}]}'
225231```
226232
@@ -250,12 +256,21 @@ In your client's settings for **Custom OpenAI Compatible**:
250256| ` PORT ` | ` 3003 ` | Service port |
251257| ` API_KEY ` | empty | API key required for requests. Leave empty to disable validation. |
252258| ` DATA_DIR ` | project root | Directory for persisted JSON state and ` logs/ ` . Docker deployments should usually use ` /data ` . |
259+ | ` CODEIUM_API_KEY ` | empty | Direct API key from Windsurf (alternative to token-based auth). |
260+ | ` CODEIUM_AUTH_TOKEN ` | empty | Token from [ windsurf.com/show-auth-token] ( https://windsurf.com/show-auth-token ) . |
261+ | ` CODEIUM_EMAIL ` | empty | Email for Windsurf account authentication. |
262+ | ` CODEIUM_PASSWORD ` | empty | Password for Windsurf account authentication. |
263+ | ` CODEIUM_API_URL ` | ` https://server.self-serve.windsurf.com ` | Windsurf cloud API endpoint. |
253264| ` DEFAULT_MODEL ` | ` claude-4.5-sonnet-thinking ` | The model to use if ` model ` is not specified. |
254265| ` MAX_TOKENS ` | ` 8192 ` | Default maximum number of response tokens. |
255266| ` LOG_LEVEL ` | ` info ` | debug / info / warn / error |
256267| ` LS_BINARY_PATH ` | ` /opt/windsurf/language_server_linux_x64 ` | Path to the LS binary. |
257268| ` LS_PORT ` | ` 42100 ` | LS gRPC port. |
269+ | ` LS_DATA_DIR ` | ` /opt/windsurf ` | Per-proxy LS data directory root. |
258270| ` DASHBOARD_PASSWORD ` | empty | Dashboard password. Leave empty for no password. |
271+ | ` CASCADE_REUSE_STRICT ` | ` 0 ` | Set to ` 1 ` for strict conversation reuse mode (waits for same fingerprint). |
272+ | ` CASCADE_REUSE_STRICT_RETRY_MS ` | ` 60000 ` | Retry delay in ms for strict reuse mode. |
273+ | ` CASCADE_REUSE_HASH_SYSTEM ` | ` 0 ` | Set to ` 1 ` to include system messages in conversation reuse hash. |
259274
260275## Dashboard Features
261276
@@ -306,6 +321,10 @@ deepseek-v3 / v3-2 / r1 · grok-3 / mini / mini-thinking / code-fast-1 · qwen-3
306321
307322> ** Free accounts** can only use ` gpt-4o-mini ` and ` gemini-2.5-flash ` . Others require Windsurf Pro.
308323
324+ ### Language-Following for CJK Users
325+
326+ 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.
327+
309328## Architecture Highlights
310329
311330- ** Zero npm dependencies** Everything uses ` node:* ` built-ins · Protobuf is handcrafted (` src/proto.js ` ) · Download and run.
0 commit comments