create-openclaw-bot 5.0.6 → 5.0.8
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 +1 -1
- package/CHANGELOG.vi.md +1 -1
- package/README.md +3 -3
- package/README.vi.md +3 -3
- package/cli.js +106 -3
- package/docs/install-native.md +1 -1
- package/docs/install-native.vi.md +1 -1
- package/package.json +1 -1
- package/setup.js +13 -13
- package/tests/smoke-cli-logic.mjs +42 -0
package/CHANGELOG.md
CHANGED
package/CHANGELOG.vi.md
CHANGED
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.0.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.0.8-0EA5E9?style=for-the-badge" alt="Version 5.0.8" /></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.0.
|
|
27
|
+
## 🆕 What's new in v5.0.8
|
|
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.
|
|
@@ -111,7 +111,7 @@ Run in your terminal → follow the interactive prompts → startup script is ge
|
|
|
111
111
|
2. Open this repo as your workspace
|
|
112
112
|
3. Paste into chat:
|
|
113
113
|
```
|
|
114
|
-
Read SETUP.md and set up OpenClaw v5.0.
|
|
114
|
+
Read SETUP.md and set up OpenClaw v5.0.8 for me.
|
|
115
115
|
My bot token is X. Use 9Router (no API key).
|
|
116
116
|
My project folder: <YOUR_PATH>
|
|
117
117
|
```
|
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.0.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.0.8-0EA5E9?style=for-the-badge" alt="Version 5.0.8" /></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.0.
|
|
27
|
+
## 🆕 Có gì mới trong v5.0.8
|
|
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.
|
|
@@ -111,7 +111,7 @@ Chạy lệnh trên trong Terminal → làm theo các prompt tương tác → sc
|
|
|
111
111
|
2. Mở repo này làm workspace
|
|
112
112
|
3. Paste vào chat:
|
|
113
113
|
```
|
|
114
|
-
Read SETUP.md and set up OpenClaw v5.0.
|
|
114
|
+
Read SETUP.md and set up OpenClaw v5.0.8 for me.
|
|
115
115
|
My bot token is X. Use 9Router (no API key).
|
|
116
116
|
My project folder: <THƯ_MỤC_CỦA_BẠN>
|
|
117
117
|
```
|
package/cli.js
CHANGED
|
@@ -50,6 +50,15 @@ function isPm2Installed() {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function is9RouterInstalled() {
|
|
54
|
+
try {
|
|
55
|
+
execSync('9router --help', { stdio: 'ignore' });
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
function getUserNpmPrefixInfo() {
|
|
54
63
|
if (process.platform === 'win32') {
|
|
55
64
|
return null;
|
|
@@ -151,6 +160,70 @@ function installGlobalPackage(pkg, { isVi, osChoice, displayName }) {
|
|
|
151
160
|
return false;
|
|
152
161
|
}
|
|
153
162
|
|
|
163
|
+
function extractFirstHttpUrl(text) {
|
|
164
|
+
const match = String(text || '').match(/https?:\/\/[^\s"'`]+/);
|
|
165
|
+
return match ? match[0] : null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getTokenizedDashboardUrl(projectDir) {
|
|
169
|
+
try {
|
|
170
|
+
const output = execSync('openclaw dashboard', {
|
|
171
|
+
cwd: projectDir,
|
|
172
|
+
env: process.env,
|
|
173
|
+
encoding: 'utf8',
|
|
174
|
+
shell: true,
|
|
175
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
176
|
+
timeout: 15000
|
|
177
|
+
});
|
|
178
|
+
return extractFirstHttpUrl(output);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
const combined = `${error?.stdout || ''}\n${error?.stderr || ''}`;
|
|
181
|
+
return extractFirstHttpUrl(combined);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function printNativeDashboardAccessInfo({ isVi, providerKey, projectDir, gatewayPort = 18791 }) {
|
|
186
|
+
const dashboardUrl = `http://localhost:${gatewayPort}`;
|
|
187
|
+
const tokenizedUrl = getTokenizedDashboardUrl(projectDir);
|
|
188
|
+
|
|
189
|
+
console.log(chalk.yellow(`\n🧭 ${isVi ? 'Dashboard OpenClaw:' : 'OpenClaw Dashboard:'} ${dashboardUrl}`));
|
|
190
|
+
|
|
191
|
+
if (tokenizedUrl) {
|
|
192
|
+
console.log(chalk.green(isVi
|
|
193
|
+
? ` → Mở link đã kèm token: ${tokenizedUrl}`
|
|
194
|
+
: ` → Open the tokenized link directly: ${tokenizedUrl}`));
|
|
195
|
+
} else {
|
|
196
|
+
console.log(chalk.gray(isVi
|
|
197
|
+
? ' → Nếu dashboard đòi Gateway Token, chạy: openclaw dashboard'
|
|
198
|
+
: ' → If the dashboard asks for a Gateway Token, run: openclaw dashboard'));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (providerKey === '9router') {
|
|
202
|
+
console.log(chalk.yellow(`\n🔀 ${isVi ? '9Router Dashboard:' : '9Router Dashboard:'} http://localhost:20128/dashboard`));
|
|
203
|
+
console.log(chalk.gray(isVi
|
|
204
|
+
? ' → Mở dashboard 9Router → đăng nhập OAuth → kết nối provider miễn phí'
|
|
205
|
+
: ' → Open the 9Router dashboard → complete OAuth login → connect a free provider'));
|
|
206
|
+
console.log(chalk.gray(isVi
|
|
207
|
+
? ' → Sau khi login 9Router xong, bot sẽ tự dùng model smart-route qua http://localhost:20128/v1'
|
|
208
|
+
: ' → Once 9Router is logged in, the bot will use smart-route through http://localhost:20128/v1'));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function startNative9RouterPm2({ isVi, projectDir, appName }) {
|
|
213
|
+
const routerAppName = `${appName}-9router`;
|
|
214
|
+
execSync(
|
|
215
|
+
`pm2 start "9router -n -t -l -H 0.0.0.0 -p 20128 --skip-update" --name "${routerAppName}" --cwd "${projectDir.replace(/\\/g, '/')}" && pm2 save`,
|
|
216
|
+
{
|
|
217
|
+
cwd: projectDir,
|
|
218
|
+
stdio: 'inherit',
|
|
219
|
+
shell: true,
|
|
220
|
+
env: process.env
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
console.log(chalk.green(`\n✅ ${isVi ? '9Router da duoc khoi dong qua PM2.' : '9Router is running via PM2.'}`));
|
|
224
|
+
console.log(chalk.gray(isVi ? ` Xem log: pm2 logs ${routerAppName}` : ` View logs: pm2 logs ${routerAppName}`));
|
|
225
|
+
}
|
|
226
|
+
|
|
154
227
|
async function syncLocalConfigToHome(projectDir, isVi) {
|
|
155
228
|
const homedir = os.homedir();
|
|
156
229
|
const globalClawDir = path.join(homedir, '.openclaw');
|
|
@@ -778,7 +851,7 @@ async function main() {
|
|
|
778
851
|
'# Fix chat.send dropping resolved agent timeout into reply pipeline.',
|
|
779
852
|
'# Without this, Telegram/WebChat paths fall back to an internal 300s default even when',
|
|
780
853
|
'# agents.defaults.timeoutSeconds is higher in config.',
|
|
781
|
-
`RUN node -e "const fs=require('fs');const
|
|
854
|
+
`RUN node -e "const fs=require('fs');const path=require('path');const dir='/usr/local/lib/node_modules/openclaw/dist';const file=(fs.readdirSync(dir).find(n=>/^gateway-cli-.*\\.js$/.test(n))||'');if(!file){console.warn('gateway cli dist file not found; skipping timeout patch');process.exit(0);}const p=path.join(dir,file);let s=fs.readFileSync(p,'utf8');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) => {';if(s.includes(to)){process.exit(0);}if(!s.includes(from)){console.warn('chat.send patch anchor not found; skipping timeout patch');process.exit(0);}s=s.replace(from,to);fs.writeFileSync(p,s);"`,
|
|
782
855
|
'',
|
|
783
856
|
'WORKDIR /root/.openclaw',
|
|
784
857
|
'',
|
|
@@ -1190,7 +1263,7 @@ ${hasBrowserDesktop ? ` extra_hosts:
|
|
|
1190
1263
|
mode: 'merge',
|
|
1191
1264
|
providers: {
|
|
1192
1265
|
'9router': {
|
|
1193
|
-
baseUrl: 'http://9router:20128/v1',
|
|
1266
|
+
baseUrl: deployMode === 'native' ? 'http://localhost:20128/v1' : 'http://9router:20128/v1',
|
|
1194
1267
|
apiKey: 'sk-no-key',
|
|
1195
1268
|
api: 'openai-completions',
|
|
1196
1269
|
models: [
|
|
@@ -1436,7 +1509,7 @@ ${hasBrowserDesktop ? ` extra_hosts:
|
|
|
1436
1509
|
mode: 'merge',
|
|
1437
1510
|
providers: {
|
|
1438
1511
|
'9router': {
|
|
1439
|
-
baseUrl: 'http://9router:20128/v1',
|
|
1512
|
+
baseUrl: deployMode === 'native' ? 'http://localhost:20128/v1' : 'http://9router:20128/v1',
|
|
1440
1513
|
apiKey: 'sk-no-key',
|
|
1441
1514
|
api: 'openai-completions',
|
|
1442
1515
|
models: [
|
|
@@ -1823,6 +1896,16 @@ fi
|
|
|
1823
1896
|
console.log(chalk.green(isVi ? '✅ openclaw da cai xong!' : '✅ openclaw installed!'));
|
|
1824
1897
|
}
|
|
1825
1898
|
|
|
1899
|
+
if (providerKey === '9router' && !is9RouterInstalled()) {
|
|
1900
|
+
console.log(chalk.cyan(isVi
|
|
1901
|
+
? '\n📦 Dang cai 9Router binary (npm install -g 9router)...'
|
|
1902
|
+
: '\n📦 Installing 9Router binary (npm install -g 9router)...'));
|
|
1903
|
+
if (!installGlobalPackage('9router@latest', { isVi, osChoice, displayName: '9Router' })) {
|
|
1904
|
+
process.exit(1);
|
|
1905
|
+
}
|
|
1906
|
+
console.log(chalk.green(isVi ? '✅ 9Router da cai xong!' : '✅ 9Router installed!'));
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1826
1909
|
await syncLocalConfigToHome(projectDir, isVi);
|
|
1827
1910
|
|
|
1828
1911
|
if (isMultiBot && channelKey === 'telegram') {
|
|
@@ -1838,6 +1921,9 @@ fi
|
|
|
1838
1921
|
}
|
|
1839
1922
|
|
|
1840
1923
|
if (isMultiBot && channelKey === 'telegram') {
|
|
1924
|
+
if (providerKey === '9router') {
|
|
1925
|
+
startNative9RouterPm2({ isVi, projectDir, appName: botName || 'openclaw-multibot' });
|
|
1926
|
+
}
|
|
1841
1927
|
execSync('pm2 start ecosystem.config.js && pm2 save', {
|
|
1842
1928
|
cwd: projectDir,
|
|
1843
1929
|
stdio: 'inherit',
|
|
@@ -1845,8 +1931,12 @@ fi
|
|
|
1845
1931
|
});
|
|
1846
1932
|
console.log(chalk.green(`\n🎉 ${isVi ? 'Setup hoan tat! Multi-bot native dang chay qua PM2.' : 'Setup complete! Native multi-bot is running via PM2.'}`));
|
|
1847
1933
|
console.log(chalk.gray(isVi ? ` Xem log: pm2 logs ${botName || 'openclaw-multibot'}` : ` View logs: pm2 logs ${botName || 'openclaw-multibot'}`));
|
|
1934
|
+
printNativeDashboardAccessInfo({ isVi, providerKey, projectDir });
|
|
1848
1935
|
} else {
|
|
1849
1936
|
const appName = botName || 'openclaw';
|
|
1937
|
+
if (providerKey === '9router') {
|
|
1938
|
+
startNative9RouterPm2({ isVi, projectDir, appName });
|
|
1939
|
+
}
|
|
1850
1940
|
execSync(`pm2 start "openclaw gateway run" --name "${appName}" --cwd "${projectDir.replace(/\\/g, '/')}" && pm2 save`, {
|
|
1851
1941
|
cwd: projectDir,
|
|
1852
1942
|
stdio: 'inherit',
|
|
@@ -1854,8 +1944,21 @@ fi
|
|
|
1854
1944
|
});
|
|
1855
1945
|
console.log(chalk.green(`\n🎉 ${isVi ? 'Setup hoan tat! Bot native dang chay qua PM2.' : 'Setup complete! Native bot is running via PM2.'}`));
|
|
1856
1946
|
console.log(chalk.gray(isVi ? ` Xem log: pm2 logs ${appName}` : ` View logs: pm2 logs ${appName}`));
|
|
1947
|
+
printNativeDashboardAccessInfo({ isVi, providerKey, projectDir });
|
|
1857
1948
|
}
|
|
1858
1949
|
} else {
|
|
1950
|
+
if (providerKey === '9router') {
|
|
1951
|
+
console.log(chalk.yellow(`\n${isVi ? 'Khoi dong 9Router native (background)...' : 'Starting native 9Router (background)...'}`));
|
|
1952
|
+
spawn('9router', ['-n', '-t', '-l', '-H', '0.0.0.0', '-p', '20128', '--skip-update'], {
|
|
1953
|
+
cwd: projectDir,
|
|
1954
|
+
detached: true,
|
|
1955
|
+
stdio: 'ignore',
|
|
1956
|
+
shell: process.platform === 'win32'
|
|
1957
|
+
}).unref();
|
|
1958
|
+
console.log(chalk.gray(isVi
|
|
1959
|
+
? ' 9Router dashboard: http://localhost:20128/dashboard'
|
|
1960
|
+
: ' 9Router dashboard: http://localhost:20128/dashboard'));
|
|
1961
|
+
}
|
|
1859
1962
|
console.log(chalk.yellow(`\n${isVi ? 'Khoi dong native bot (foreground)...' : 'Starting native bot (foreground)...'}`));
|
|
1860
1963
|
const child = spawn('openclaw', ['gateway', 'run'], {
|
|
1861
1964
|
cwd: projectDir,
|
package/docs/install-native.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Native installation is designed for users who cannot or prefer not to use Docker. This includes deployments on Shared Hosting (cPanel), low-tier VPS environments, or Windows desktops for direct access.
|
|
4
4
|
|
|
5
|
-
OpenClaw v5.0.
|
|
5
|
+
OpenClaw v5.0.8+ natively supports deployment script generation for Windows, Linux, VPS, and Hosting environments.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Chế độ Native được thiết kế dành cho những ai không thể hoặc không muốn cài Docker. Chế độ này thường tối ưu cho Shared Hosting (cPanel), các gói VPS cấu hình rất thấp, hoặc cài trực tiếp trên máy Window để chạy cá nhân.
|
|
4
4
|
|
|
5
|
-
OpenClaw v5.0.
|
|
5
|
+
OpenClaw v5.0.8+ tự động sinh sẵn các script cài đặt dành riêng cho Windows, Linux, VPS và Hosting.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/package.json
CHANGED
package/setup.js
CHANGED
|
@@ -1815,7 +1815,7 @@ RUN apt-get update && apt-get install -y git curl${browserAptExtra} && rm -rf /v
|
|
|
1815
1815
|
|
|
1816
1816
|
ARG CACHEBUST=${Date.now()}
|
|
1817
1817
|
RUN npm install -g openclaw@latest${skillLines}${browserInstallLines}
|
|
1818
|
-
RUN node -e "const fs=require('fs');const
|
|
1818
|
+
RUN node -e "const fs=require('fs');const path=require('path');const dir='/usr/local/lib/node_modules/openclaw/dist';const file=(fs.readdirSync(dir).find(n=>/^gateway-cli-.*\\.js$/.test(n))||'');if(!file){console.warn('gateway cli dist file not found; skipping timeout patch');process.exit(0);}const p=path.join(dir,file);let s=fs.readFileSync(p,'utf8');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) => {';if(s.includes(to)){process.exit(0);}if(!s.includes(from)){console.warn('chat.send patch anchor not found; skipping timeout patch');process.exit(0);}s=s.replace(from,to);fs.writeFileSync(p,s);}"
|
|
1819
1819
|
WORKDIR /root/.openclaw
|
|
1820
1820
|
|
|
1821
1821
|
EXPOSE 18791
|
|
@@ -2836,18 +2836,18 @@ I am **${botName}**. When asked my name, I answer: _"I'm ${botName}"_.`;
|
|
|
2836
2836
|
const pluginCmd = allPlugins.length > 0 ? ('npm exec openclaw plugins install ' + allPlugins.join(' ')) : '';
|
|
2837
2837
|
|
|
2838
2838
|
// ─── Shared initializer (provider install) ───────────────────────────────
|
|
2839
|
-
function providerLines(arr, shell) {
|
|
2840
|
-
if (is9Router) {
|
|
2841
|
-
if (shell === 'bat') {
|
|
2842
|
-
arr.push('npm install -g 9router');
|
|
2843
|
-
arr.push('start "9Router" cmd /k "9router"');
|
|
2844
|
-
arr.push('timeout /t 5 /nobreak >nul');
|
|
2845
|
-
} else {
|
|
2846
|
-
arr.push('npm install -g 9router');
|
|
2847
|
-
arr.push('9router &');
|
|
2848
|
-
arr.push('sleep 3');
|
|
2849
|
-
}
|
|
2850
|
-
} else if (isOllama) {
|
|
2839
|
+
function providerLines(arr, shell) {
|
|
2840
|
+
if (is9Router) {
|
|
2841
|
+
if (shell === 'bat') {
|
|
2842
|
+
arr.push('npm install -g 9router');
|
|
2843
|
+
arr.push('start "9Router" cmd /k "9router -n -t -l -H 0.0.0.0 -p 20128 --skip-update"');
|
|
2844
|
+
arr.push('timeout /t 5 /nobreak >nul');
|
|
2845
|
+
} else {
|
|
2846
|
+
arr.push('npm install -g 9router');
|
|
2847
|
+
arr.push('nohup 9router -n -t -l -H 0.0.0.0 -p 20128 --skip-update >/tmp/9router.log 2>&1 &');
|
|
2848
|
+
arr.push('sleep 3');
|
|
2849
|
+
}
|
|
2850
|
+
} else if (isOllama) {
|
|
2851
2851
|
if (shell === 'bat') {
|
|
2852
2852
|
arr.push('where ollama >nul 2>&1 || (powershell -Command "Invoke-WebRequest -Uri https://ollama.com/download/OllamaSetup.exe -OutFile OllamaSetup.exe" && OllamaSetup.exe && del OllamaSetup.exe)');
|
|
2853
2853
|
arr.push('ollama pull ' + selectedModel);
|
|
@@ -50,6 +50,12 @@ checks.push(() => expectMatch(
|
|
|
50
50
|
'VPS native branch must auto-install PM2'
|
|
51
51
|
));
|
|
52
52
|
|
|
53
|
+
checks.push(() => expectMatch(
|
|
54
|
+
cli,
|
|
55
|
+
/if \(providerKey === '9router' && !is9RouterInstalled\(\)\) \{[\s\S]*installGlobalPackage\('9router@latest', \{ isVi, osChoice, displayName: '9Router' \}\)/,
|
|
56
|
+
'Native 9Router flow must auto-install 9Router'
|
|
57
|
+
));
|
|
58
|
+
|
|
53
59
|
checks.push(() => expectMatch(
|
|
54
60
|
cli,
|
|
55
61
|
/function ensureUserWritableGlobalNpm\(\{ isVi, osChoice \}\) \{[\s\S]*process\.env\.npm_config_prefix = npmInfo\.prefixDir[\s\S]*npm config set prefix "\$\{npmInfo\.prefixDir\.replace/s,
|
|
@@ -68,6 +74,24 @@ checks.push(() => expectMatch(
|
|
|
68
74
|
'Native single-bot VPS must start gateway through PM2'
|
|
69
75
|
));
|
|
70
76
|
|
|
77
|
+
checks.push(() => expectMatch(
|
|
78
|
+
cli,
|
|
79
|
+
/function printNativeDashboardAccessInfo\(\{ isVi, providerKey, projectDir, gatewayPort = 18791 \}\) \{[\s\S]*openclaw dashboard[\s\S]*9Router Dashboard:[\s\S]*localhost:20128\/dashboard/s,
|
|
80
|
+
'Native PM2 flow must expose dashboard access info and the tokenized dashboard command'
|
|
81
|
+
));
|
|
82
|
+
|
|
83
|
+
checks.push(() => expectMatch(
|
|
84
|
+
cli,
|
|
85
|
+
/baseUrl: deployMode === 'native' \? 'http:\/\/localhost:20128\/v1' : 'http:\/\/9router:20128\/v1'/,
|
|
86
|
+
'Native 9Router config must target localhost instead of the Docker hostname'
|
|
87
|
+
));
|
|
88
|
+
|
|
89
|
+
checks.push(() => expectMatch(
|
|
90
|
+
cli,
|
|
91
|
+
/function startNative9RouterPm2\(\{ isVi, projectDir, appName \}\) \{[\s\S]*9router -n -t -l -H 0\.0\.0\.0 -p 20128 --skip-update[\s\S]*pm2 save/s,
|
|
92
|
+
'VPS native 9Router flow must start a standalone 9Router dashboard on port 20128 via PM2'
|
|
93
|
+
));
|
|
94
|
+
|
|
71
95
|
checks.push(() => expectMatch(
|
|
72
96
|
cli,
|
|
73
97
|
/const child = spawn\('openclaw', \['gateway', 'run'\], \{/,
|
|
@@ -123,6 +147,24 @@ checks.push(() => expectMatch(
|
|
|
123
147
|
'VPS native script generation must install openclaw+pm2 and persist PM2 startup'
|
|
124
148
|
));
|
|
125
149
|
|
|
150
|
+
checks.push(() => expectMatch(
|
|
151
|
+
setup,
|
|
152
|
+
/function providerLines\(arr, shell\) \{[\s\S]*npm install -g 9router[\s\S]*9router -n -t -l -H 0\.0\.0\.0 -p 20128 --skip-update/s,
|
|
153
|
+
'Native script generation must install and start a standalone 9Router dashboard on port 20128'
|
|
154
|
+
));
|
|
155
|
+
|
|
156
|
+
checks.push(() => expectMatch(
|
|
157
|
+
cli,
|
|
158
|
+
/readdirSync\(dir\)\.find\(n=>\/\^gateway-cli-.*\\\\\.js\$\/\.test\(n\)\)[\s\S]*skipping timeout patch/,
|
|
159
|
+
'Dockerfile patching in CLI must resolve gateway-cli dist files dynamically instead of hardcoding one hash'
|
|
160
|
+
));
|
|
161
|
+
|
|
162
|
+
checks.push(() => expectMatch(
|
|
163
|
+
setup,
|
|
164
|
+
/readdirSync\(dir\)\.find\(n=>\/\^gateway-cli-.*\\\\\.js\$\/\.test\(n\)\)[\s\S]*skipping timeout patch/,
|
|
165
|
+
'Dockerfile patching in setup.js must resolve gateway-cli dist files dynamically instead of hardcoding one hash'
|
|
166
|
+
));
|
|
167
|
+
|
|
126
168
|
checks.push(() => expectMatch(
|
|
127
169
|
setup,
|
|
128
170
|
/else if \(state\.nativeOs === 'vps'\) \{[\s\S]*pm2 start --name openclaw-multibot -- sh -c "openclaw gateway run"[\s\S]*pm2 logs openclaw-multibot/s,
|