create-openclaw-bot 5.2.1 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/CHANGELOG.vi.md +11 -0
- package/README.md +4 -4
- package/README.vi.md +4 -4
- package/cli.js +7 -5
- package/package.json +1 -1
- package/setup.js +4 -3
- package/tests/smoke-cli-logic.mjs +10 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Changelog (English)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [5.2.2] — 2026-04-10
|
|
5
|
+
|
|
6
|
+
### 🐛 Docker & Native PM2 Bug Fixes
|
|
7
|
+
|
|
8
|
+
- **Fix Docker crash loop (socat port conflict)**: `socat TCP-LISTEN:18791` was binding `0.0.0.0:18791` before `openclaw gateway run` started, causing `EADDRINUSE` on `127.0.0.1:18791`. Removed the broken gateway bridge from the generated Dockerfile CMD in both `cli.js` and `setup.js`.
|
|
9
|
+
- **Fix Docker dashboard not accessible from host**: Gateway `bind` was set to `'loopback'` — Docker port mapping cannot route to container loopback. Restored the v5.0.9 working pattern: `bind:'custom', customBindHost:'0.0.0.0'`.
|
|
10
|
+
- **Fix `delete c.gateway.customBindHost`**: A stray `delete` statement was erasing the `customBindHost` key right after setting it. Removed.
|
|
11
|
+
- **Fix Docker build re-downloading npm packages on every rebuild**: `ARG CACHEBUST=<epoch>` was cache-busting the `npm install -g openclaw` layer on every build (even config-only changes). Replaced with a version-stable `ARG OPENCLAW_VER` so Docker layer cache is reused between rebuilds.
|
|
12
|
+
- **Fix native PM2 double `.openclaw` nesting**: `ecosystem.config.js` was setting `OPENCLAW_HOME: projectDir/.openclaw`, causing OpenClaw to resolve workspace as `projectDir/.openclaw/.openclaw/workspace`. Removed `OPENCLAW_HOME` from PM2 env; OpenClaw discovers config via `cwd` (matching v5.0.9 behavior).
|
|
13
|
+
|
|
4
14
|
## [5.2.1] — 2026-04-09
|
|
5
15
|
|
|
6
16
|
### 🐛 Native Ubuntu/VPS Bug Fixes
|
package/CHANGELOG.vi.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# Changelog (Tiếng Việt)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [5.2.2] — 2026-04-10
|
|
5
|
+
|
|
6
|
+
### 🐛 Sửa lỗi Docker & Native PM2
|
|
7
|
+
|
|
8
|
+
- **Sửa crash loop Docker (xung đột port socat)**: `socat TCP-LISTEN:18791` chiếm port `0.0.0.0:18791` trước khi `openclaw gateway run` khởi động, gây `EADDRINUSE`. Đã xóa gateway bridge khỏi Dockerfile CMD trong `cli.js` và `setup.js`.
|
|
9
|
+
- **Sửa Dashboard Docker không vào được từ host**: Gateway `bind` đặt là `'loopback'` — Docker port mapping không reach được loopback bên trong container. Khôi phục pattern đúng từ v5.0.9: `bind:'custom', customBindHost:'0.0.0.0'`.
|
|
10
|
+
- **Sửa `delete c.gateway.customBindHost`**: Một lệnh `delete` thừa đang xóa key `customBindHost` ngay sau khi set. Đã xóa dòng đó.
|
|
11
|
+
- **Sửa Docker tải lại npm mỗi lần build**: `ARG CACHEBUST=<timestamp>` bust cache layer `npm install -g openclaw` mỗi lần build dù chỉ đổi config. Thay bằng `ARG OPENCLAW_VER` ổn định theo version — Docker tái sử dụng cache giữa các lần rebuild.
|
|
12
|
+
- **Sửa lồng đôi `.openclaw` trong native PM2**: `ecosystem.config.js` đang đặt `OPENCLAW_HOME: projectDir/.openclaw`, khiến OpenClaw resolve workspace thành `projectDir/.openclaw/.openclaw/workspace`. Đã xóa `OPENCLAW_HOME` khỏi PM2 env; OpenClaw tự tìm config qua `cwd` (khớp với v5.0.9).
|
|
13
|
+
|
|
14
|
+
|
|
4
15
|
## [5.2.1] — 2026-04-09
|
|
5
16
|
|
|
6
17
|
### 🐛 Sửa Lỗi Ubuntu/VPS Native
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# 🦞 OpenClaw Setup
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.2.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.2.2-0EA5E9?style=for-the-badge" alt="Version 5.2.2" /></a>
|
|
7
7
|
<a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
|
|
8
8
|
<a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
|
|
9
9
|
<a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
|
|
@@ -24,7 +24,7 @@ An interactive **CLI tool** and **Setup Wizard** to deploy your own free AI Bot
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
## 🆕 What's new in v5.2.
|
|
27
|
+
## 🆕 What's new in v5.2.2
|
|
28
28
|
|
|
29
29
|
- 🔄 **One-command upgrade** — Run `npx create-openclaw-bot@latest upgrade` in your bot folder to update OpenClaw without re-running the wizard. Auto-detects Docker vs Native mode.
|
|
30
30
|
- 🪟 **Windows upgrade shortcut** — `upgrade.ps1` ships with the repo. Double-click it to upgrade instantly (no terminal knowledge required).
|
|
@@ -32,7 +32,7 @@ An interactive **CLI tool** and **Setup Wizard** to deploy your own free AI Bot
|
|
|
32
32
|
- 🛡️ **All user data preserved** — `.env`, memory, sessions, credentials, and 9Router OAuth tokens are never touched during upgrade.
|
|
33
33
|
|
|
34
34
|
<details>
|
|
35
|
-
<summary><b>Previous: What's new in v5.2.
|
|
35
|
+
<summary><b>Previous: What's new in v5.2.2</b></summary>
|
|
36
36
|
|
|
37
37
|
- 🔒 **Pinned OpenClaw version** — The OpenClaw update published on `April 8, 2026` is currently broken, so setup now stays on `openclaw@2026.4.5` for stability.
|
|
38
38
|
- 🐳 **Dockerfile fixes** — Fixed the Windows Docker flow so startup no longer breaks on bad command escaping or invalid generated `allowedOrigins`.
|
|
@@ -110,7 +110,7 @@ Run in your terminal → follow the interactive prompts → startup script is ge
|
|
|
110
110
|
2. Open this repo as your workspace
|
|
111
111
|
3. Paste into chat:
|
|
112
112
|
```
|
|
113
|
-
Read SETUP.md and set up OpenClaw v5.2.
|
|
113
|
+
Read SETUP.md and set up OpenClaw v5.2.2 for me.
|
|
114
114
|
My bot token is X. Use 9Router (no API key).
|
|
115
115
|
My project folder: <YOUR_PATH>
|
|
116
116
|
```
|
package/README.vi.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# 🦞 OpenClaw Setup
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.2.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.2.2-0EA5E9?style=for-the-badge" alt="Version 5.2.2" /></a>
|
|
7
7
|
<a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
|
|
8
8
|
<a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
|
|
9
9
|
<a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
|
|
@@ -24,7 +24,7 @@ Công cụ **CLI tương tác** và **Setup Wizard** để tự triển khai Bot
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
## 🆕 Có gì mới trong v5.2.
|
|
27
|
+
## 🆕 Có gì mới trong v5.2.2
|
|
28
28
|
|
|
29
29
|
- 🔄 **Upgrade 1 lệnh** — Chạy `npx create-openclaw-bot@latest upgrade` trong thư mục bot để cập nhật OpenClaw mà không cần chạy lại wizard. Tự động nhận diện Docker hay Native.
|
|
30
30
|
- 🪟 **Windows: double-click để upgrade** — File `upgrade.ps1` có sẵn trong repo. Nhấp đúp là xong — không cần biết terminal.
|
|
@@ -32,7 +32,7 @@ Công cụ **CLI tương tác** và **Setup Wizard** để tự triển khai Bot
|
|
|
32
32
|
- 🛡️ **Dữ liệu cũ giữ nguyên hoàn toàn** — `.env`, memory, sessions, credentials, OAuth token 9Router không bao giờ bị xoá khi upgrade.
|
|
33
33
|
|
|
34
34
|
<details>
|
|
35
|
-
<summary><b>Trước đó: Có gì mới ở v5.2.
|
|
35
|
+
<summary><b>Trước đó: Có gì mới ở v5.2.2</b></summary>
|
|
36
36
|
|
|
37
37
|
- 🔒 **Pin lại OpenClaw** — Bản OpenClaw cập nhật ngày `08/04/2026` đang lỗi, nên setup được fix để giữ ở `openclaw@2026.4.5` cho ổn định.
|
|
38
38
|
- 🐳 **Fix Dockerfile** — Sửa luồng Docker cho Windows để không còn lỗi startup do command/escaping sai và tránh lỗi `allowedOrigins` bị sinh ra không hợp lệ.
|
|
@@ -110,7 +110,7 @@ Chạy lệnh trên trong Terminal → làm theo các prompt tương tác → sc
|
|
|
110
110
|
2. Mở repo này làm workspace
|
|
111
111
|
3. Paste vào chat:
|
|
112
112
|
```
|
|
113
|
-
Read SETUP.md and set up OpenClaw v5.2.
|
|
113
|
+
Read SETUP.md and set up OpenClaw v5.2.2 for me.
|
|
114
114
|
My bot token is X. Use 9Router (no API key).
|
|
115
115
|
My project folder: <THƯ_MỤC_CỦA_BẠN>
|
|
116
116
|
```
|
package/cli.js
CHANGED
|
@@ -1624,7 +1624,7 @@ async function main() {
|
|
|
1624
1624
|
}
|
|
1625
1625
|
|
|
1626
1626
|
|
|
1627
|
-
const patchScript = `const fs=require('fs'),os=require('os'),p='/root/.openclaw/openclaw.json';if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));const a=new Set(['http://localhost:18791','http://127.0.0.1:18791','http://0.0.0.0:18791']);for(const entries of Object.values(os.networkInterfaces()||{})){for(const entry of entries||[]){if(!entry||entry.internal||entry.family!=='IPv4'||!entry.address)continue;a.add('http://' + entry.address + ':18791');}}c.tools=Object.assign({},c.tools,{profile:'full',exec:{host:'gateway',security:'full',ask:'off'}});c.gateway=Object.assign({},c.gateway,{port:18791,bind:'
|
|
1627
|
+
const patchScript = `const fs=require('fs'),os=require('os'),p='/root/.openclaw/openclaw.json';if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));const a=new Set(['http://localhost:18791','http://127.0.0.1:18791','http://0.0.0.0:18791']);for(const entries of Object.values(os.networkInterfaces()||{})){for(const entry of entries||[]){if(!entry||entry.internal||entry.family!=='IPv4'||!entry.address)continue;a.add('http://' + entry.address + ':18791');}}c.tools=Object.assign({},c.tools,{profile:'full',exec:{host:'gateway',security:'full',ask:'off'}});c.gateway=Object.assign({},c.gateway,{port:18791,bind:'custom',customBindHost:'0.0.0.0',controlUi:Object.assign({},c.gateway?.controlUi,{allowedOrigins:Array.from(a).filter(Boolean)})});fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
|
|
1628
1628
|
const b64Patch = Buffer.from(patchScript).toString('base64');
|
|
1629
1629
|
|
|
1630
1630
|
// Browser Playwright (both desktop & server modes need chromium)
|
|
@@ -1639,7 +1639,9 @@ async function main() {
|
|
|
1639
1639
|
// socat only for Desktop mode (bridge to host Chrome)
|
|
1640
1640
|
const socatApt = ' socat';
|
|
1641
1641
|
const socatBridge = hasBrowserDesktop ? 'socat TCP-LISTEN:9222,fork,reuseaddr TCP:host.docker.internal:9222 & ' : '';
|
|
1642
|
-
|
|
1642
|
+
// gatewayBridge removed: socat on 0.0.0.0:18791 conflicts with openclaw binding 127.0.0.1:18791.
|
|
1643
|
+
// The openclaw gateway connects outbound to chat platforms — no inbound bridge needed.
|
|
1644
|
+
const gatewayBridge = '';
|
|
1643
1645
|
|
|
1644
1646
|
// Skills install at RUNTIME (not build-time — requires openclaw config + ClawHub auth)
|
|
1645
1647
|
const skillSlugs = SKILLS
|
|
@@ -1662,7 +1664,7 @@ async function main() {
|
|
|
1662
1664
|
if (browserDockerLines) dockerfileLines.push(browserDockerLines);
|
|
1663
1665
|
dockerfileLines.push(
|
|
1664
1666
|
'',
|
|
1665
|
-
`ARG
|
|
1667
|
+
`ARG OPENCLAW_VER="${OPENCLAW_NPM_SPEC}"`,
|
|
1666
1668
|
`RUN npm install -g ${OPENCLAW_NPM_SPEC} ${OPENCLAW_RUNTIME_PACKAGES}`,
|
|
1667
1669
|
'',
|
|
1668
1670
|
'# Fix chat.send dropping resolved agent timeout into reply pipeline.',
|
|
@@ -2138,7 +2140,7 @@ ${hasBrowserDesktop ? ` extra_hosts:
|
|
|
2138
2140
|
` interpreter: 'none',`,
|
|
2139
2141
|
` autorestart: true,`,
|
|
2140
2142
|
` watch: false,`,
|
|
2141
|
-
` env: { NODE_ENV: 'production',
|
|
2143
|
+
` env: { NODE_ENV: 'production', DATA_DIR: '${path.join(projectDir, '.9router').replace(/\\/g, '/')}' }`,
|
|
2142
2144
|
' },',
|
|
2143
2145
|
' {',
|
|
2144
2146
|
` name: '${botName || 'openclaw-multibot'}-auto-approve',`,
|
|
@@ -2148,7 +2150,7 @@ ${hasBrowserDesktop ? ` extra_hosts:
|
|
|
2148
2150
|
` interpreter: 'none',`,
|
|
2149
2151
|
` autorestart: true,`,
|
|
2150
2152
|
` watch: false,`,
|
|
2151
|
-
` env: { NODE_ENV: 'production',
|
|
2153
|
+
` env: { NODE_ENV: 'production', DATA_DIR: '${path.join(projectDir, '.9router').replace(/\\/g, '/')}' }`,
|
|
2152
2154
|
' }',
|
|
2153
2155
|
].join('\n');
|
|
2154
2156
|
const ecosystemContent = [
|
package/package.json
CHANGED
package/setup.js
CHANGED
|
@@ -2083,9 +2083,10 @@ model:
|
|
|
2083
2083
|
const browserPrefix = hasBrowser
|
|
2084
2084
|
? 'socat TCP-LISTEN:9222,fork,reuseaddr TCP:host.docker.internal:9222 & '
|
|
2085
2085
|
: '';
|
|
2086
|
-
|
|
2086
|
+
// gatewayBridgePrefix removed: socat on 0.0.0.0:18791 conflicts with openclaw binding 127.0.0.1:18791.
|
|
2087
|
+
const gatewayBridgePrefix = '';
|
|
2087
2088
|
// Patch config on every startup to keep gateway settings stable
|
|
2088
|
-
const patchCmd = `node -e \\"const fs=require('fs'),os=require('os'),p='/root/.openclaw/openclaw.json';if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));const a=new Set(['http://localhost:18791','http://127.0.0.1:18791','http://0.0.0.0:18791']);for(const entries of Object.values(os.networkInterfaces()||{})){for(const entry of entries||[]){if(!entry||entry.internal||entry.family!=='IPv4'||!entry.address)continue;a.add('http://' + entry.address + ':18791');}}c.tools=Object.assign({},c.tools,{profile:'full',exec:{host:'gateway',security:'full',ask:'off'}});c.gateway=Object.assign({},c.gateway,{port:18791,bind:'
|
|
2089
|
+
const patchCmd = `node -e \\"const fs=require('fs'),os=require('os'),p='/root/.openclaw/openclaw.json';if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));const a=new Set(['http://localhost:18791','http://127.0.0.1:18791','http://0.0.0.0:18791']);for(const entries of Object.values(os.networkInterfaces()||{})){for(const entry of entries||[]){if(!entry||entry.internal||entry.family!=='IPv4'||!entry.address)continue;a.add('http://' + entry.address + ':18791');}}c.tools=Object.assign({},c.tools,{profile:'full',exec:{host:'gateway',security:'full',ask:'off'}});c.gateway=Object.assign({},c.gateway,{port:18791,bind:'custom',customBindHost:'0.0.0.0',controlUi:Object.assign({},c.gateway?.controlUi,{allowedOrigins:Array.from(a).filter(Boolean)})});fs.writeFileSync(p,JSON.stringify(c,null,2));}\\" && `;
|
|
2089
2090
|
// Auto-approve device pairing after gateway starts (required since v2026.3.x)
|
|
2090
2091
|
const autoApproveCmd = '(while true; do sleep 5; openclaw devices approve --latest 2>/dev/null || true; done) & ';
|
|
2091
2092
|
const finalCmd = `CMD sh -c "${pluginInstallCmd}${patchCmd}${browserPrefix}${gatewayBridgePrefix}${autoApproveCmd}${gatewayCmd}"`;
|
|
@@ -2095,7 +2096,7 @@ model:
|
|
|
2095
2096
|
RUN apt-get update && apt-get install -y git curl${browserAptExtra} && rm -rf /var/lib/apt/lists/*
|
|
2096
2097
|
|
|
2097
2098
|
|
|
2098
|
-
ARG
|
|
2099
|
+
ARG OPENCLAW_VER="openclaw@2026.4.5"
|
|
2099
2100
|
RUN npm install -g openclaw@2026.4.5 ${openClawRuntimePackages}${skillLines}${browserInstallLines}
|
|
2100
2101
|
RUN node -e "const fs=require('fs');const path=require('path');const dir='/usr/local/lib/node_modules/openclaw/dist';const from='\\t\\t\\t\\t\\tonAgentRunStart: (runId) => {';const to='\\t\\t\\t\\t\\ttimeoutOverrideSeconds: Math.max(1, Math.ceil(timeoutMs / 1e3)),\\n\\t\\t\\t\\t\\tonAgentRunStart: (runId) => {';const files=fs.readdirSync(dir).filter(n=>/\\.js$/.test(n));let patched=0;for(const file of files){const p=path.join(dir,file);let s='';try{s=fs.readFileSync(p,'utf8');}catch{continue;}if(s.includes(to)||!s.includes(from))continue;s=s.replace(from,to);fs.writeFileSync(p,s);patched++;}if(!patched){process.exit(0);}"
|
|
2101
2102
|
WORKDIR /root/.openclaw
|
|
@@ -241,11 +241,12 @@ checks.push(() => expectMatch(
|
|
|
241
241
|
checks.push(() => expect(
|
|
242
242
|
cli.includes("a.add('http://' + entry.address + ':18791')")
|
|
243
243
|
&& cli.includes('allowedOrigins:Array.from(a).filter(Boolean)')
|
|
244
|
-
&& cli.includes("bind:'
|
|
245
|
-
&& cli.includes("
|
|
246
|
-
&& cli.includes("
|
|
244
|
+
&& cli.includes("bind:'custom',customBindHost:'0.0.0.0'")
|
|
245
|
+
&& !cli.includes("bind:'loopback'")
|
|
246
|
+
&& !cli.includes("delete c.gateway.customBindHost;")
|
|
247
|
+
&& !cli.includes("const gatewayBridge = 'socat TCP-LISTEN:18791")
|
|
247
248
|
&& !cli.includes("a.add(`http://${entry.address}:18791`)"),
|
|
248
|
-
'Docker CLI patch script must
|
|
249
|
+
'Docker CLI patch script must use bind:custom+customBindHost:0.0.0.0, skip socat gateway bridge, and avoid shell-expanding ${entry.address}'
|
|
249
250
|
));
|
|
250
251
|
|
|
251
252
|
checks.push(() => expectMatch(
|
|
@@ -361,11 +362,12 @@ checks.push(() => expectMatch(
|
|
|
361
362
|
checks.push(() => expect(
|
|
362
363
|
setup.includes("a.add('http://' + entry.address + ':18791')")
|
|
363
364
|
&& setup.includes('allowedOrigins:Array.from(a).filter(Boolean)')
|
|
364
|
-
&& setup.includes("bind:'
|
|
365
|
-
&& setup.includes("
|
|
366
|
-
&& setup.includes("
|
|
365
|
+
&& setup.includes("bind:'custom',customBindHost:'0.0.0.0'")
|
|
366
|
+
&& !setup.includes("bind:'loopback'")
|
|
367
|
+
&& !setup.includes("delete c.gateway.customBindHost;")
|
|
368
|
+
&& !setup.includes("const gatewayBridgePrefix = 'socat TCP-LISTEN:18791")
|
|
367
369
|
&& !setup.includes("a.add(\\`http://\\${entry.address}:18791\\`)"),
|
|
368
|
-
'Wizard Docker patch command must
|
|
370
|
+
'Wizard Docker patch command must use bind:custom+customBindHost:0.0.0.0, skip socat gateway bridge, and avoid shell-expanding ${entry.address}'
|
|
369
371
|
));
|
|
370
372
|
|
|
371
373
|
checks.push(() => expectMatch(
|