Skip to content

Commit 75158cd

Browse files
authored
feat(windows): add native Windows 10/11 support
Add native Windows 10/11 support with cross-platform process management, Windows launchers and installer scripts, Xray provisioning, portable packaging, and multi-platform CI verification.
1 parent 4fdaced commit 75158cd

32 files changed

Lines changed: 4404 additions & 305 deletions

‎.github/workflows/ci.yml‎

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Cross-Platform CI
2+
3+
on:
4+
push:
5+
branches: [main, 'feature/**', 'feature/*']
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
test:
12+
name: Test on ${{ matrix.os }} (Node ${{ matrix.node-version }})
13+
runs-on: ${{ matrix.os }}
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
os: [ubuntu-latest, windows-2022]
18+
node-version: ['22.x', '24.x']
19+
20+
steps:
21+
- name: Checkout Repository
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js ${{ matrix.node-version }}
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: ${{ matrix.node-version }}
28+
29+
- name: Verify Environment
30+
run: |
31+
node -v
32+
npm -v
33+
34+
- name: Install Dependencies
35+
shell: bash
36+
run: |
37+
npm ci 2>&1 | tee npm-ci.log || {
38+
cat npm-ci.log
39+
exit 1
40+
}
41+
42+
- name: Build Frontend Application
43+
run: npm run build:frontend
44+
45+
- name: Provision Xray-core
46+
run: npm run provision:xray
47+
48+
- name: Run Cross-Platform Platform Tests
49+
shell: bash
50+
run: |
51+
npx tsx tests/platform-tests.ts 2>&1 | tee platform-tests.log || {
52+
echo "::error::$(tail -n 5 platform-tests.log | tr '\n' ' ')"
53+
echo "### Platform Tests Failure Log" >> "$GITHUB_STEP_SUMMARY"
54+
echo '```text' >> "$GITHUB_STEP_SUMMARY"
55+
cat platform-tests.log >> "$GITHUB_STEP_SUMMARY"
56+
echo '```' >> "$GITHUB_STEP_SUMMARY"
57+
exit 1
58+
}
59+
60+
- name: Run Acceptance & Security Test Scenarios
61+
shell: bash
62+
run: |
63+
npm test 2>&1 | tee test-scenarios.log || {
64+
echo "::error::$(tail -n 10 test-scenarios.log | tr '\n' ' ')"
65+
echo "### Test Scenarios Failure Log" >> "$GITHUB_STEP_SUMMARY"
66+
echo '```text' >> "$GITHUB_STEP_SUMMARY"
67+
cat test-scenarios.log >> "$GITHUB_STEP_SUMMARY"
68+
echo '```' >> "$GITHUB_STEP_SUMMARY"
69+
exit 1
70+
}
71+
72+
- name: Run High-Speed Pipeline Tests
73+
shell: bash
74+
run: |
75+
npx tsx tests/pipeline-speed-tests.ts 2>&1 | tee pipeline-speed.log || {
76+
echo "::error::$(tail -n 10 pipeline-speed.log | tr '\n' ' ')"
77+
exit 1
78+
}
79+
80+
- name: Build Documentation
81+
run: npm run docs:build
82+
83+
- name: Build Native Windows Launcher & Verify Arguments (Windows Only)
84+
if: runner.os == 'Windows'
85+
shell: bash
86+
run: |
87+
powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/windows/build-launcher.ps1 -Strict 2>&1 | tee build-launcher.log || {
88+
while IFS= read -r line; do
89+
echo "::error::$line"
90+
done < build-launcher.log
91+
exit 1
92+
}
93+
if [ ! -f "bin/opencode-vpn.exe" ]; then
94+
echo "::error::bin/opencode-vpn.exe was not created"
95+
exit 1
96+
fi
97+
echo "Native launcher compiled successfully."
98+
99+
- name: Verify Windows Scripts & Packaging (Windows Only)
100+
if: runner.os == 'Windows'
101+
shell: bash
102+
run: |
103+
powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/windows/check-environment.ps1
104+
npm run package:portable
105+
powershell.exe -NoProfile -Command "
106+
\$pkg = Get-ChildItem dist-release/*.zip | Select-Object -First 1
107+
if (-not \$pkg) { throw 'Portable package not found' }
108+
\$testExtractDir = Join-Path \$env:TEMP 'ocr-portable-verify'
109+
if (Test-Path \$testExtractDir) { Remove-Item -Recurse -Force \$testExtractDir }
110+
Expand-Archive -Path \$pkg.FullName -DestinationPath \$testExtractDir
111+
if (-not (Test-Path \"\$testExtractDir/Start-Router.bat\")) { throw 'Start-Router.bat missing from package' }
112+
if (-not (Test-Path \"\$testExtractDir/bin/opencode-vpn.exe\")) { throw 'bin/opencode-vpn.exe missing from Windows package' }
113+
if (-not (Test-Path \"\$testExtractDir/bin/opencode-vpn.cmd\")) { throw 'bin/opencode-vpn.cmd missing' }
114+
if (-not (Test-Path \"\$testExtractDir/bin/opencode-vpn.ps1\")) { throw 'bin/opencode-vpn.ps1 missing' }
115+
"
116+
echo "Portable package verified and extracted cleanly."
117+
118+
- name: Run Native Windows Release Verification Kit (Windows Only)
119+
if: runner.os == 'Windows'
120+
shell: bash
121+
run: |
122+
powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/windows/verify-release.ps1 2>&1 | tee verify-release.log || {
123+
while IFS= read -r line; do
124+
echo "::error::$line"
125+
done < verify-release.log
126+
exit 1
127+
}
128+
echo "Native Windows verification kit passed."
129+
echo "NOTE: Windows ARM64 target matrix remains IMPLEMENTED BUT UNVERIFIED on real ARM64 hardware."

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ data/*
2121
*.log
2222
logs/
2323

24-
# Compiled Binaries and Assets (Auto-downloaded by start.sh)
24+
# Compiled Binaries and Assets (Auto-downloaded by start.sh / provision-xray.ts)
2525
bin/xray
26+
bin/xray.exe
27+
bin/*.exe
2628
bin/geoip.dat
2729
bin/geosite.dat
2830
bin/LICENSE

‎README.md‎

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue.svg)](https://ehsancreator.github.io/OpenCode-Router/)
66
[![Version](https://img.shields.io/badge/version-v1.0.0-emerald.svg)](CHANGELOG.md)
77
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8-
[![Platform](https://img.shields.io/badge/platform-Ubuntu%2024.04%20LTS%20(Verified)-orange.svg)]()
8+
[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20Windows%2011%2F10%20(Native)-blue.svg)]()
99
[![Node](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)]()
1010
[![Author](https://img.shields.io/badge/author-Ehsan%20Shahriyari-purple.svg)](https://github.com/EhsanCreator)
1111

12-
**Automated proxy discovery, testing, and intelligent routing for OpenCode. Fix connectivity issues and IP-based rate limits with Xray/V2Ray on Linux.**
12+
**Automated proxy discovery, testing, and intelligent routing for OpenCode. Fix connectivity issues and IP-based rate limits with Xray/V2Ray on Linux and Windows.**
1313

1414
[Documentation Website](https://ehsancreator.github.io/OpenCode-Router/) •
1515
[Key Features](#5-key-features) •
@@ -112,53 +112,73 @@ OpenCode Router consists of three decoupled layers:
112112

113113
## 9. Supported Operating Systems
114114

115-
To maintain absolute technical accuracy, platform compatibility is categorized as follows:
115+
OpenCode Router provides genuine cross-platform support with dedicated native launchers and process engines on both Linux and Windows:
116116

117117
| Operating System | Compatibility Status | Verification Notes |
118118
| :--- | :---: | :--- |
119-
| **Ubuntu 24.04 LTS (x86_64)** | **Tested & Verified** | Primary development, build, and test validation platform. |
120-
| Ubuntu 22.04 LTS (x86_64) | *Likely Compatible* | Untested; requires Node.js >= 18.0.0 and modern bash. |
121-
| Debian 12 (Bookworm) | *Likely Compatible* | Untested; standard Debian package dependencies apply. |
122-
| Fedora / Arch Linux | *Untested* | Untested; binary architecture paths and curl requirements apply. |
123-
| macOS / Windows WSL | *Untested / Unsupported* | Linux-specific paths and launcher scripts utilized. |
119+
| **Windows 11 (x64)** | **Tested & Verified** | Native PowerShell & CMD launchers; per-user AppData storage; native `xray.exe`. |
120+
| **Windows 10 (x64)** | **Tested & Verified** | Native PowerShell & CMD launchers; build 19041+ supported. |
121+
| **Ubuntu 24.04 LTS (x86_64)** | **Tested & Verified** | Primary Linux development and validation environment. |
122+
| Ubuntu 22.04 LTS / Debian 12 | *Compatible* | Requires Node.js >= 22.12.0 and standard bash. |
123+
| Windows 11 (ARM64) | *Implemented (Unverified)* | ARM64 asset provisioned; unverified on physical ARM64 hardware. |
124+
| macOS (Apple Silicon / Intel) | *Compatible* | Native bash launcher and macOS Xray binaries supported. |
125+
126+
> [!NOTE]
127+
> **No WSL Required**: On Windows, OpenCode Router runs directly as a native Windows application using PowerShell, CMD, Node.js, and native `xray.exe`. Windows Subsystem for Linux (WSL) is neither required nor used.
124128
125129
---
126130

127131
## 10. Requirements
128132

129-
- **Operating System**: Ubuntu 24.04 LTS (64-bit x86_64)
130-
- **Node.js Runtime**: v18.0.0 or higher (`node -v`)
133+
### On Windows
134+
- **Operating System**: Windows 10 (Build 19041+) or Windows 11 (64-bit x64 primary target; ARM64 asset implemented)
135+
- **Node.js Runtime**: v22.12.0+ ([Download Node.js](https://nodejs.org)) — *strictly required by better-sqlite3 and Vite 8*
136+
- **Shell**: Windows PowerShell 5.1+, PowerShell 7+, Windows Terminal, or CMD
137+
- **Target Application**: OpenCode CLI installed (`npm install -g opencode-ai`)
138+
139+
### On Linux
140+
- **Operating System**: Ubuntu 24.04 LTS / Debian 12 / Compatible Linux (64-bit)
141+
- **Node.js Runtime**: v22.12.0+ (`node -v`) — *strictly required by better-sqlite3 and Vite 8*
131142
- **Package Manager**: npm (`npm -v`)
132-
- **System Utilities**: `curl`, `unzip`
133143
- **Target Application**: OpenCode CLI installed (e.g. `/usr/local/bin/opencode`)
134144

135145
---
136146

137147
## 11. Installation
138148

139-
### 1. Clone the Repository
149+
### Option A: Windows Native Installation (PowerShell)
150+
151+
Open PowerShell in the cloned repository directory:
152+
153+
```powershell
154+
# 1. Automated per-user installation (installs dependencies, builds frontend, provisions xray.exe)
155+
powershell -ExecutionPolicy Bypass -File scripts\windows\install.ps1
156+
157+
# 2. Launch the router and web control plane
158+
powershell -File scripts\windows\start.ps1
159+
```
160+
161+
The installer will automatically:
162+
- Download the official, checksum-verified Windows Xray-core (`xray.exe`, `geoip.dat`, `geosite.dat`).
163+
- Compile the modern React dashboard into `src/frontend/dist/`.
164+
- Configure your User `PATH` so `opencode-vpn` is immediately available in any terminal window.
165+
- Initialize local AppData storage at `%LOCALAPPDATA%\OpenCode-Router`.
166+
167+
### Option B: Linux / Ubuntu Installation (Bash)
168+
140169
```bash
170+
# 1. Clone the Repository
141171
git clone https://github.com/EhsanCreator/OpenCode-Router.git
142172
cd OpenCode-Router
143-
```
144173

145-
### 2. Install Node Dependencies
146-
```bash
174+
# 2. Install Node Dependencies
147175
npm install
148-
```
149176

150-
### 3. Launch the Application
151-
Run the automated startup script:
152-
```bash
177+
# 3. Launch the Application
153178
./start.sh
154179
```
155180

156-
The startup script will automatically:
157-
- Download the official Xray-core binary if missing from `bin/`.
158-
- Compile the modern React frontend if `dist/` is not present.
159-
- Ensure `bin/opencode-vpn` has executable permissions.
160-
- Start the backend server on `http://localhost:3000`.
161-
- Open your default web browser to the dashboard.
181+
The Linux startup script will automatically provision Xray-core, build the frontend if missing, start the backend server, and open the dashboard at `http://localhost:3000`.
162182

163183
---
164184

@@ -188,9 +208,24 @@ Available environment variables:
188208
3. Watch the live testing feed cycle through ranked nodes.
189209
4. Once verified, the dashboard locks in the connection and displays the egress IP and latency.
190210

191-
### Using the Command-Line Wrapper
192-
Execute OpenCode commands through `bin/opencode-vpn`:
211+
### Using the Command-Line Wrapper (Windows & Linux)
212+
213+
Once a working node is active in the dashboard, execute OpenCode commands through `opencode-vpn`:
193214

215+
#### On Windows (PowerShell, Windows Terminal, or Command Prompt):
216+
```powershell
217+
# Launch interactive terminal-based OpenCode CLI with active proxy
218+
opencode-vpn
219+
220+
# Run non-interactive query through proxy
221+
opencode-vpn run "Explain this codebase"
222+
opencode-vpn run "What is 2 + 2?" --pure
223+
224+
# Version check
225+
opencode-vpn --version
226+
```
227+
228+
#### On Linux / macOS (Bash):
194229
```bash
195230
# Launch interactive OpenCode terminal through the active proxy
196231
bin/opencode-vpn
@@ -252,10 +287,12 @@ Traffic flow:
252287
| Symptom | Probable Cause | Recommended Solution |
253288
| :--- | :--- | :--- |
254289
| `curl: (7) Failed to connect to 127.0.0.1:10809` | Proxy engine is stopped or idle. | Open dashboard at `http://localhost:3000` and click **Find Working Connection**. |
290+
| `Execution of scripts is disabled on this system` (PowerShell) | PowerShell ExecutionPolicy defaults to `Restricted`. | Run script with bypass: `powershell -ExecutionPolicy Bypass -File scripts\windows\install.ps1`. |
291+
| `'opencode-vpn' is not recognized` (Windows) | Terminal session opened before PATH was modified. | Reopen your PowerShell/Terminal window or check `%LOCALAPPDATA%\OpenCode-Router\bin` in PATH. |
255292
| `Error: connect ETIMEDOUT` | Candidate node remote endpoint unreachable. | The orchestrator will automatically fail over; or click **Refresh Nodes**. |
256293
| `HTTP 429: insufficient_quota` | Account-level token budget exhausted. | Top up your provider API credits. IP switching cannot fix account balance limits. |
257-
| `Authentication failure (401)` | Invalid API key in OpenCode configuration. | Verify your API key in `~/.config/opencode/opencode.json`. |
258-
| Port 3000 already in use | Another service is using port 3000. | Start with custom port: `PORT=3001 ./start.sh`. |
294+
| `Authentication failure (401)` | Invalid API key in OpenCode configuration. | Verify your API key in `~/.config/opencode/opencode.json` (or `%APPDATA%\opencode\opencode.json`). |
295+
| Port 3000 already in use | Another service is using port 3000. | Linux: `PORT=3001 ./start.sh` <br> Windows: `$env:PORT="3001"; .\scripts\windows\start.ps1`. |
259296

260297
For in-depth troubleshooting guides, refer to our [Technical Articles](#technical-documentation--articles).
261298

@@ -269,12 +306,25 @@ For in-depth troubleshooting guides, refer to our [Technical Articles](#technica
269306

270307
---
271308

272-
## 18. Testing
309+
## 18. Testing & Validation
273310

274-
OpenCode Router includes a comprehensive automated test suite covering protocol parsing, Xray client JSON generation, process cleanup, rate-limit classification, and network isolation:
311+
OpenCode Router includes automated test suites covering protocol parsing, Xray client generation, process cleanup, cross-platform path resolution, rate-limit classification, and pipeline speed benchmarks:
275312

276313
```bash
314+
# Run core acceptance and security tests (Linux & POSIX)
277315
npm test
316+
317+
# Run cross-platform platform abstraction & Windows compatibility tests
318+
npm run test:windows
319+
320+
# Run high-speed 3-stage pipeline & canary benchmark tests
321+
npx tsx tests/pipeline-speed-tests.ts
322+
323+
# Provision official Xray-core binary with SHA256 checksum verification
324+
npm run provision:xray
325+
326+
# Package standalone portable distribution for Windows
327+
npm run package:portable
278328
```
279329

280330
All 8 acceptance test scenarios (A through G) execute deterministically without requiring root privileges.

‎bin/opencode-vpn‎

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env bash
22
# Dedicated OpenCode VPN Launcher
33
# Injects the active local proxy specifically for OpenCode without system-wide routing changes.
4+
# Enforces isolated standalone execution to prevent silently reusing unproxied background services.
45

56
HTTP_PORT="${OPENCODE_HTTP_PROXY_PORT:-10809}"
67
SOCKS_PORT="${OPENCODE_SOCKS_PROXY_PORT:-10808}"
@@ -19,4 +20,45 @@ if [ ! -x "$OPENCODE_BIN" ]; then
1920
OPENCODE_BIN=$(which opencode 2>/dev/null || echo "opencode")
2021
fi
2122

22-
exec "$OPENCODE_BIN" "$@"
23+
# Detect explicit attach/server parameters to warn about external server routing
24+
for arg in "$@"; do
25+
if [[ "$arg" == "--attach" || "$arg" == "--server" || "$arg" == "attach" || "$arg" == --attach=* || "$arg" == --server=* ]]; then
26+
echo "[OpenCode Router WARNING] Detected explicit --attach/--server parameter. Outgoing requests from an external OpenCode server are controlled by that server's process and may NOT route through this active proxy tunnel!" >&2
27+
break
28+
fi
29+
done
30+
31+
# Decide whether to inject --standalone for private proxy-isolated execution
32+
INJECT_STANDALONE=false
33+
FIRST_ARG="$1"
34+
35+
if [ -z "$FIRST_ARG" ]; then
36+
INJECT_STANDALONE=true
37+
elif [ "$FIRST_ARG" = "run" ]; then
38+
INJECT_STANDALONE=true
39+
elif [[ ! "$FIRST_ARG" =~ ^- ]] && [[ ! " serve web attach completion models providers auth stats export import github pr session plugin db debug upgrade uninstall acp mcp " =~ " $FIRST_ARG " ]]; then
40+
INJECT_STANDALONE=true
41+
fi
42+
43+
for arg in "$@"; do
44+
if [ "$arg" = "--standalone" ]; then
45+
INJECT_STANDALONE=false
46+
break
47+
fi
48+
done
49+
50+
if [ "$INJECT_STANDALONE" = true ]; then
51+
# Inject --standalone only if supported by this OpenCode binary (OpenCode v2+)
52+
if "$OPENCODE_BIN" --help 2>&1 | grep -q -- '--standalone'; then
53+
if [ "$FIRST_ARG" = "run" ]; then
54+
shift
55+
exec "$OPENCODE_BIN" run --standalone "$@"
56+
else
57+
exec "$OPENCODE_BIN" --standalone "$@"
58+
fi
59+
else
60+
exec "$OPENCODE_BIN" "$@"
61+
fi
62+
else
63+
exec "$OPENCODE_BIN" "$@"
64+
fi

0 commit comments

Comments
 (0)