Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,17 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

# Toolchain (Node 22) is pre-installed on the self-hosted runner.
# Toolchain (Node 26.1+) is pre-installed on the self-hosted runner.
# actions/setup-node is unreliable under the NetworkService account
# (HKLM/tool-cache permission issues), so just verify the version.
- name: Verify pre-installed Node.js
run: |
$ErrorActionPreference = 'Stop'
$node = (& node --version).TrimStart('v')
$parsed = [version]$node
$supported =
($parsed.Major -eq 22 -and $parsed -ge [version]'22.22.3') -or
($parsed.Major -eq 24 -and $parsed -ge [version]'24.15.0') -or
($parsed.Major -ge 25 -and $parsed -ge [version]'25.9.0')
if (-not $supported) { throw "Node $node is unsupported by OpenClaw 2026.8.2" }
. .\scripts\windows\node-runtime.ps1
$node = & node --version
if ($LASTEXITCODE -ne 0 -or -not (Test-SupportedNodeVersion $node)) {
throw "Node $node is unsupported by OpenClaw 2026.9.3 (need >=24.16.0 <25 || >=26.1.0; install Node 26)"
}
Write-Host "node $node"

- name: Install dependencies (all packages)
Expand Down Expand Up @@ -138,20 +136,18 @@ jobs:
with:
submodules: recursive

# Toolchain (Node 22, .NET 9/10 SDKs, Python 3.12+) is pre-installed on
# Toolchain (Node 26.1+, .NET 9/10 SDKs, Python 3.12+) is pre-installed on
# the self-hosted runner. We only verify versions here; installing
# via actions/setup-* is unreliable under the NetworkService account
# (HKLM/tool-cache permission issues).
- name: Verify pre-installed toolchain
run: |
$ErrorActionPreference = 'Stop'
$node = (& node --version).TrimStart('v')
$parsed = [version]$node
$supported =
($parsed.Major -eq 22 -and $parsed -ge [version]'22.22.3') -or
($parsed.Major -eq 24 -and $parsed -ge [version]'24.15.0') -or
($parsed.Major -ge 25 -and $parsed -ge [version]'25.9.0')
if (-not $supported) { throw "Node $node is unsupported by OpenClaw 2026.8.2" }
. .\scripts\windows\node-runtime.ps1
$node = & node --version
if ($LASTEXITCODE -ne 0 -or -not (Test-SupportedNodeVersion $node)) {
throw "Node $node is unsupported by OpenClaw 2026.9.3 (need >=24.16.0 <25 || >=26.1.0; install Node 26)"
}
Write-Host "node $node"
$sdks = & dotnet --list-sdks
if (-not ($sdks -match '^9\.')) { throw ".NET 9 SDK is required" }
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-security-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js 22
- name: Setup Node.js 26
uses: actions/setup-node@v4
with:
node-version: "22"
node-version: "26"

# Install dependencies
- name: Install root dependencies
Expand Down
16 changes: 7 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ jobs:
# (reliable on hosted runners, unlike on the self-hosted NetworkService
# account). build.ps1 then installs its own npm/pip deps and locates NSIS
# from electron-builder's cache.
- name: Setup Node.js 22
- name: Setup Node.js 26
uses: actions/setup-node@v4
with:
node-version: "22"
node-version: "26"

