create-openclaw-bot 5.1.4 → 5.1.5
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 +8 -0
- package/CHANGELOG.vi.md +8 -0
- package/README.md +3 -3
- package/README.vi.md +3 -3
- package/cli.js +63 -26
- package/package.json +1 -1
- package/tests/smoke-cli-logic.mjs +1 -1
- package/tmp_diff.patch +114 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog (English)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [5.1.5] — 2026-04-06
|
|
5
|
+
|
|
6
|
+
### 🐞 Fix Native PM2 9Router Startup
|
|
7
|
+
|
|
8
|
+
- **Fix**: Replaced shell string execution (`execSync`) with strict array arguments (`execFileSync`) when starting 9Router and its background sync script via PM2 on native systems. This guarantees reliable process spawning across both Linux (VPS) and Windows environments without PM2 shell-parsing errors on quotes or path spaces.
|
|
9
|
+
- **Improved**: PM2 now explicitly runs the global `9router` binary via `--interpreter none` and the sync script via the current NodeJS runtime using `--interpreter process.execPath`.
|
|
10
|
+
|
|
11
|
+
|
|
4
12
|
## [5.1.4] — 2026-04-06
|
|
5
13
|
|
|
6
14
|
### 🐞 Fix CLI Startup BOM Error & Improve Docker Timeout Patch
|
package/CHANGELOG.vi.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog (Tiếng Việt)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [5.1.5] — 2026-04-06
|
|
5
|
+
|
|
6
|
+
### 🐞 Sửa lỗi PM2 khởi động 9Router trên Native
|
|
7
|
+
|
|
8
|
+
- **Fix**: Chuyển từ việc chạy chuỗi bash (`execSync`) sang truyền mảng tham số rõ ràng (`execFileSync`) khi khởi động 9Router và script đồng bộ (sync) qua PM2. Đảm bảo PM2 luôn chạy được ứng dụng ổn định trên cả Linux (VPS) và Windows mà không bị vướng lỗi phân tích cú pháp dấu ngoặc kép hay khoảng trắng trong đường dẫn.
|
|
9
|
+
- **Tối ưu**: PM2 giờ đây sẽ phân tách rạch ròi bằng cách gọi file thực thi `9router` với tham số `--interpreter none`, và luôn chạy sync script bằng đúng phiên bản NodeJS nội tại thông qua `--interpreter process.execPath`.
|
|
10
|
+
|
|
11
|
+
|
|
4
12
|
## [5.1.4] — 2026-04-06
|
|
5
13
|
|
|
6
14
|
### 🐞 Sửa lỗi BOM khởi động CLI & Tối ưu luồng vá Timeout trên Docker
|
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.1.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.5-0EA5E9?style=for-the-badge" alt="Version 5.1.5" /></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.1.
|
|
27
|
+
## 🆕 What's new in v5.1.5
|
|
28
28
|
|
|
29
29
|
- 💻 **OS-First Setup** — Step 1 is now choosing your OS (Windows, macOS, Ubuntu, VPS). All scripts, configs, and instructions are generated to match.
|
|
30
30
|
- 🧠 **Gemma 4 — 4 sizes** — `gemma4:e2b` (~4 GB), `gemma4:e4b` (~8 GB), `gemma4:26b` (~18 GB), `gemma4:31b` (~24 GB). Auto-pulled on first launch.
|
|
@@ -112,7 +112,7 @@ Run in your terminal → follow the interactive prompts → startup script is ge
|
|
|
112
112
|
2. Open this repo as your workspace
|
|
113
113
|
3. Paste into chat:
|
|
114
114
|
```
|
|
115
|
-
Read SETUP.md and set up OpenClaw v5.1.
|
|
115
|
+
Read SETUP.md and set up OpenClaw v5.1.5 for me.
|
|
116
116
|
My bot token is X. Use 9Router (no API key).
|
|
117
117
|
My project folder: <YOUR_PATH>
|
|
118
118
|
```
|
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.1.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.5-0EA5E9?style=for-the-badge" alt="Version 5.1.5" /></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.1.
|
|
27
|
+
## 🆕 Có gì mới trong v5.1.5
|
|
28
28
|
|
|
29
29
|
- 💻 **OS-First Setup** — Bước đầu tiên bây giờ là chọn hệ điều hành của bạn (Windows, macOS, Ubuntu, VPS). Toàn bộ script, cấu hình và hướng dẫn được tạo ra phù hợp với lựa chọn đó.
|
|
30
30
|
- 🧠 **Gemma 4 — 4 kích thước** — `gemma4:e2b` (~4 GB), `gemma4:e4b` (~8 GB), `gemma4:26b` (~18 GB), `gemma4:31b` (~24 GB). Tự pull về khi bot khởi động lần đầu.
|
|
@@ -112,7 +112,7 @@ Chạy lệnh trên trong Terminal → làm theo các prompt tương tác → sc
|
|
|
112
112
|
2. Mở repo này làm workspace
|
|
113
113
|
3. Paste vào chat:
|
|
114
114
|
```
|
|
115
|
-
Read SETUP.md and set up OpenClaw v5.1.
|
|
115
|
+
Read SETUP.md and set up OpenClaw v5.1.5 for me.
|
|
116
116
|
My bot token is X. Use 9Router (no API key).
|
|
117
117
|
My project folder: <THƯ_MỤC_CỦA_BẠN>
|
|
118
118
|
```
|
package/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import fs from 'fs-extra';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import os from 'os';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
-
import { spawn, execSync } from 'child_process';
|
|
8
|
+
import { spawn, execSync, execFileSync } from 'child_process';
|
|
9
9
|
const TELEGRAM_RELAY_PLUGIN_ID = 'openclaw-telegram-multibot-relay';
|
|
10
10
|
// Use plain npm package name — clawhub: protocol not supported in all OpenClaw versions
|
|
11
11
|
const TELEGRAM_RELAY_PLUGIN_SPEC = TELEGRAM_RELAY_PLUGIN_ID;
|
|
@@ -95,7 +95,7 @@ function quotePowerShellSingle(value) {
|
|
|
95
95
|
return `'${String(value).replace(/'/g, "''")}'`;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
function resolveWindowsCommand(command) {
|
|
98
|
+
function resolveWindowsCommand(command) {
|
|
99
99
|
try {
|
|
100
100
|
const output = execSync(`where.exe ${command}`, {
|
|
101
101
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
@@ -363,6 +363,23 @@ setTimeout(sync, 5000);
|
|
|
363
363
|
setInterval(sync, INTERVAL);`;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
+
function resolveCommandOnPath(command) {
|
|
367
|
+
if (process.platform === 'win32') {
|
|
368
|
+
return resolveWindowsCommand(command);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
try {
|
|
372
|
+
return execSync(`command -v ${command}`, {
|
|
373
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
374
|
+
encoding: 'utf8',
|
|
375
|
+
shell: true,
|
|
376
|
+
env: process.env
|
|
377
|
+
}).trim() || command;
|
|
378
|
+
} catch {
|
|
379
|
+
return command;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
366
383
|
function indentBlock(text, spaces) {
|
|
367
384
|
const prefix = ' '.repeat(spaces);
|
|
368
385
|
return String(text)
|
|
@@ -606,30 +623,50 @@ function runPm2Save({ projectDir, isVi }) {
|
|
|
606
623
|
}
|
|
607
624
|
}
|
|
608
625
|
|
|
609
|
-
function startNative9RouterPm2({ isVi, projectDir, appName, syncScriptPath }) {
|
|
610
|
-
const routerAppName = `${appName}-9router`;
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
626
|
+
function startNative9RouterPm2({ isVi, projectDir, appName, syncScriptPath }) {
|
|
627
|
+
const routerAppName = `${appName}-9router`;
|
|
628
|
+
const routerCommand = resolveCommandOnPath('9router');
|
|
629
|
+
execFileSync('pm2', [
|
|
630
|
+
'start',
|
|
631
|
+
routerCommand,
|
|
632
|
+
'--name',
|
|
633
|
+
routerAppName,
|
|
634
|
+
'--cwd',
|
|
635
|
+
projectDir.replace(/\\/g, '/'),
|
|
636
|
+
'--interpreter',
|
|
637
|
+
'none',
|
|
638
|
+
'--',
|
|
639
|
+
'-n',
|
|
640
|
+
'-t',
|
|
641
|
+
'-l',
|
|
642
|
+
'-H',
|
|
643
|
+
'0.0.0.0',
|
|
644
|
+
'-p',
|
|
645
|
+
'20128',
|
|
646
|
+
'--skip-update'
|
|
647
|
+
], {
|
|
648
|
+
cwd: projectDir,
|
|
649
|
+
stdio: 'inherit',
|
|
650
|
+
env: process.env
|
|
651
|
+
});
|
|
652
|
+
if (syncScriptPath) {
|
|
653
|
+
const syncAppName = `${appName}-9router-sync`;
|
|
654
|
+
execFileSync('pm2', [
|
|
655
|
+
'start',
|
|
656
|
+
syncScriptPath.replace(/\\/g, '/'),
|
|
657
|
+
'--name',
|
|
658
|
+
syncAppName,
|
|
659
|
+
'--cwd',
|
|
660
|
+
projectDir.replace(/\\/g, '/'),
|
|
661
|
+
'--interpreter',
|
|
662
|
+
process.execPath
|
|
663
|
+
], {
|
|
664
|
+
cwd: projectDir,
|
|
665
|
+
stdio: 'inherit',
|
|
666
|
+
env: process.env
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
runPm2Save({ projectDir, isVi });
|
|
633
670
|
console.log(chalk.green(`\n✅ ${isVi ? '9Router da duoc khoi dong qua PM2.' : '9Router is running via PM2.'}`));
|
|
634
671
|
console.log(chalk.gray(isVi ? ` Xem log: pm2 logs ${routerAppName}` : ` View logs: pm2 logs ${routerAppName}`));
|
|
635
672
|
}
|
package/package.json
CHANGED
|
@@ -195,7 +195,7 @@ checks.push(() => expectMatch(
|
|
|
195
195
|
|
|
196
196
|
checks.push(() => expectMatch(
|
|
197
197
|
cli,
|
|
198
|
-
/function startNative9RouterPm2\(\{ isVi, projectDir, appName, syncScriptPath \}\) \{[\s\S]*9router
|
|
198
|
+
/function startNative9RouterPm2\(\{ isVi, projectDir, appName, syncScriptPath \}\) \{[\s\S]*resolveCommandOnPath\('9router'\)[\s\S]*execFileSync\('pm2'[\s\S]*--interpreter'?,?[\s\S]*none[\s\S]*--skip-update[\s\S]*syncScriptPath\.replace\(\/\\\\\/g, '\/'\)[\s\S]*process\.execPath[\s\S]*runPm2Save\(\{ projectDir, isVi \}\)/s,
|
|
199
199
|
'VPS native 9Router flow must start a standalone 9Router dashboard on port 20128 via PM2'
|
|
200
200
|
));
|
|
201
201
|
|
package/tmp_diff.patch
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
diff --git a/cli.js b/cli.js
|
|
2
|
+
index e0bbb01..4d1b591 100644
|
|
3
|
+
--- a/cli.js
|
|
4
|
+
+++ b/cli.js
|
|
5
|
+
@@ -5,7 +5,7 @@ import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
-import { spawn, execSync } from 'child_process';
|
|
10
|
+
+import { spawn, execSync, execFileSync } from 'child_process';
|
|
11
|
+
const TELEGRAM_RELAY_PLUGIN_ID = 'openclaw-telegram-multibot-relay';
|
|
12
|
+
// Use plain npm package name ΓÇö clawhub: protocol not supported in all OpenClaw versions
|
|
13
|
+
const TELEGRAM_RELAY_PLUGIN_SPEC = TELEGRAM_RELAY_PLUGIN_ID;
|
|
14
|
+
@@ -363,6 +363,23 @@ setTimeout(sync, 5000);
|
|
15
|
+
setInterval(sync, INTERVAL);`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
+function resolveCommandOnPath(command) {
|
|
19
|
+
+ if (process.platform === 'win32') {
|
|
20
|
+
+ return resolveWindowsCommand(command);
|
|
21
|
+
+ }
|
|
22
|
+
+
|
|
23
|
+
+ try {
|
|
24
|
+
+ return execSync(`command -v ${command}`, {
|
|
25
|
+
+ stdio: ['ignore', 'pipe', 'ignore'],
|
|
26
|
+
+ encoding: 'utf8',
|
|
27
|
+
+ shell: true,
|
|
28
|
+
+ env: process.env
|
|
29
|
+
+ }).trim() || command;
|
|
30
|
+
+ } catch {
|
|
31
|
+
+ return command;
|
|
32
|
+
+ }
|
|
33
|
+
+}
|
|
34
|
+
+
|
|
35
|
+
function indentBlock(text, spaces) {
|
|
36
|
+
const prefix = ' '.repeat(spaces);
|
|
37
|
+
return String(text)
|
|
38
|
+
@@ -608,26 +625,46 @@ function runPm2Save({ projectDir, isVi }) {
|
|
39
|
+
|
|
40
|
+
function startNative9RouterPm2({ isVi, projectDir, appName, syncScriptPath }) {
|
|
41
|
+
const routerAppName = `${appName}-9router`;
|
|
42
|
+
- execSync(
|
|
43
|
+
- `pm2 start "9router -n -t -l -H 0.0.0.0 -p 20128 --skip-update" --name "${routerAppName}" --cwd "${projectDir.replace(/\\/g, '/')}"`,
|
|
44
|
+
- {
|
|
45
|
+
+ const routerCommand = resolveCommandOnPath('9router');
|
|
46
|
+
+ execFileSync('pm2', [
|
|
47
|
+
+ 'start',
|
|
48
|
+
+ routerCommand,
|
|
49
|
+
+ '--name',
|
|
50
|
+
+ routerAppName,
|
|
51
|
+
+ '--cwd',
|
|
52
|
+
+ projectDir.replace(/\\/g, '/'),
|
|
53
|
+
+ '--interpreter',
|
|
54
|
+
+ 'none',
|
|
55
|
+
+ '--',
|
|
56
|
+
+ '-n',
|
|
57
|
+
+ '-t',
|
|
58
|
+
+ '-l',
|
|
59
|
+
+ '-H',
|
|
60
|
+
+ '0.0.0.0',
|
|
61
|
+
+ '-p',
|
|
62
|
+
+ '20128',
|
|
63
|
+
+ '--skip-update'
|
|
64
|
+
+ ], {
|
|
65
|
+
+ cwd: projectDir,
|
|
66
|
+
+ stdio: 'inherit',
|
|
67
|
+
+ env: process.env
|
|
68
|
+
+ });
|
|
69
|
+
+ if (syncScriptPath) {
|
|
70
|
+
+ const syncAppName = `${appName}-9router-sync`;
|
|
71
|
+
+ execFileSync('pm2', [
|
|
72
|
+
+ 'start',
|
|
73
|
+
+ syncScriptPath.replace(/\\/g, '/'),
|
|
74
|
+
+ '--name',
|
|
75
|
+
+ syncAppName,
|
|
76
|
+
+ '--cwd',
|
|
77
|
+
+ projectDir.replace(/\\/g, '/'),
|
|
78
|
+
+ '--interpreter',
|
|
79
|
+
+ process.execPath
|
|
80
|
+
+ ], {
|
|
81
|
+
cwd: projectDir,
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
- shell: true,
|
|
84
|
+
env: process.env
|
|
85
|
+
- }
|
|
86
|
+
- );
|
|
87
|
+
- if (syncScriptPath) {
|
|
88
|
+
- const syncAppName = `${appName}-9router-sync`;
|
|
89
|
+
- execSync(
|
|
90
|
+
- `pm2 start "node ${syncScriptPath.replace(/\\/g, '/')}" --name "${syncAppName}" --cwd "${projectDir.replace(/\\/g, '/')}"`,
|
|
91
|
+
- {
|
|
92
|
+
- cwd: projectDir,
|
|
93
|
+
- stdio: 'inherit',
|
|
94
|
+
- shell: true,
|
|
95
|
+
- env: process.env
|
|
96
|
+
- }
|
|
97
|
+
- );
|
|
98
|
+
+ });
|
|
99
|
+
}
|
|
100
|
+
runPm2Save({ projectDir, isVi });
|
|
101
|
+
console.log(chalk.green(`\n✅ ${isVi ? '9Router da duoc khoi dong qua PM2.' : '9Router is running via PM2.'}`));
|
|
102
|
+
diff --git a/tests/smoke-cli-logic.mjs b/tests/smoke-cli-logic.mjs
|
|
103
|
+
index 3ab996c..7fd80f8 100644
|
|
104
|
+
--- a/tests/smoke-cli-logic.mjs
|
|
105
|
+
+++ b/tests/smoke-cli-logic.mjs
|
|
106
|
+
@@ -195,7 +195,7 @@ checks.push(() => expectMatch(
|
|
107
|
+
|
|
108
|
+
checks.push(() => expectMatch(
|
|
109
|
+
cli,
|
|
110
|
+
- /function startNative9RouterPm2\(\{ isVi, projectDir, appName, syncScriptPath \}\) \{[\s\S]*9router -n -t -l -H 0\.0\.0\.0 -p 20128 --skip-update[\s\S]*9router-sync[\s\S]*runPm2Save\(\{ projectDir, isVi \}\)/s,
|
|
111
|
+
+ /function startNative9RouterPm2\(\{ isVi, projectDir, appName, syncScriptPath \}\) \{[\s\S]*resolveCommandOnPath\('9router'\)[\s\S]*execFileSync\('pm2'[\s\S]*--interpreter'?,?[\s\S]*none[\s\S]*--skip-update[\s\S]*syncScriptPath\.replace\(\/\\\\\/g, '\/'\)[\s\S]*process\.execPath[\s\S]*runPm2Save\(\{ projectDir, isVi \}\)/s,
|
|
112
|
+
'VPS native 9Router flow must start a standalone 9Router dashboard on port 20128 via PM2'
|
|
113
|
+
));
|
|
114
|
+
|