- name: Setup .NET 9 and 10 SDKs
uses: actions/setup-dotnet@v4
Expand All @@ -99,13 +99,11 @@ jobs:
- name: Verify toolchain
run: |
$ErrorActionPreference = 'Stop'
$node = (& node --version).TrimStart('v')
$parsed = [version]$node
$supported =
($parsed.Major -eq 22 -and $parsed -ge [version]'22.22.3') -or
($parsed.Major -eq 24 -and $parsed -ge [version]'24.15.0') -or
($parsed.Major -ge 25 -and $parsed -ge [version]'25.9.0')
if (-not $supported) { throw "Node $node is unsupported by OpenClaw 2026.8.2" }
. .\scripts\windows\node-runtime.ps1
$node = & node --version
if ($LASTEXITCODE -ne 0 -or -not (Test-SupportedNodeVersion $node)) {
throw "Node $node is unsupported by OpenClaw 2026.9.3 (need >=24.16.0 <25 || >=26.1.0; install Node 26)"
}
Write-Host "node $node"
$sdks = & dotnet --list-sdks
if (-not ($sdks -match '^9\.')) { throw ".NET 9 SDK is required" }
Expand Down
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ Custom skills installed to `~/.openclaw/skills/`. Each skill has `SKILL.md` (met

- `.env` (gitignored): `MODEL_API_KEY`, `MODEL_BASE_URL`, `MODEL_NAME`, `BRAVE_API_KEY`
- `openclaw.json`: Auto-generated by installer — gateway port, skill allowlists, model config
- Node.js installed via the official signed `.msi` to `%ProgramFiles%\nodejs\` (per-machine, UAC-elevated; override with `OPENCLAW_NODE_DIR`); existing system Node ≥22.16 at a standard path is reused as-is; OpenClaw state dir at `%APPDATA%/openclaw`
- OpenClaw target: **2026.9.3**. Node.js engine range: `>=24.16.0 <25 || >=26.1.0` (Node 22 and 25 unsupported); Node **26** is recommended and the download fallback is **26.1.0**.
- Node.js installed via the official signed `.msi` to `%ProgramFiles%\nodejs\` (per-machine, UAC-elevated; override with `OPENCLAW_NODE_DIR`); an existing supported system Node at a standard path is reused as-is; OpenClaw state dir at `%APPDATA%/openclaw`

## Key Constants (desktop/src/constants.ts)

Expand All @@ -149,6 +150,6 @@ Custom skills installed to `~/.openclaw/skills/`. Each skill has `SKILL.md` (met

## Prerequisites

- Node.js 22+ (build.ps1 auto-detects `%ProgramFiles%\nodejs\`, the per-user `%LocalAppData%\Programs\nodejs\`, or the legacy `~/.openclaw-node/`)
- Node.js 26.1+ (recommended), or 24.16+ on the 24.x line (build.ps1 validates the runtime in `%ProgramFiles%\nodejs\`, the per-user `%LocalAppData%\Programs\nodejs\`, the legacy `~/.openclaw-node/`, or PATH)
- Python 3.10+ (for installer and PyInstaller packaging)
- Windows 10/11 (Electron apps are Windows-only builds)
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additio
### Development Setup

1. Clone the repository
2. Install Node.js 22+
2. Install Node.js 26.1+ (recommended), or 24.16+ on the 24.x line. OpenClaw 2026.9.3 requires `>=24.16.0 <25 || >=26.1.0`; Node 22 and 25 are unsupported.
3. Install dependencies:
```bash
cd desktop && npm install
Expand Down
1 change: 1 addition & 0 deletions MicroClawDeployer.spec
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ a = Analysis(
('dist/microclaw-portable.zip', '.'),
('dist/install-manifest.json', '.'),
('scripts/windows/setup-dependencies.ps1', '.'),
('scripts/windows/node-runtime.ps1', '.'),
('scripts', 'scripts'),
('deployer/assets', 'deployer/assets'),
] + managed_skill_datas + webview_datas + pythonnet_datas,
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ MicroClaw targets **Windows 10/11**. For most users, the only thing you need to

Build the installer from source, then run it:

> **Build prerequisites** (only needed to run `build.ps1`): **Node.js 22+** and **Python 3.10+**. Install the Python build dependencies with `pip install -r requirements.txt` (this includes PyInstaller, used to package the installer exe). End users running the packaged `MicroClawInstaller.exe` do **not** need Python.
> **Build prerequisites** (only needed to run `build.ps1`): **Node.js 26.1+ (recommended)** or **24.16+ on the 24.x line**, and **Python 3.10+**. OpenClaw **2026.9.3** requires `>=24.16.0 <25 || >=26.1.0`; Node 22 and 25 are unsupported. Install the Python build dependencies with `pip install -r requirements.txt` (this includes PyInstaller, used to package the installer exe). End users running the packaged `MicroClawInstaller.exe` do **not** need Python.

```powershell
.\build.ps1 # produces dist/MicroClawInstaller/MicroClawInstaller.exe
Expand All @@ -124,7 +124,7 @@ Build the installer from source, then run it:
The installer handles the Windows-side setup in a single run:

- Git for Windows (PortableGit → `~/.openclaw-git`)
- Node.js 22+ via the official signed `.msi` (per-machine install to `%ProgramFiles%\nodejs\`, UAC-elevated; an existing system Node ≥22.16 at that path is reused as-is)
- Node.js 26 via the official signed `.msi` (per-machine install to `%ProgramFiles%\nodejs\`, UAC-elevated; an existing supported system Node at that path is reused as-is; supported range: `>=24.16.0 <25 || >=26.1.0`, download fallback: `26.1.0`)
- OpenClaw Gateway (`npm install -g openclaw`)
- Configures the npm registry mirror and V8 compile cache
- Installs the MicroClaw desktop client, managed skills, AppContainer sandbox, WeChat plugin
Expand Down Expand Up @@ -317,7 +317,7 @@ download-update path.

### Prerequisites

- Node.js 22+
- Node.js 26.1+ (recommended), or 24.16+ on the 24.x line
- Python 3.10+ — install build deps with `pip install -r requirements.txt` (includes PyInstaller)
- .NET 9 SDK (for the AppContainer launcher)
- .NET 10 SDK (for the bundled Windows Node host)
Expand Down
6 changes: 3 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ MicroClaw 仅支持 **Windows 10/11**。对大多数用户来说,真正需要

从源码构建安装器后运行:

> **构建前置依赖**(仅运行 `build.ps1` 时需要):**Node.js 22+** **Python 3.10+**。使用 `pip install -r requirements.txt` 安装 Python 构建依赖(其中包含用于打包安装器 exe 的 PyInstaller)。终端用户运行已打包的 `MicroClawInstaller.exe` **无需** 安装 Python。
> **构建前置依赖**(仅运行 `build.ps1` 时需要):**Node.js 26.1+(推荐)** **24.x 系列的 24.16+**,以及 **Python 3.10+**。OpenClaw **2026.9.3** 要求 `>=24.16.0 <25 || >=26.1.0`,不再支持 Node 22 和 25。使用 `pip install -r requirements.txt` 安装 Python 构建依赖(其中包含用于打包安装器 exe 的 PyInstaller)。终端用户运行已打包的 `MicroClawInstaller.exe` **无需** 安装 Python。

```powershell
.\build.ps1 # 生成 dist/MicroClawInstaller/MicroClawInstaller.exe
Expand All @@ -70,7 +70,7 @@ MicroClaw 仅支持 **Windows 10/11**。对大多数用户来说,真正需要
安装器会在一次运行中完成 Windows 侧的主要准备工作:

- Git for Windows(PortableGit → `~/.openclaw-git`)
- Node.js 22+,通过官方签名 `.msi` 以 per-machine 方式安装到 `%ProgramFiles%\nodejs\`(UAC 提权;若该路径已存在 ≥22.16 的系统 Node 则直接复用
- Node.js 26,通过官方签名 `.msi` 以 per-machine 方式安装到 `%ProgramFiles%\nodejs\`(UAC 提权;若该路径已存在受支持的系统 Node 则直接复用;支持范围为 `>=24.16.0 <25 || >=26.1.0`,下载回退版本为 `26.1.0`
- OpenClaw Gateway(`npm install -g openclaw`)
- 配置 npm 镜像源与 V8 编译缓存
- 安装 MicroClaw 桌面客户端、托管技能、AppContainer 沙箱、微信插件
Expand Down Expand Up @@ -199,7 +199,7 @@ npm run dev

### 前置条件

- Node.js 22+
- Node.js 26.1+(推荐),或 24.x 系列的 24.16+
- Python 3.10+ —— 通过 `pip install -r requirements.txt` 安装构建依赖(已包含 PyInstaller)
- .NET 9 SDK(用于构建 AppContainer 启动器)
- .NET 10 SDK(用于构建内置 Windows Node 主机)
Expand Down
24 changes: 17 additions & 7 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ function Get-FileSetId {
}
}

# Prefer Node 22 from the standard per-user MSI install location, falling back
# to the legacy zip-extract path and finally the system Node.
. "$root\scripts\windows\node-runtime.ps1"

# Prefer a supported standard MSI install, then the legacy zip and PATH.
$nodeCandidates = @(
"$env:ProgramFiles\nodejs",
"$env:LOCALAPPDATA\Programs\nodejs",
Expand All @@ -41,8 +42,13 @@ $nodeCandidates = @(
$nodeFound = $false
foreach ($candidate in $nodeCandidates) {
if (Test-Path "$candidate\node.exe") {
$version = & "$candidate\node.exe" --version
if ($LASTEXITCODE -ne 0 -or -not (Test-SupportedNodeVersion $version)) {
Write-Host " Skipping unsupported Node: $candidate ($version)" -ForegroundColor Yellow
continue
}
$env:PATH = "$candidate;$env:PATH"
Write-Host " Using Node: $candidate ($(& node --version))"
Write-Host " Using Node: $candidate ($version)"
$nodeFound = $true
break
}
Expand All @@ -55,15 +61,19 @@ if (-not $nodeFound) {
$nodeCmd = Get-Command node.exe -ErrorAction SilentlyContinue
if ($nodeCmd) {
$nodeDir = Split-Path -Parent $nodeCmd.Source
Write-Host " Using Node from PATH: $nodeDir ($(& node --version))"
$nodeFound = $true
$version = & $nodeCmd.Source --version
if ($LASTEXITCODE -eq 0 -and (Test-SupportedNodeVersion $version)) {
Write-Host " Using Node from PATH: $nodeDir ($version)"
$nodeFound = $true
}
}
}
if (-not $nodeFound) {
Write-Host " ERROR: node.exe not found in any of:" -ForegroundColor Red
Write-Host " ERROR: supported node.exe not found in any of:" -ForegroundColor Red
foreach ($candidate in $nodeCandidates) { Write-Host " - $candidate" -ForegroundColor Red }
Write-Host " - PATH (Get-Command node.exe)" -ForegroundColor Red
Write-Host " Install Node.js 22+ (https://nodejs.org/) and re-run build.ps1." -ForegroundColor Red
Write-Host " OpenClaw 2026.9.3 requires Node.js >=24.16.0 <25 || >=26.1.0." -ForegroundColor Red
Write-Host " Install Node.js 26 (https://nodejs.org/) and re-run build.ps1." -ForegroundColor Red
exit 1
}

Expand Down
3 changes: 3 additions & 0 deletions deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,9 @@ def _copy_bundled_assets(self, ws) -> bool:
if src:
try:
shutil.copy2(str(src), str(dest_dir / "setup-dependencies.ps1"))
shutil.copy2(
str(src.with_name("node-runtime.ps1")), str(dest_dir / "node-runtime.ps1")
)
self.logger.info(f"Setup script copied to {dest_dir} (for reference)")
except Exception as e:
self.logger.warn(f"Could not copy setup script: {e}")
Expand Down
2 changes: 1 addition & 1 deletion deployer/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def _load_dotenv() -> None:

DEFAULT_CONFIG: dict[str, Any] = {
"node": {
"version": "22",
"version": "26",
},
"openclaw": {
"install_method": "npm", # npm | source
Expand Down
16 changes: 9 additions & 7 deletions deployer/openclaw_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

import re

OPENCLAW_TARGET_VERSION = "2026.8.2"
NODE_FALLBACK_VERSION = "22.22.3"
OPENCLAW_TARGET_VERSION = "2026.9.3"
NODE_ENGINE_RANGE = ">=24.16.0 <25 || >=26.1.0"
NODE_FALLBACK_VERSION = "26.1.0"

_NODE_VERSION_RE = re.compile(r"^v?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)$")
_NODE_VERSION_RE = re.compile(
r"v?(?P<major>0|[1-9][0-9]*)\.(?P<minor>0|[1-9][0-9]*)\.(?P<patch>0|[1-9][0-9]*)"
)
_OPENCLAW_VERSION_RE = re.compile(r"openclaw@(?P<version>\S+)")


Expand All @@ -25,10 +28,9 @@ def is_supported_node_version(value: str) -> bool:

major, minor, patch = version
return (
(major == 22 and (minor, patch) >= (22, 3))
or (major == 24 and (minor, patch) >= (15, 0))
or (major == 25 and (minor, patch) >= (9, 0))
or major > 25
(major == 24 and (minor, patch) >= (16, 0))
or (major == 26 and (minor, patch) >= (1, 0))
or major > 26
)


Expand Down
3 changes: 3 additions & 0 deletions deployer/webview_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,9 @@ def _copy_bundled_assets(self):
if src:
try:
shutil.copy2(str(src), str(dest_dir / "setup-dependencies.ps1"))
shutil.copy2(
str(src.with_name("node-runtime.ps1")), str(dest_dir / "node-runtime.ps1")
)
self._logger.info(f"Setup script copied to {dest_dir} (for reference)")
except Exception as exc:
self._logger.warn(f"Could not copy setup script: {exc}")
Expand Down
Loading
Loading