create-openclaw-bot 5.7.10 → 5.8.1
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/README.md +61 -219
- package/README.vi.md +63 -216
- package/dist/cli.js +92 -2777
- package/dist/legacy-cli.js +2812 -0
- package/dist/server/local-server.js +2568 -0
- package/dist/setup/data/header.js +80 -80
- package/dist/setup/data/index.js +0 -1
- package/dist/setup/data/plugins.js +8 -1
- package/dist/setup/data/skills.js +2 -10
- package/dist/setup/shared/bot-config-gen.js +469 -462
- package/dist/setup/shared/common-gen.js +313 -315
- package/dist/setup/shared/docker-gen.js +193 -124
- package/dist/setup/shared/install-gen.js +566 -566
- package/dist/setup/shared/workspace-gen.js +813 -525
- package/dist/setup.js +729 -499
- package/dist/web/app.js +1247 -0
- package/dist/web/bvvbank.jpg +0 -0
- package/dist/web/index.html +14 -0
- package/dist/web/momo.jpg +0 -0
- package/dist/web/openclaw-logo.png +0 -0
- package/dist/web/openclaw-logo.svg +1 -0
- package/dist/web/styles.css +1375 -0
- package/package.json +40 -39
|
@@ -1,566 +1,566 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
// install-gen.js — Build install/runtime artifacts (Chrome debug, uninstall, skill catalog)
|
|
3
|
-
// Workspace .md files are in workspace-gen.js (single source of truth).
|
|
4
|
-
(function (root) {
|
|
5
|
-
function buildSkillCatalogMarkdown(options = {}) {
|
|
6
|
-
const {
|
|
7
|
-
isVi = true,
|
|
8
|
-
selectedSkillIds = [],
|
|
9
|
-
skillsCatalog = [],
|
|
10
|
-
detail = 'full',
|
|
11
|
-
} = options;
|
|
12
|
-
|
|
13
|
-
const lines = selectedSkillIds.map((sid) => {
|
|
14
|
-
const skill = skillsCatalog.find((entry) => entry && (entry.id === sid || entry.value === sid));
|
|
15
|
-
if (!skill) return null;
|
|
16
|
-
const skillSlug = skill.slug ? ` (${skill.slug})` : '';
|
|
17
|
-
if (detail === 'compact') {
|
|
18
|
-
return `- **${skill.name}**${skillSlug}`;
|
|
19
|
-
}
|
|
20
|
-
return `- **${skill.name}**${skillSlug}: ${skill.desc || (isVi ? 'Skill da cai dat' : 'Installed skill')}`;
|
|
21
|
-
}).filter(Boolean);
|
|
22
|
-
|
|
23
|
-
if (lines.length > 0) return lines.join('\n');
|
|
24
|
-
return detail === 'compact'
|
|
25
|
-
? (isVi ? '- _(Chua co skill nao)_' : '- _(No skills installed)_')
|
|
26
|
-
: (isVi ? '- _(Chua co skill nao duoc cai)_' : '- _(No skills installed yet)_');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function buildChromeDebugBat() {
|
|
30
|
-
return `@echo off
|
|
31
|
-
echo ====== OpenClaw - Chrome Debug Mode ======
|
|
32
|
-
echo.
|
|
33
|
-
echo Dang tat Chrome cu (neu co)...
|
|
34
|
-
taskkill /F /IM chrome.exe >nul 2>&1
|
|
35
|
-
timeout /t 3 /nobreak >nul
|
|
36
|
-
echo Dang mo Chrome voi Debug Mode...
|
|
37
|
-
start "" "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ^
|
|
38
|
-
--remote-debugging-port=9222 ^
|
|
39
|
-
--remote-allow-origins=* ^
|
|
40
|
-
--user-data-dir="%TEMP%\\chrome-debug"
|
|
41
|
-
timeout /t 4 /nobreak >nul
|
|
42
|
-
powershell -Command "try { Invoke-WebRequest -Uri 'http://localhost:9222/json/version' -UseBasicParsing -TimeoutSec 5 | Out-Null; Write-Host 'OK! Chrome Debug Mode dang chay.' -ForegroundColor Green } catch { Write-Host 'LOI: Port 9222 chua mo.' -ForegroundColor Red }"
|
|
43
|
-
echo.
|
|
44
|
-
pause
|
|
45
|
-
`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function buildChromeDebugSh() {
|
|
49
|
-
return `#!/usr/bin/env bash
|
|
50
|
-
# ====== OpenClaw - Chrome Debug Mode (Mac/Linux) ======
|
|
51
|
-
set -e
|
|
52
|
-
echo "====== OpenClaw - Chrome Debug Mode ======"
|
|
53
|
-
echo ""
|
|
54
|
-
|
|
55
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
56
|
-
CHROME_BIN="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
57
|
-
[ ! -f "$CHROME_BIN" ] && CHROME_BIN="/Applications/Chromium.app/Contents/MacOS/Chromium"
|
|
58
|
-
[ ! -f "$CHROME_BIN" ] && CHROME_BIN="/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
|
|
59
|
-
else
|
|
60
|
-
CHROME_BIN="$(command -v google-chrome || command -v google-chrome-stable || command -v chromium-browser || command -v chromium || echo '')"
|
|
61
|
-
fi
|
|
62
|
-
[ -n "$CHROME_DEBUG_BIN" ] && CHROME_BIN="$CHROME_DEBUG_BIN"
|
|
63
|
-
|
|
64
|
-
if [ -z "$CHROME_BIN" ] || { [ ! -f "$CHROME_BIN" ] && [ ! -x "$CHROME_BIN" ]; }; then
|
|
65
|
-
echo -e "\\033[31mERROR: Chrome/Chromium not found.\\033[0m"
|
|
66
|
-
echo "Install Chrome or: export CHROME_DEBUG_BIN=/path/to/chrome"
|
|
67
|
-
exit 1
|
|
68
|
-
fi
|
|
69
|
-
|
|
70
|
-
echo "Using: $CHROME_BIN"
|
|
71
|
-
echo "Killing existing Chrome debug instances..."
|
|
72
|
-
pkill -f -- "--remote-debugging-port=9222" 2>/dev/null || true
|
|
73
|
-
sleep 2
|
|
74
|
-
|
|
75
|
-
TMP_DIR="\${TMPDIR:-/tmp}/chrome-debug-openclaw"
|
|
76
|
-
mkdir -p "$TMP_DIR"
|
|
77
|
-
|
|
78
|
-
echo "Starting Chrome in Debug Mode (port 9222)..."
|
|
79
|
-
"$CHROME_BIN" \\
|
|
80
|
-
--remote-debugging-port=9222 \\
|
|
81
|
-
--remote-allow-origins=* \\
|
|
82
|
-
--user-data-dir="$TMP_DIR" &
|
|
83
|
-
|
|
84
|
-
sleep 4
|
|
85
|
-
if curl -s http://localhost:9222/json/version > /dev/null 2>&1; then
|
|
86
|
-
echo -e "\\033[32mOK! Chrome Debug Mode is running on port 9222.\\033[0m"
|
|
87
|
-
else
|
|
88
|
-
echo -e "\\033[31mERROR: Port 9222 not responding.\\033[0m"
|
|
89
|
-
exit 1
|
|
90
|
-
fi
|
|
91
|
-
`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function buildUninstallArtifact(options = {}) {
|
|
95
|
-
const {
|
|
96
|
-
os = 'win',
|
|
97
|
-
isDocker = false,
|
|
98
|
-
projectDir = '.',
|
|
99
|
-
botName = 'openclaw',
|
|
100
|
-
} = options;
|
|
101
|
-
|
|
102
|
-
const absWin = String(projectDir).replace(/\//g, '\\');
|
|
103
|
-
const absUnix = String(projectDir).replace(/\\/g, '/');
|
|
104
|
-
const appName = String(botName || 'openclaw').toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
105
|
-
|
|
106
|
-
if (os === 'win' && !isDocker) {
|
|
107
|
-
return { name: 'uninstall-openclaw-win.bat', content: `@echo off\nsetlocal EnableExtensions\nchcp 65001 >nul\necho.\necho ============================================================\necho OpenClaw Uninstaller - Windows Native\necho Project: ${absWin}\necho ============================================================\necho.\necho [WARNING] This will:\necho 1. Kill openclaw and 9router background processes\necho 2. Uninstall global npm packages (openclaw, 9router)\necho 3. Delete the project folder and all its data\necho.\nset /p CONFIRM=Nhap YES de xac nhan xoa toan bo: \nif /i not "%CONFIRM%"=="YES" (\n echo Huy bo. Khong xoa gi ca.\n pause\n exit /b 0\n)\necho.\necho [1/4] Dang dung cac tien trinh openclaw va 9router...\nwmic process where "Name='node.exe' and CommandLine like '%%9router%%'" delete >nul 2>&1\nwmic process where "Name='cmd.exe' and CommandLine like '%%9router%%'" delete >nul 2>&1\nwmic process where "Name='node.exe' and CommandLine like '%%openclaw.mjs%%'" delete >nul 2>&1\ntimeout /t 2 /nobreak >nul\necho OK: Tien trinh da dung.\necho.\necho [2/4] Dang go cai npm packages toan cau...\nset "PATH=%APPDATA%\\\\npm;%PATH%"\ncall npm uninstall -g openclaw 9router grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api 2>nul\necho OK: npm packages da duoc go cai.\necho.\necho [3/4] Xoa thu muc project...\nset "TARGET=${absWin}"\nif exist "%TARGET%" (\n rd /s /q "%TARGET%"\n echo OK: Da xoa %TARGET%\n) else (\n echo INFO: Thu muc khong ton tai: %TARGET%\n)\necho.\necho [4/4] Xoa thu muc .9router trong Home (neu co)...\nif exist "%USERPROFILE%\\\\.9router" (\n set /p CLEAN_HOME=Xoa ca %USERPROFILE%\\\\.9router? [YES/no]: \n if /i "%CLEAN_HOME%"=="YES" rd /s /q "%USERPROFILE%\\\\.9router" >nul 2>&1\n)\necho.\necho ============================================================\necho Go cai hoan tat!\necho De cai lai: chay lai file setup hoac npx create-openclaw-bot\necho ============================================================\npause\nendlocal\n` };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (os === 'win' && isDocker) {
|
|
111
|
-
return { name: 'uninstall-openclaw-docker.bat', content: `@echo off\nsetlocal EnableExtensions\nchcp 65001 >nul\necho.\necho ============================================================\necho OpenClaw Uninstaller - Docker (Windows)\necho Project: ${absWin}\necho ============================================================\necho.\necho [WARNING] This will stop Docker containers and delete the project folder.\necho.\nset /p CONFIRM=Nhap YES de xac nhan xoa toan bo: \nif /i not "%CONFIRM%"=="YES" (\n echo Huy bo. Khong xoa gi ca.\n pause\n exit /b 0\n)\necho.\necho [1/2] Dang dung Docker containers...\ncd /d "${absWin}\\\\docker\\\\openclaw" 2>nul && (\n docker compose down --volumes --remove-orphans 2>nul || docker-compose down --volumes --remove-orphans 2>nul\n echo OK: Containers da dung.\n) || echo INFO: Khong tim thay docker compose.\necho.\necho [2/2] Xoa thu muc project...\ncd /d "%USERPROFILE%"\nif exist "${absWin}" (\n rd /s /q "${absWin}"\n echo OK: Da xoa ${absWin}\n)\necho.\necho ============================================================\necho Go cai hoan tat! De cai lai: npx create-openclaw-bot@latest\necho ============================================================\npause\nendlocal\n` };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (isDocker) {
|
|
115
|
-
return { name: 'uninstall-openclaw-docker.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\nDOCKER_DIR="$PROJECT_DIR/docker/openclaw"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - Docker"\necho " Project: $PROJECT_DIR"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/3] Stopping Docker containers and removing volumes..."\nif [ -d "$DOCKER_DIR" ] && command -v docker &>/dev/null; then\n cd "$DOCKER_DIR"\n docker compose down --volumes --remove-orphans 2>/dev/null || docker-compose down --volumes --remove-orphans 2>/dev/null || true\nfi\necho "[2/3] Removing project directory..."\n[ -d "$PROJECT_DIR" ] && rm -rf "$PROJECT_DIR" && echo " OK: Deleted $PROJECT_DIR" || echo " INFO: Not found."\necho "[3/3] Checking home-level .openclaw..."\nif [ -d "$HOME/.openclaw" ]; then\n read -rp "Delete $HOME/.openclaw? [YES/no]: " CLEAN\n [ "$CLEAN" = "YES" ] && rm -rf "$HOME/.openclaw" && echo " OK." || echo " Kept."\nfi\n` };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (os === 'vps') {
|
|
119
|
-
return { name: 'uninstall-openclaw-vps.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\nAPP_NAME="${appName}"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - VPS / Ubuntu Server"\necho " Project: $PROJECT_DIR"\necho " PM2 app: $APP_NAME"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/5] Stopping PM2 processes..."\nif command -v pm2 &>/dev/null; then\n pm2 delete "$APP_NAME" "$APP_NAME-9router" "$APP_NAME-9router-sync" openclaw openclaw-multibot 2>/dev/null || true\n pm2 save --force 2>/dev/null || true\nfi\necho "[2/5] Killing leftover processes on ports
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (os === 'linux' || os === 'linux-desktop' || os === 'macos') {
|
|
123
|
-
const label = os === 'macos' ? 'macOS' : 'Linux Desktop';
|
|
124
|
-
return { name: 'uninstall-openclaw.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - ${label} Native"\necho " Project: $PROJECT_DIR"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/4] Stopping openclaw and 9router processes..."\npkill -f "openclaw gateway run" 2>/dev/null || true\npkill -f "9router.*20128" 2>/dev/null || true\npkill -f "9router-smart-route" 2>/dev/null || true\npkill -f "$PROJECT_DIR" 2>/dev/null || true\nfor port in
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function buildCliUninstallArtifacts(options = {}) {
|
|
131
|
-
const { deployMode = 'native', osChoice = 'windows', projectDir = '.', botName = 'openclaw' } = options;
|
|
132
|
-
if (deployMode === 'docker') {
|
|
133
|
-
return [
|
|
134
|
-
buildUninstallArtifact({ os: 'linux', isDocker: true, projectDir, botName }),
|
|
135
|
-
buildUninstallArtifact({ os: 'win', isDocker: true, projectDir, botName }),
|
|
136
|
-
].filter(Boolean);
|
|
137
|
-
}
|
|
138
|
-
if (osChoice === 'windows') return [buildUninstallArtifact({ os: 'win', projectDir, botName })].filter(Boolean);
|
|
139
|
-
if (osChoice === 'vps') return [buildUninstallArtifact({ os: 'vps', projectDir, botName })].filter(Boolean);
|
|
140
|
-
if (osChoice === 'macos') return [buildUninstallArtifact({ os: 'macos', projectDir, botName })].filter(Boolean);
|
|
141
|
-
return [buildUninstallArtifact({ os: 'linux', projectDir, botName })].filter(Boolean);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function buildCliChromeDebugArtifacts() {
|
|
145
|
-
return [
|
|
146
|
-
{ name: 'start-chrome-debug.bat', content: buildChromeDebugBat() },
|
|
147
|
-
{ name: 'start-chrome-debug.sh', content: buildChromeDebugSh(), executable: true },
|
|
148
|
-
];
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function buildStartBotBat(opts = {}) {
|
|
152
|
-
const { projectDir = '.', openclawHome = '.openclaw', is9Router = false, isVi = true } = opts;
|
|
153
|
-
const L = [];
|
|
154
|
-
L.push('@echo off');
|
|
155
|
-
L.push('setlocal EnableExtensions');
|
|
156
|
-
L.push('chcp 65001 >nul');
|
|
157
|
-
L.push(`set "PROJECT_DIR=${projectDir}"`);
|
|
158
|
-
L.push(`set "OPENCLAW_HOME=${openclawHome}"`);
|
|
159
|
-
L.push(`set "DATA_DIR=${projectDir}\\.9router"`);
|
|
160
|
-
L.push('set "PATH=%APPDATA%\\npm;%PATH%"');
|
|
161
|
-
L.push('powershell -NoProfile -Command "Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force" >nul 2>&1');
|
|
162
|
-
L.push('echo.');
|
|
163
|
-
L.push(isVi ? 'echo ====== OpenClaw - Khoi dong lai bot ======' : 'echo ====== OpenClaw - Restart Bot ======');
|
|
164
|
-
L.push('echo.');
|
|
165
|
-
L.push(isVi ? 'echo [1] Dung process openclaw cu (neu co)...' : 'echo [1] Stopping existing openclaw process (if any)...');
|
|
166
|
-
L.push('call openclaw gateway stop >nul 2>&1');
|
|
167
|
-
L.push('timeout /t 2 /nobreak >nul');
|
|
168
|
-
if (is9Router) {
|
|
169
|
-
L.push('');
|
|
170
|
-
L.push(isVi ? 'echo [2] Dung 9Router cu va khoi dong lai...' : 'echo [2] Stopping old 9Router and restarting...');
|
|
171
|
-
L.push("wmic process where \"Name='node.exe' and CommandLine like '%%9router%%'\" delete >nul 2>&1");
|
|
172
|
-
L.push("wmic process where \"Name='cmd.exe' and CommandLine like '%%9router%%'\" delete >nul 2>&1");
|
|
173
|
-
L.push('timeout /t 2 /nobreak >nul');
|
|
174
|
-
L.push("echo $env:DATA_DIR = '%DATA_DIR%' > \"%TEMP%\\oc-start9r.ps1\"");
|
|
175
|
-
L.push("echo $b = Join-Path $env:APPDATA 'npm\\9router.cmd' >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
176
|
-
L.push("echo if ^(-not ^(Test-Path $b^)^) { $b = Join-Path $env:APPDATA 'npm\\9router' } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
177
|
-
L.push(`echo $patch = Join-Path '${projectDir}' '.openclaw\\patch-9router.js' >> "%TEMP%\\oc-start9r.ps1"`);
|
|
178
|
-
L.push("echo if ^(Test-Path $patch^) { ^& node $patch ^| Out-Null } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
179
|
-
L.push(`echo Start-Process 'cmd.exe' -WindowStyle Hidden -WorkingDirectory '${projectDir}' -ArgumentList ^('/c "' + $b + '" -n -H 0.0.0.0 -p 20128 --skip-update'^) >> "%TEMP%\\oc-start9r.ps1"`);
|
|
180
|
-
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-start9r.ps1"');
|
|
181
|
-
L.push('del "%TEMP%\\oc-start9r.ps1" >nul 2>&1');
|
|
182
|
-
L.push('timeout /t 5 /nobreak >nul');
|
|
183
|
-
L.push(isVi ? 'echo [OK] 9Router da khoi dong.' : 'echo [OK] 9Router started.');
|
|
184
|
-
L.push('');
|
|
185
|
-
L.push(isVi ? 'echo [2b] Khoi dong sync smart-route...' : 'echo [2b] Starting smart-route sync...');
|
|
186
|
-
L.push(`echo $env:DATA_DIR = '%DATA_DIR%' > "%TEMP%\\oc-syncsmart.ps1"`);
|
|
187
|
-
L.push(`echo $sync = Join-Path '${projectDir}' '.openclaw\\9router-smart-route-sync.js' >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
188
|
-
L.push(`echo if ^(Test-Path $sync^) { Start-Process 'node' -WindowStyle Hidden -ArgumentList $sync } >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
189
|
-
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-syncsmart.ps1"');
|
|
190
|
-
L.push('del "%TEMP%\\oc-syncsmart.ps1" >nul 2>&1');
|
|
191
|
-
}
|
|
192
|
-
L.push('');
|
|
193
|
-
L.push(isVi ? 'echo [3] Khoi dong OpenClaw Gateway...' : 'echo [3] Starting OpenClaw Gateway...');
|
|
194
|
-
L.push('set "GW_LAUNCHER=%TEMP%\\openclaw-gateway-start.bat"');
|
|
195
|
-
L.push('> "%GW_LAUNCHER%" echo @echo off');
|
|
196
|
-
L.push('>> "%GW_LAUNCHER%" echo title openclaw-gateway');
|
|
197
|
-
L.push('>> "%GW_LAUNCHER%" echo setlocal EnableExtensions');
|
|
198
|
-
L.push('>> "%GW_LAUNCHER%" echo chcp 65001 ^>nul');
|
|
199
|
-
L.push('>> "%GW_LAUNCHER%" echo cd /d "%PROJECT_DIR%"');
|
|
200
|
-
L.push('>> "%GW_LAUNCHER%" echo set "PROJECT_DIR=%PROJECT_DIR%"');
|
|
201
|
-
L.push('>> "%GW_LAUNCHER%" echo set "OPENCLAW_HOME=%OPENCLAW_HOME%"');
|
|
202
|
-
L.push('>> "%GW_LAUNCHER%" echo set "OPENCLAW_STATE_DIR=%OPENCLAW_HOME%"');
|
|
203
|
-
L.push('>> "%GW_LAUNCHER%" echo set "DATA_DIR=%DATA_DIR%"');
|
|
204
|
-
L.push('>> "%GW_LAUNCHER%" echo set "PATH=%APPDATA%\\npm;%%PATH%%"');
|
|
205
|
-
L.push('>> "%GW_LAUNCHER%" echo if exist ".env" for /f "usebackq eol=# tokens=1,* delims==" %%%%A in ^(".env"^) do set "%%%%A=%%%%B"');
|
|
206
|
-
L.push('>> "%GW_LAUNCHER%" echo echo ===== OpenClaw Gateway =====');
|
|
207
|
-
L.push('>> "%GW_LAUNCHER%" echo echo Project: %%PROJECT_DIR%%');
|
|
208
|
-
L.push('>> "%GW_LAUNCHER%" echo echo.');
|
|
209
|
-
L.push('>> "%GW_LAUNCHER%" echo if exist "%%APPDATA%%\\npm\\openclaw.cmd" ^(call "%%APPDATA%%\\npm\\openclaw.cmd" gateway run^) else ^(openclaw gateway run^)');
|
|
210
|
-
L.push('>> "%GW_LAUNCHER%" echo echo.');
|
|
211
|
-
L.push(isVi
|
|
212
|
-
? '>> "%GW_LAUNCHER%" echo echo OpenClaw Gateway da dung voi ma loi %%ERRORLEVEL%%.'
|
|
213
|
-
: '>> "%GW_LAUNCHER%" echo echo OpenClaw Gateway exited with code %%ERRORLEVEL%%.');
|
|
214
|
-
L.push('>> "%GW_LAUNCHER%" echo pause');
|
|
215
|
-
L.push('start "openclaw-gateway" cmd /k call "%GW_LAUNCHER%"');
|
|
216
|
-
L.push('timeout /t 3 /nobreak >nul');
|
|
217
|
-
L.push('echo.');
|
|
218
|
-
L.push(isVi ? 'echo [OK] OpenClaw Gateway da khoi dong trong cua so moi!' : 'echo [OK] OpenClaw Gateway started in a new window!');
|
|
219
|
-
L.push('echo.');
|
|
220
|
-
L.push('echo OpenClaw Dashboard: http://127.0.0.1:
|
|
221
|
-
if (is9Router) L.push('echo 9Router Dashboard: http://127.0.0.1:20128/dashboard');
|
|
222
|
-
L.push('echo.');
|
|
223
|
-
L.push(isVi ? 'echo Ban co the dong cua so nay.' : 'echo You may close this window.');
|
|
224
|
-
L.push('pause');
|
|
225
|
-
L.push('endlocal');
|
|
226
|
-
return L.join('\r\n');
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function buildStartBotSh(opts = {}) {
|
|
230
|
-
const {
|
|
231
|
-
projectDir = '.',
|
|
232
|
-
is9Router = false,
|
|
233
|
-
isVi = true,
|
|
234
|
-
osChoice = 'linux',
|
|
235
|
-
isMultiBot = false,
|
|
236
|
-
appName = 'openclaw',
|
|
237
|
-
logFile9r = '/tmp/9router.log',
|
|
238
|
-
logFileGw = '/tmp/openclaw-gw.log',
|
|
239
|
-
} = opts;
|
|
240
|
-
if (osChoice === 'vps') {
|
|
241
|
-
const L = [];
|
|
242
|
-
L.push('#!/bin/bash');
|
|
243
|
-
L.push('set -euo pipefail');
|
|
244
|
-
L.push(`PROJECT_DIR="${projectDir}"`);
|
|
245
|
-
L.push('cd "$PROJECT_DIR"');
|
|
246
|
-
L.push('export OPENCLAW_HOME="$PROJECT_DIR/.openclaw"');
|
|
247
|
-
L.push('export OPENCLAW_STATE_DIR="$PROJECT_DIR/.openclaw"');
|
|
248
|
-
L.push('export DATA_DIR="$PROJECT_DIR/.9router"');
|
|
249
|
-
L.push('if [ -f ".env" ]; then set -a; . ./.env; set +a; fi');
|
|
250
|
-
L.push(`APP_NAME="${appName}"`);
|
|
251
|
-
L.push('');
|
|
252
|
-
L.push('if ! command -v pm2 >/dev/null 2>&1; then');
|
|
253
|
-
L.push(isVi ? ' echo "ERROR: Khong tim thay PM2. Chay: npm install -g pm2"' : ' echo "ERROR: PM2 not found. Run: npm install -g pm2"');
|
|
254
|
-
L.push(' exit 1');
|
|
255
|
-
L.push('fi');
|
|
256
|
-
L.push('');
|
|
257
|
-
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot qua PM2 ======"' : 'echo "====== OpenClaw - Restart Bot via PM2 ======"');
|
|
258
|
-
L.push('echo ""');
|
|
259
|
-
if (is9Router) {
|
|
260
|
-
L.push(isVi ? 'echo "[1] Khoi dong lai 9Router qua PM2..."' : 'echo "[1] Restarting 9Router via PM2..."');
|
|
261
|
-
L.push('NINE_ROUTER_BIN="$(command -v 9router 2>/dev/null || true)"');
|
|
262
|
-
L.push('NODE_BIN="$(command -v node 2>/dev/null || true)"');
|
|
263
|
-
L.push('if [ -z "$NINE_ROUTER_BIN" ] || [ -z "$NODE_BIN" ]; then');
|
|
264
|
-
L.push(isVi ? ' echo "ERROR: Thieu node hoac 9router. Chay: npm install -g 9router"' : ' echo "ERROR: Missing node or 9router. Run: npm install -g 9router"');
|
|
265
|
-
L.push(' exit 1');
|
|
266
|
-
L.push('fi');
|
|
267
|
-
L.push('pm2 delete "$APP_NAME-9router" "$APP_NAME-9router-sync" >/dev/null 2>&1 || true');
|
|
268
|
-
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
269
|
-
L.push(' "$NODE_BIN" "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
270
|
-
L.push('fi');
|
|
271
|
-
L.push('PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" pm2 start "$NINE_ROUTER_BIN" --name "$APP_NAME-9router" --interpreter "$NODE_BIN" -- -n -H 0.0.0.0 -p 20128 --skip-update');
|
|
272
|
-
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
273
|
-
L.push(' pm2 start "$NODE_BIN" --name "$APP_NAME-9router-sync" -- "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js"');
|
|
274
|
-
L.push('fi');
|
|
275
|
-
} else {
|
|
276
|
-
L.push(isVi ? 'echo "[1] Khong dung 9Router cho project nay."' : 'echo "[1] This project does not use 9Router."');
|
|
277
|
-
}
|
|
278
|
-
L.push('');
|
|
279
|
-
if (isMultiBot) {
|
|
280
|
-
L.push(isVi ? 'echo "[2] Khoi dong lai multi-bot gateway qua PM2..."' : 'echo "[2] Restarting multi-bot gateway via PM2..."');
|
|
281
|
-
L.push('pm2 delete "$APP_NAME" >/dev/null 2>&1 || true');
|
|
282
|
-
L.push('pm2 start ecosystem.config.js');
|
|
283
|
-
} else {
|
|
284
|
-
L.push(isVi ? 'echo "[2] Khoi dong lai OpenClaw gateway qua PM2..."' : 'echo "[2] Restarting OpenClaw gateway via PM2..."');
|
|
285
|
-
L.push('pm2 delete "$APP_NAME" >/dev/null 2>&1 || true');
|
|
286
|
-
L.push('if [ -f "$PROJECT_DIR/.openclaw/start-gateway.sh" ]; then');
|
|
287
|
-
L.push(' pm2 start "$PROJECT_DIR/.openclaw/start-gateway.sh" --name "$APP_NAME" --interpreter bash');
|
|
288
|
-
L.push('else');
|
|
289
|
-
L.push(' OPENCLAW_HOME="$PROJECT_DIR/.openclaw" OPENCLAW_STATE_DIR="$PROJECT_DIR/.openclaw" pm2 start "$(command -v openclaw)" --name "$APP_NAME" --interpreter "$(command -v node)" -- gateway run');
|
|
290
|
-
L.push('fi');
|
|
291
|
-
}
|
|
292
|
-
L.push('pm2 save >/dev/null 2>&1 || true');
|
|
293
|
-
L.push('echo ""');
|
|
294
|
-
L.push('echo "OpenClaw Dashboard: http://127.0.0.1:
|
|
295
|
-
if (is9Router) L.push('echo "9Router Dashboard: http://127.0.0.1:20128/dashboard"');
|
|
296
|
-
L.push('echo ""');
|
|
297
|
-
L.push(isVi ? 'echo "Log gateway: pm2 logs $APP_NAME"' : 'echo "Gateway logs: pm2 logs $APP_NAME"');
|
|
298
|
-
if (is9Router) L.push(isVi ? 'echo "Log 9Router: pm2 logs $APP_NAME-9router"' : 'echo "9Router logs: pm2 logs $APP_NAME-9router"');
|
|
299
|
-
return L.join('\n');
|
|
300
|
-
}
|
|
301
|
-
const L = [];
|
|
302
|
-
L.push('#!/bin/bash');
|
|
303
|
-
L.push('set -euo pipefail');
|
|
304
|
-
L.push(`cd "${projectDir}"`);
|
|
305
|
-
L.push('export OPENCLAW_HOME="$PWD/.openclaw"');
|
|
306
|
-
L.push('export OPENCLAW_STATE_DIR="$PWD/.openclaw"');
|
|
307
|
-
L.push('export DATA_DIR="$PWD/.9router"');
|
|
308
|
-
L.push('if [ -f ".env" ]; then set -a; . ./.env; set +a; fi');
|
|
309
|
-
L.push('');
|
|
310
|
-
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot ======"' : 'echo "====== OpenClaw - Restart Bot ======"');
|
|
311
|
-
L.push('');
|
|
312
|
-
L.push(isVi ? 'echo "[1] Dung openclaw gateway cu (neu co)..."' : 'echo "[1] Stopping existing openclaw gateway (if any)..."');
|
|
313
|
-
L.push('openclaw gateway stop 2>/dev/null || true');
|
|
314
|
-
L.push('sleep 1');
|
|
315
|
-
if (is9Router) {
|
|
316
|
-
L.push('');
|
|
317
|
-
L.push(isVi ? 'echo "[2] Dung 9Router cu va khoi dong lai..."' : 'echo "[2] Stopping 9Router and restarting..."');
|
|
318
|
-
L.push('pkill -f "9router" 2>/dev/null || true');
|
|
319
|
-
L.push('sleep 1');
|
|
320
|
-
L.push('NINE_ROUTER_BIN="$(command -v 9router 2>/dev/null || true)"');
|
|
321
|
-
L.push('if [ -z "$NINE_ROUTER_BIN" ]; then');
|
|
322
|
-
L.push(isVi ? ' echo "ERROR: Khong tim thay 9router! Chay: npm install -g 9router"' : ' echo "ERROR: 9router not found! Run: npm install -g 9router"');
|
|
323
|
-
L.push(' exit 1');
|
|
324
|
-
L.push('fi');
|
|
325
|
-
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
326
|
-
L.push(' node "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
327
|
-
L.push('fi');
|
|
328
|
-
L.push(`nohup env PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" "$NINE_ROUTER_BIN" -n -H 0.0.0.0 -p 20128 --skip-update > "${logFile9r}" 2>&1 &`);
|
|
329
|
-
L.push('sleep 3');
|
|
330
|
-
L.push(isVi ? `echo "[OK] 9Router da khoi dong. Log: ${logFile9r}"` : `echo "[OK] 9Router started. Log: ${logFile9r}"`);
|
|
331
|
-
L.push('');
|
|
332
|
-
L.push(isVi ? 'echo "[2b] Khoi dong sync smart-route..."' : 'echo "[2b] Starting smart-route sync..."');
|
|
333
|
-
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
334
|
-
L.push(' nohup env DATA_DIR="$DATA_DIR" node "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" > /tmp/9router-sync.log 2>&1 &');
|
|
335
|
-
L.push('fi');
|
|
336
|
-
}
|
|
337
|
-
L.push('');
|
|
338
|
-
L.push(isVi ? 'echo "[3] Khoi dong OpenClaw Gateway..."' : 'echo "[3] Starting OpenClaw Gateway..."');
|
|
339
|
-
L.push(`nohup openclaw gateway run > "${logFileGw}" 2>&1 &`);
|
|
340
|
-
L.push('GW_PID=$!');
|
|
341
|
-
L.push('sleep 2');
|
|
342
|
-
L.push(isVi ? `echo "[OK] Gateway khoi dong (PID $GW_PID). Log: ${logFileGw}"` : `echo "[OK] Gateway started (PID $GW_PID). Log: ${logFileGw}"`);
|
|
343
|
-
L.push('');
|
|
344
|
-
L.push('echo ""');
|
|
345
|
-
L.push('echo "OpenClaw Dashboard: http://127.0.0.1:
|
|
346
|
-
if (is9Router) L.push('echo "9Router Dashboard: http://127.0.0.1:20128/dashboard"');
|
|
347
|
-
L.push('echo ""');
|
|
348
|
-
L.push(isVi ? 'echo "Bot dang chay background. Dung: openclaw gateway stop"' : 'echo "Bot running in background. Stop: openclaw gateway stop"');
|
|
349
|
-
return L.join('\n');
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function buildCliStartBotArtifacts(options = {}) {
|
|
353
|
-
return [
|
|
354
|
-
{
|
|
355
|
-
name: 'start-bot.bat',
|
|
356
|
-
content: buildStartBotBat(options),
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
name: 'start-bot.sh',
|
|
360
|
-
content: buildStartBotSh(options),
|
|
361
|
-
executable: true,
|
|
362
|
-
},
|
|
363
|
-
];
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
function buildUpgradePs1() {
|
|
368
|
-
return [
|
|
369
|
-
"# OpenClaw Upgrade Script — Windows (PowerShell)",
|
|
370
|
-
"# Cach dung:",
|
|
371
|
-
"# Nhan dup upgrade.ps1 hoac: .\\upgrade.ps1",
|
|
372
|
-
"# irm https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.ps1 | iex",
|
|
373
|
-
"# Chi danh cho Windows. Linux/macOS/Ubuntu: dung upgrade.sh",
|
|
374
|
-
"",
|
|
375
|
-
"$ErrorActionPreference = \"Stop\"",
|
|
376
|
-
"",
|
|
377
|
-
"# ── Version ──────────────────────────────────────────────────────────────────",
|
|
378
|
-
"$VER_STR = \"\"",
|
|
379
|
-
"try {",
|
|
380
|
-
" if (Test-Path \"package.json\") {",
|
|
381
|
-
" $pkg = Get-Content \"package.json\" -Raw | ConvertFrom-Json",
|
|
382
|
-
" if ($pkg.version) { $VER_STR = \" v$($pkg.version)\" }",
|
|
383
|
-
" }",
|
|
384
|
-
"} catch {}",
|
|
385
|
-
"",
|
|
386
|
-
"# ── Banner: LOGO + BOX ───────────────────────────────────────────────────────",
|
|
387
|
-
"Write-Host \"\"",
|
|
388
|
-
"$logo = @(",
|
|
389
|
-
" '████████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ███╗██╗███╗ ██╗██╗ ██╗██╗ ██╗ ██████╗ ██╗ ███████╗',",
|
|
390
|
-
" '╚══██╔══╝██║ ██║██╔══██╗████╗ ██║████╗ ████║██║████╗ ██║██║ ██║██║ ██║██╔═══██╗██║ ██╔════╝',",
|
|
391
|
-
" ' ██║ ██║ ██║███████║██╔██╗ ██║██╔████╔██║██║██╔██╗ ██║███████║███████║██║ ██║██║ █████╗ ',",
|
|
392
|
-
" ' ██║ ██║ ██║██╔══██║██║╚██╗██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║██╔══██║██║ ██║██║ ██╔══╝ ',",
|
|
393
|
-
" ' ██║ ╚██████╔╝██║ ██║██║ ╚████║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║██║ ██║╚██████╔╝███████╗███████╗',",
|
|
394
|
-
" ' ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝'",
|
|
395
|
-
")",
|
|
396
|
-
"foreach ($l in $logo) { Write-Host $l -ForegroundColor Red }",
|
|
397
|
-
"Write-Host \"\"",
|
|
398
|
-
"",
|
|
399
|
-
"# Box — node render (handles emoji visual width correctly on all terminals)",
|
|
400
|
-
"$env:L1 = \" 🦞 OpenClaw Setup$VER_STR | Upgrade Script\"",
|
|
401
|
-
"$env:L2 = \" Windows (PowerShell)\"",
|
|
402
|
-
"node -e @\"\nconst RED='\\x1b[0;31m',NC='\\x1b[0m';\nfunction vw(s){let w=0;for(const c of[...s]){const cp=c.codePointAt(0);w+=(cp>=0x1F000&&cp<=0x1FFFF?2:1);}return w;}\nconst L1=process.env.L1,L2=process.env.L2;\nconst INNER=Math.max(vw(L1),vw(L2))+2;\nconst D='─'.repeat(INNER);const pad=s=>' '.repeat(Math.max(0,INNER-vw(s)));\nconsole.log(RED+'╭'+D+'╮'+NC);\nconsole.log(RED+'│'+NC+L1+pad(L1)+RED+'│'+NC);\nconsole.log(RED+'│'+NC+L2+pad(L2)+RED+'│'+NC);\nconsole.log(RED+'╰'+D+'╯'+NC);\n\"@",
|
|
403
|
-
"Write-Host \"\"",
|
|
404
|
-
"",
|
|
405
|
-
"# ── 1. Kiem tra Node.js ──────────────────────────────────────────────────────",
|
|
406
|
-
"if (-not (Get-Command node -ErrorAction SilentlyContinue)) {",
|
|
407
|
-
" Write-Host \" ❌ Khong tim thay Node.js.\" -ForegroundColor Red",
|
|
408
|
-
" Write-Host \" Tai LTS: https://nodejs.org/\" -ForegroundColor Yellow",
|
|
409
|
-
" Read-Host \"Nhan Enter de dong\"; exit 1",
|
|
410
|
-
"}",
|
|
411
|
-
"$nodeVer = node -e \"process.stdout.write(process.version)\"",
|
|
412
|
-
"Write-Host \" ✅ Node.js $nodeVer\" -ForegroundColor Green",
|
|
413
|
-
"",
|
|
414
|
-
"# ── 2. Xac dinh thu muc project ──────────────────────────────────────────────",
|
|
415
|
-
"$ScriptDir = $PSScriptRoot",
|
|
416
|
-
"if (-not $ScriptDir -or $ScriptDir -eq \"\") {",
|
|
417
|
-
" $ProjectDir = (Get-Location).Path",
|
|
418
|
-
"} elseif ((Test-Path (Join-Path $ScriptDir \".openclaw\")) -or (Test-Path (Join-Path $ScriptDir \"docker\"))) {",
|
|
419
|
-
" $ProjectDir = $ScriptDir",
|
|
420
|
-
"} else {",
|
|
421
|
-
" $ProjectDir = (Get-Location).Path",
|
|
422
|
-
"}",
|
|
423
|
-
"Write-Host \" 📁 Project: $ProjectDir\" -ForegroundColor DarkGray",
|
|
424
|
-
"Write-Host \"\"",
|
|
425
|
-
"Set-Location $ProjectDir",
|
|
426
|
-
"",
|
|
427
|
-
"# ── 3. Chay upgrade ──────────────────────────────────────────────────────────",
|
|
428
|
-
"Write-Host \" 🔄 Dang lay CLI moi nhat va chay upgrade...\" -ForegroundColor Cyan",
|
|
429
|
-
"Write-Host \" npx luon tai create-openclaw-bot@latest — khong can cap nhat tay\" -ForegroundColor DarkGray",
|
|
430
|
-
"Write-Host \"\"",
|
|
431
|
-
"",
|
|
432
|
-
"try {",
|
|
433
|
-
" & npx create-openclaw-bot@latest upgrade",
|
|
434
|
-
" $exitCode = $LASTEXITCODE",
|
|
435
|
-
"} catch {",
|
|
436
|
-
" Write-Host \" ❌ Loi: $_\" -ForegroundColor Red",
|
|
437
|
-
" Read-Host \"Nhan Enter de dong\"; exit 1",
|
|
438
|
-
"}",
|
|
439
|
-
"",
|
|
440
|
-
"Write-Host \"\"",
|
|
441
|
-
"if ($exitCode -eq 0) {",
|
|
442
|
-
" Write-Host \" 🎉 Upgrade hoan tat!\" -ForegroundColor Green",
|
|
443
|
-
" Write-Host \" Dashboard: http://localhost:
|
|
444
|
-
"} else {",
|
|
445
|
-
" Write-Host \" ⚠️ Ma loi: $exitCode — xem log o tren.\" -ForegroundColor Yellow",
|
|
446
|
-
"}",
|
|
447
|
-
"Write-Host \"\"",
|
|
448
|
-
"Read-Host \"Nhan Enter de dong\"",
|
|
449
|
-
""
|
|
450
|
-
].join('\r\n');
|
|
451
|
-
}
|
|
452
|
-
function buildUpgradeSh() {
|
|
453
|
-
return [
|
|
454
|
-
"#!/bin/bash",
|
|
455
|
-
"# OpenClaw Upgrade Script — Linux / macOS / Ubuntu",
|
|
456
|
-
"# Cach dung:",
|
|
457
|
-
"# bash upgrade.sh",
|
|
458
|
-
"# curl -fsSL https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.sh | bash",
|
|
459
|
-
"# wget -qO- https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.sh | bash",
|
|
460
|
-
"",
|
|
461
|
-
"set -e",
|
|
462
|
-
"",
|
|
463
|
-
"RED='\\033[0;31m'",
|
|
464
|
-
"GREEN='\\033[0;32m'",
|
|
465
|
-
"CYAN='\\033[0;36m'",
|
|
466
|
-
"YELLOW='\\033[1;33m'",
|
|
467
|
-
"GRAY='\\033[0;90m'",
|
|
468
|
-
"NC='\\033[0m'",
|
|
469
|
-
"",
|
|
470
|
-
"# ── Version ──────────────────────────────────────────────────────────────────",
|
|
471
|
-
"VER=\"\"",
|
|
472
|
-
"if [ -f \"package.json\" ] && command -v node &>/dev/null; then",
|
|
473
|
-
" VER=$(node -p \"try{JSON.parse(require('fs').readFileSync('package.json','utf8')).version}catch(e){''}\" 2>/dev/null || true)",
|
|
474
|
-
"fi",
|
|
475
|
-
"[ -n \"$VER\" ] && VER_STR=\" v${VER}\" || VER_STR=\"\"",
|
|
476
|
-
"",
|
|
477
|
-
"# ── Banner: LOGO + BOX ───────────────────────────────────────────────────────",
|
|
478
|
-
"echo -e \"${RED}\"",
|
|
479
|
-
"echo '████████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ███╗██╗███╗ ██╗██╗ ██╗██╗ ██╗ ██████╗ ██╗ ███████╗'",
|
|
480
|
-
"echo '╚══██╔══╝██║ ██║██╔══██╗████╗ ██║████╗ ████║██║████╗ ██║██║ ██║██║ ██║██╔═══██╗██║ ██╔════╝'",
|
|
481
|
-
"echo ' ██║ ██║ ██║███████║██╔██╗ ██║██╔████╔██║██║██╔██╗ ██║███████║███████║██║ ██║██║ █████╗ '",
|
|
482
|
-
"echo ' ██║ ██║ ██║██╔══██║██║╚██╗██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║██╔══██║██║ ██║██║ ██╔══╝ '",
|
|
483
|
-
"echo ' ██║ ╚██████╔╝██║ ██║██║ ╚████║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║██║ ██║╚██████╔╝███████╗███████╗'",
|
|
484
|
-
"echo ' ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝'",
|
|
485
|
-
"echo -e \"${NC}\"",
|
|
486
|
-
"",
|
|
487
|
-
"# Box — node render (handles emoji visual width correctly on all terminals)",
|
|
488
|
-
"L1=\" 🦞 OpenClaw Setup${VER_STR} | Upgrade Script\"",
|
|
489
|
-
"L2=\" Linux / macOS / Ubuntu\"",
|
|
490
|
-
"L1=\"$L1\" L2=\"$L2\" node -e \"\nconst RED='\\x1b[0;31m',NC='\\x1b[0m';\nfunction vw(s){let w=0;for(const c of[...s]){const cp=c.codePointAt(0);w+=(cp>=0x1F000&&cp<=0x1FFFF?2:1);}return w;}\nconst L1=process.env.L1,L2=process.env.L2;\nconst INNER=Math.max(vw(L1),vw(L2))+2;\nconst D='─'.repeat(INNER);const pad=s=>' '.repeat(Math.max(0,INNER-vw(s)));\nconsole.log(RED+'╭'+D+'╮'+NC);\nconsole.log(RED+'│'+NC+L1+pad(L1)+RED+'│'+NC);\nconsole.log(RED+'│'+NC+L2+pad(L2)+RED+'│'+NC);\nconsole.log(RED+'╰'+D+'╯'+NC);\n\"",
|
|
491
|
-
"echo \"\"",
|
|
492
|
-
"",
|
|
493
|
-
"# ── 1. Kiem tra Node.js ──────────────────────────────────────────────────────",
|
|
494
|
-
"if ! command -v node &> /dev/null; then",
|
|
495
|
-
" echo -e \"${RED} ❌ Khong tim thay Node.js.${NC}\"",
|
|
496
|
-
" echo -e \"${YELLOW} Cai dat: https://nodejs.org/${NC}\"",
|
|
497
|
-
" echo \"\"",
|
|
498
|
-
" echo -e \"${GRAY} Ubuntu/Debian:${NC}\"",
|
|
499
|
-
" echo -e \"${GRAY} curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -${NC}\"",
|
|
500
|
-
" echo -e \"${GRAY} sudo apt-get install -y nodejs${NC}\"",
|
|
501
|
-
" exit 1",
|
|
502
|
-
"fi",
|
|
503
|
-
"NODE_VER=$(node -e \"process.stdout.write(process.version)\")",
|
|
504
|
-
"echo -e \"${GREEN} ✅ Node.js ${NODE_VER}${NC}\"",
|
|
505
|
-
"",
|
|
506
|
-
"# ── 2. Xac dinh thu muc project ──────────────────────────────────────────────",
|
|
507
|
-
"if [[ \"${BASH_SOURCE[0]}\" == \"$0\" ]]; then",
|
|
508
|
-
" SCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"",
|
|
509
|
-
" if [ -d \"$SCRIPT_DIR/.openclaw\" ] || [ -d \"$SCRIPT_DIR/docker\" ]; then",
|
|
510
|
-
" PROJECT_DIR=\"$SCRIPT_DIR\"",
|
|
511
|
-
" else",
|
|
512
|
-
" PROJECT_DIR=\"$PWD\"",
|
|
513
|
-
" fi",
|
|
514
|
-
"else",
|
|
515
|
-
" PROJECT_DIR=\"$PWD\"",
|
|
516
|
-
"fi",
|
|
517
|
-
"echo -e \"${GRAY} 📁 Project: $PROJECT_DIR${NC}\"",
|
|
518
|
-
"echo \"\"",
|
|
519
|
-
"cd \"$PROJECT_DIR\"",
|
|
520
|
-
"",
|
|
521
|
-
"# ── 3. Chay upgrade ──────────────────────────────────────────────────────────",
|
|
522
|
-
"echo -e \"${CYAN} 🔄 Dang lay CLI moi nhat va chay upgrade...${NC}\"",
|
|
523
|
-
"echo -e \"${GRAY} npx luon tai create-openclaw-bot@latest — khong can cap nhat tay${NC}\"",
|
|
524
|
-
"echo \"\"",
|
|
525
|
-
"",
|
|
526
|
-
"npx create-openclaw-bot@latest upgrade",
|
|
527
|
-
"EXIT_CODE=$?",
|
|
528
|
-
"",
|
|
529
|
-
"echo \"\"",
|
|
530
|
-
"if [ $EXIT_CODE -eq 0 ]; then",
|
|
531
|
-
" echo -e \"${GREEN} 🎉 Upgrade hoan tat!${NC}\"",
|
|
532
|
-
" echo -e \"${CYAN} Dashboard: http://localhost:
|
|
533
|
-
"else",
|
|
534
|
-
" echo -e \"${YELLOW} ⚠️ Ma loi: $EXIT_CODE — xem log o tren.${NC}\"",
|
|
535
|
-
"fi",
|
|
536
|
-
"echo \"\"",
|
|
537
|
-
""
|
|
538
|
-
].join('\n');
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
function buildCliUpgradeArtifacts() {
|
|
542
|
-
return [
|
|
543
|
-
{ name: 'upgrade.ps1', content: buildUpgradePs1() },
|
|
544
|
-
{ name: 'upgrade.sh', content: buildUpgradeSh(), executable: true },
|
|
545
|
-
];
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
root.__openclawInstall = {
|
|
549
|
-
buildSkillCatalogMarkdown,
|
|
550
|
-
buildChromeDebugBat,
|
|
551
|
-
buildChromeDebugSh,
|
|
552
|
-
buildCliChromeDebugArtifacts,
|
|
553
|
-
buildUninstallArtifact,
|
|
554
|
-
buildCliUninstallArtifacts,
|
|
555
|
-
buildStartBotBat,
|
|
556
|
-
buildStartBotSh,
|
|
557
|
-
buildCliStartBotArtifacts,
|
|
558
|
-
buildUpgradePs1,
|
|
559
|
-
buildUpgradeSh,
|
|
560
|
-
buildCliUpgradeArtifacts,
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
})(typeof globalThis !== 'undefined' ? globalThis : {});
|
|
564
|
-
if (typeof exports !== 'undefined' && typeof globalThis !== 'undefined' && globalThis.__openclawInstall) {
|
|
565
|
-
Object.assign(exports, globalThis.__openclawInstall);
|
|
566
|
-
}
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// install-gen.js — Build install/runtime artifacts (Chrome debug, uninstall, skill catalog)
|
|
3
|
+
// Workspace .md files are in workspace-gen.js (single source of truth).
|
|
4
|
+
(function (root) {
|
|
5
|
+
function buildSkillCatalogMarkdown(options = {}) {
|
|
6
|
+
const {
|
|
7
|
+
isVi = true,
|
|
8
|
+
selectedSkillIds = [],
|
|
9
|
+
skillsCatalog = [],
|
|
10
|
+
detail = 'full',
|
|
11
|
+
} = options;
|
|
12
|
+
|
|
13
|
+
const lines = selectedSkillIds.map((sid) => {
|
|
14
|
+
const skill = skillsCatalog.find((entry) => entry && (entry.id === sid || entry.value === sid));
|
|
15
|
+
if (!skill) return null;
|
|
16
|
+
const skillSlug = skill.slug ? ` (${skill.slug})` : '';
|
|
17
|
+
if (detail === 'compact') {
|
|
18
|
+
return `- **${skill.name}**${skillSlug}`;
|
|
19
|
+
}
|
|
20
|
+
return `- **${skill.name}**${skillSlug}: ${skill.desc || (isVi ? 'Skill da cai dat' : 'Installed skill')}`;
|
|
21
|
+
}).filter(Boolean);
|
|
22
|
+
|
|
23
|
+
if (lines.length > 0) return lines.join('\n');
|
|
24
|
+
return detail === 'compact'
|
|
25
|
+
? (isVi ? '- _(Chua co skill nao)_' : '- _(No skills installed)_')
|
|
26
|
+
: (isVi ? '- _(Chua co skill nao duoc cai)_' : '- _(No skills installed yet)_');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function buildChromeDebugBat() {
|
|
30
|
+
return `@echo off
|
|
31
|
+
echo ====== OpenClaw - Chrome Debug Mode ======
|
|
32
|
+
echo.
|
|
33
|
+
echo Dang tat Chrome cu (neu co)...
|
|
34
|
+
taskkill /F /IM chrome.exe >nul 2>&1
|
|
35
|
+
timeout /t 3 /nobreak >nul
|
|
36
|
+
echo Dang mo Chrome voi Debug Mode...
|
|
37
|
+
start "" "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ^
|
|
38
|
+
--remote-debugging-port=9222 ^
|
|
39
|
+
--remote-allow-origins=* ^
|
|
40
|
+
--user-data-dir="%TEMP%\\chrome-debug"
|
|
41
|
+
timeout /t 4 /nobreak >nul
|
|
42
|
+
powershell -Command "try { Invoke-WebRequest -Uri 'http://localhost:9222/json/version' -UseBasicParsing -TimeoutSec 5 | Out-Null; Write-Host 'OK! Chrome Debug Mode dang chay.' -ForegroundColor Green } catch { Write-Host 'LOI: Port 9222 chua mo.' -ForegroundColor Red }"
|
|
43
|
+
echo.
|
|
44
|
+
pause
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function buildChromeDebugSh() {
|
|
49
|
+
return `#!/usr/bin/env bash
|
|
50
|
+
# ====== OpenClaw - Chrome Debug Mode (Mac/Linux) ======
|
|
51
|
+
set -e
|
|
52
|
+
echo "====== OpenClaw - Chrome Debug Mode ======"
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
56
|
+
CHROME_BIN="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
57
|
+
[ ! -f "$CHROME_BIN" ] && CHROME_BIN="/Applications/Chromium.app/Contents/MacOS/Chromium"
|
|
58
|
+
[ ! -f "$CHROME_BIN" ] && CHROME_BIN="/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
|
|
59
|
+
else
|
|
60
|
+
CHROME_BIN="$(command -v google-chrome || command -v google-chrome-stable || command -v chromium-browser || command -v chromium || echo '')"
|
|
61
|
+
fi
|
|
62
|
+
[ -n "$CHROME_DEBUG_BIN" ] && CHROME_BIN="$CHROME_DEBUG_BIN"
|
|
63
|
+
|
|
64
|
+
if [ -z "$CHROME_BIN" ] || { [ ! -f "$CHROME_BIN" ] && [ ! -x "$CHROME_BIN" ]; }; then
|
|
65
|
+
echo -e "\\033[31mERROR: Chrome/Chromium not found.\\033[0m"
|
|
66
|
+
echo "Install Chrome or: export CHROME_DEBUG_BIN=/path/to/chrome"
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
echo "Using: $CHROME_BIN"
|
|
71
|
+
echo "Killing existing Chrome debug instances..."
|
|
72
|
+
pkill -f -- "--remote-debugging-port=9222" 2>/dev/null || true
|
|
73
|
+
sleep 2
|
|
74
|
+
|
|
75
|
+
TMP_DIR="\${TMPDIR:-/tmp}/chrome-debug-openclaw"
|
|
76
|
+
mkdir -p "$TMP_DIR"
|
|
77
|
+
|
|
78
|
+
echo "Starting Chrome in Debug Mode (port 9222)..."
|
|
79
|
+
"$CHROME_BIN" \\
|
|
80
|
+
--remote-debugging-port=9222 \\
|
|
81
|
+
--remote-allow-origins=* \\
|
|
82
|
+
--user-data-dir="$TMP_DIR" &
|
|
83
|
+
|
|
84
|
+
sleep 4
|
|
85
|
+
if curl -s http://localhost:9222/json/version > /dev/null 2>&1; then
|
|
86
|
+
echo -e "\\033[32mOK! Chrome Debug Mode is running on port 9222.\\033[0m"
|
|
87
|
+
else
|
|
88
|
+
echo -e "\\033[31mERROR: Port 9222 not responding.\\033[0m"
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function buildUninstallArtifact(options = {}) {
|
|
95
|
+
const {
|
|
96
|
+
os = 'win',
|
|
97
|
+
isDocker = false,
|
|
98
|
+
projectDir = '.',
|
|
99
|
+
botName = 'openclaw',
|
|
100
|
+
} = options;
|
|
101
|
+
|
|
102
|
+
const absWin = String(projectDir).replace(/\//g, '\\');
|
|
103
|
+
const absUnix = String(projectDir).replace(/\\/g, '/');
|
|
104
|
+
const appName = String(botName || 'openclaw').toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
105
|
+
|
|
106
|
+
if (os === 'win' && !isDocker) {
|
|
107
|
+
return { name: 'uninstall-openclaw-win.bat', content: `@echo off\nsetlocal EnableExtensions\nchcp 65001 >nul\necho.\necho ============================================================\necho OpenClaw Uninstaller - Windows Native\necho Project: ${absWin}\necho ============================================================\necho.\necho [WARNING] This will:\necho 1. Kill openclaw and 9router background processes\necho 2. Uninstall global npm packages (openclaw, 9router)\necho 3. Delete the project folder and all its data\necho.\nset /p CONFIRM=Nhap YES de xac nhan xoa toan bo: \nif /i not "%CONFIRM%"=="YES" (\n echo Huy bo. Khong xoa gi ca.\n pause\n exit /b 0\n)\necho.\necho [1/4] Dang dung cac tien trinh openclaw va 9router...\nwmic process where "Name='node.exe' and CommandLine like '%%9router%%'" delete >nul 2>&1\nwmic process where "Name='cmd.exe' and CommandLine like '%%9router%%'" delete >nul 2>&1\nwmic process where "Name='node.exe' and CommandLine like '%%openclaw.mjs%%'" delete >nul 2>&1\ntimeout /t 2 /nobreak >nul\necho OK: Tien trinh da dung.\necho.\necho [2/4] Dang go cai npm packages toan cau...\nset "PATH=%APPDATA%\\\\npm;%PATH%"\ncall npm uninstall -g openclaw 9router grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api 2>nul\necho OK: npm packages da duoc go cai.\necho.\necho [3/4] Xoa thu muc project...\nset "TARGET=${absWin}"\nif exist "%TARGET%" (\n rd /s /q "%TARGET%"\n echo OK: Da xoa %TARGET%\n) else (\n echo INFO: Thu muc khong ton tai: %TARGET%\n)\necho.\necho [4/4] Xoa thu muc .9router trong Home (neu co)...\nif exist "%USERPROFILE%\\\\.9router" (\n set /p CLEAN_HOME=Xoa ca %USERPROFILE%\\\\.9router? [YES/no]: \n if /i "%CLEAN_HOME%"=="YES" rd /s /q "%USERPROFILE%\\\\.9router" >nul 2>&1\n)\necho.\necho ============================================================\necho Go cai hoan tat!\necho De cai lai: chay lai file setup hoac npx create-openclaw-bot\necho ============================================================\npause\nendlocal\n` };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (os === 'win' && isDocker) {
|
|
111
|
+
return { name: 'uninstall-openclaw-docker.bat', content: `@echo off\nsetlocal EnableExtensions\nchcp 65001 >nul\necho.\necho ============================================================\necho OpenClaw Uninstaller - Docker (Windows)\necho Project: ${absWin}\necho ============================================================\necho.\necho [WARNING] This will stop Docker containers and delete the project folder.\necho.\nset /p CONFIRM=Nhap YES de xac nhan xoa toan bo: \nif /i not "%CONFIRM%"=="YES" (\n echo Huy bo. Khong xoa gi ca.\n pause\n exit /b 0\n)\necho.\necho [1/2] Dang dung Docker containers...\ncd /d "${absWin}\\\\docker\\\\openclaw" 2>nul && (\n docker compose down --volumes --remove-orphans 2>nul || docker-compose down --volumes --remove-orphans 2>nul\n echo OK: Containers da dung.\n) || echo INFO: Khong tim thay docker compose.\necho.\necho [2/2] Xoa thu muc project...\ncd /d "%USERPROFILE%"\nif exist "${absWin}" (\n rd /s /q "${absWin}"\n echo OK: Da xoa ${absWin}\n)\necho.\necho ============================================================\necho Go cai hoan tat! De cai lai: npx create-openclaw-bot@latest\necho ============================================================\npause\nendlocal\n` };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (isDocker) {
|
|
115
|
+
return { name: 'uninstall-openclaw-docker.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\nDOCKER_DIR="$PROJECT_DIR/docker/openclaw"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - Docker"\necho " Project: $PROJECT_DIR"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/3] Stopping Docker containers and removing volumes..."\nif [ -d "$DOCKER_DIR" ] && command -v docker &>/dev/null; then\n cd "$DOCKER_DIR"\n docker compose down --volumes --remove-orphans 2>/dev/null || docker-compose down --volumes --remove-orphans 2>/dev/null || true\nfi\necho "[2/3] Removing project directory..."\n[ -d "$PROJECT_DIR" ] && rm -rf "$PROJECT_DIR" && echo " OK: Deleted $PROJECT_DIR" || echo " INFO: Not found."\necho "[3/3] Checking home-level .openclaw..."\nif [ -d "$HOME/.openclaw" ]; then\n read -rp "Delete $HOME/.openclaw? [YES/no]: " CLEAN\n [ "$CLEAN" = "YES" ] && rm -rf "$HOME/.openclaw" && echo " OK." || echo " Kept."\nfi\n` };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (os === 'vps') {
|
|
119
|
+
return { name: 'uninstall-openclaw-vps.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\nAPP_NAME="${appName}"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - VPS / Ubuntu Server"\necho " Project: $PROJECT_DIR"\necho " PM2 app: $APP_NAME"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/5] Stopping PM2 processes..."\nif command -v pm2 &>/dev/null; then\n pm2 delete "$APP_NAME" "$APP_NAME-9router" "$APP_NAME-9router-sync" openclaw openclaw-multibot 2>/dev/null || true\n pm2 save --force 2>/dev/null || true\nfi\necho "[2/5] Killing leftover processes on ports 18789 / 20128..."\nfor port in 18789 20128; do\n pid=$(lsof -ti tcp:$port 2>/dev/null || true)\n [ -n "$pid" ] && kill -9 $pid 2>/dev/null || true\ndone\necho "[3/5] Uninstalling npm packages..."\nnpm uninstall -g openclaw 9router pm2 grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api 2>/dev/null || true\necho "[4/5] Removing project directory..."\n[ -d "$PROJECT_DIR" ] && rm -rf "$PROJECT_DIR" && echo " OK: Deleted $PROJECT_DIR" || echo " INFO: Not found."\necho "[5/5] Checking home-level .9router / .openclaw..."\nfor dir in "$HOME/.9router" "$HOME/.openclaw"; do\n if [ -d "$dir" ]; then\n read -rp "Delete $dir ? [YES/no]: " CLEAN\n [ "$CLEAN" = "YES" ] && rm -rf "$dir" && echo " OK: Deleted $dir" || echo " Kept: $dir"\n fi\ndone\n` };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (os === 'linux' || os === 'linux-desktop' || os === 'macos') {
|
|
123
|
+
const label = os === 'macos' ? 'macOS' : 'Linux Desktop';
|
|
124
|
+
return { name: 'uninstall-openclaw.sh', content: `#!/usr/bin/env bash\nset -e\nPROJECT_DIR="${absUnix}"\necho ""\necho "============================================================"\necho " OpenClaw Uninstaller - ${label} Native"\necho " Project: $PROJECT_DIR"\necho "============================================================"\necho ""\nread -rp "Type YES to confirm full removal: " CONFIRM\nif [ "$CONFIRM" != "YES" ]; then echo "Cancelled."; exit 0; fi\necho "[1/4] Stopping openclaw and 9router processes..."\npkill -f "openclaw gateway run" 2>/dev/null || true\npkill -f "9router.*20128" 2>/dev/null || true\npkill -f "9router-smart-route" 2>/dev/null || true\npkill -f "$PROJECT_DIR" 2>/dev/null || true\nfor port in 18789 20128; do\n pid=$(lsof -ti tcp:$port 2>/dev/null || true)\n [ -n "$pid" ] && kill -9 $pid 2>/dev/null || true\ndone\necho "[2/4] Uninstalling npm packages..."\nnpm uninstall -g openclaw 9router grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api 2>/dev/null || true\nsudo npm uninstall -g openclaw 9router 2>/dev/null || true\necho "[3/4] Removing project directory..."\n[ -d "$PROJECT_DIR" ] && rm -rf "$PROJECT_DIR" && echo " OK: Deleted $PROJECT_DIR" || echo " INFO: Not found."\necho "[4/4] Checking home-level .9router / .openclaw..."\nfor dir in "$HOME/.9router" "$HOME/.openclaw"; do\n if [ -d "$dir" ]; then\n read -rp "Delete $dir ? [YES/no]: " CLEAN\n [ "$CLEAN" = "YES" ] && rm -rf "$dir" && echo " OK: Deleted $dir" || echo " Kept: $dir"\n fi\ndone\n` };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function buildCliUninstallArtifacts(options = {}) {
|
|
131
|
+
const { deployMode = 'native', osChoice = 'windows', projectDir = '.', botName = 'openclaw' } = options;
|
|
132
|
+
if (deployMode === 'docker') {
|
|
133
|
+
return [
|
|
134
|
+
buildUninstallArtifact({ os: 'linux', isDocker: true, projectDir, botName }),
|
|
135
|
+
buildUninstallArtifact({ os: 'win', isDocker: true, projectDir, botName }),
|
|
136
|
+
].filter(Boolean);
|
|
137
|
+
}
|
|
138
|
+
if (osChoice === 'windows') return [buildUninstallArtifact({ os: 'win', projectDir, botName })].filter(Boolean);
|
|
139
|
+
if (osChoice === 'vps') return [buildUninstallArtifact({ os: 'vps', projectDir, botName })].filter(Boolean);
|
|
140
|
+
if (osChoice === 'macos') return [buildUninstallArtifact({ os: 'macos', projectDir, botName })].filter(Boolean);
|
|
141
|
+
return [buildUninstallArtifact({ os: 'linux', projectDir, botName })].filter(Boolean);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function buildCliChromeDebugArtifacts() {
|
|
145
|
+
return [
|
|
146
|
+
{ name: 'start-chrome-debug.bat', content: buildChromeDebugBat() },
|
|
147
|
+
{ name: 'start-chrome-debug.sh', content: buildChromeDebugSh(), executable: true },
|
|
148
|
+
];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function buildStartBotBat(opts = {}) {
|
|
152
|
+
const { projectDir = '.', openclawHome = '.openclaw', is9Router = false, isVi = true } = opts;
|
|
153
|
+
const L = [];
|
|
154
|
+
L.push('@echo off');
|
|
155
|
+
L.push('setlocal EnableExtensions');
|
|
156
|
+
L.push('chcp 65001 >nul');
|
|
157
|
+
L.push(`set "PROJECT_DIR=${projectDir}"`);
|
|
158
|
+
L.push(`set "OPENCLAW_HOME=${openclawHome}"`);
|
|
159
|
+
L.push(`set "DATA_DIR=${projectDir}\\.9router"`);
|
|
160
|
+
L.push('set "PATH=%APPDATA%\\npm;%PATH%"');
|
|
161
|
+
L.push('powershell -NoProfile -Command "Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force" >nul 2>&1');
|
|
162
|
+
L.push('echo.');
|
|
163
|
+
L.push(isVi ? 'echo ====== OpenClaw - Khoi dong lai bot ======' : 'echo ====== OpenClaw - Restart Bot ======');
|
|
164
|
+
L.push('echo.');
|
|
165
|
+
L.push(isVi ? 'echo [1] Dung process openclaw cu (neu co)...' : 'echo [1] Stopping existing openclaw process (if any)...');
|
|
166
|
+
L.push('call openclaw gateway stop >nul 2>&1');
|
|
167
|
+
L.push('timeout /t 2 /nobreak >nul');
|
|
168
|
+
if (is9Router) {
|
|
169
|
+
L.push('');
|
|
170
|
+
L.push(isVi ? 'echo [2] Dung 9Router cu va khoi dong lai...' : 'echo [2] Stopping old 9Router and restarting...');
|
|
171
|
+
L.push("wmic process where \"Name='node.exe' and CommandLine like '%%9router%%'\" delete >nul 2>&1");
|
|
172
|
+
L.push("wmic process where \"Name='cmd.exe' and CommandLine like '%%9router%%'\" delete >nul 2>&1");
|
|
173
|
+
L.push('timeout /t 2 /nobreak >nul');
|
|
174
|
+
L.push("echo $env:DATA_DIR = '%DATA_DIR%' > \"%TEMP%\\oc-start9r.ps1\"");
|
|
175
|
+
L.push("echo $b = Join-Path $env:APPDATA 'npm\\9router.cmd' >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
176
|
+
L.push("echo if ^(-not ^(Test-Path $b^)^) { $b = Join-Path $env:APPDATA 'npm\\9router' } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
177
|
+
L.push(`echo $patch = Join-Path '${projectDir}' '.openclaw\\patch-9router.js' >> "%TEMP%\\oc-start9r.ps1"`);
|
|
178
|
+
L.push("echo if ^(Test-Path $patch^) { ^& node $patch ^| Out-Null } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
179
|
+
L.push(`echo Start-Process 'cmd.exe' -WindowStyle Hidden -WorkingDirectory '${projectDir}' -ArgumentList ^('/c "' + $b + '" -n -H 0.0.0.0 -p 20128 --skip-update'^) >> "%TEMP%\\oc-start9r.ps1"`);
|
|
180
|
+
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-start9r.ps1"');
|
|
181
|
+
L.push('del "%TEMP%\\oc-start9r.ps1" >nul 2>&1');
|
|
182
|
+
L.push('timeout /t 5 /nobreak >nul');
|
|
183
|
+
L.push(isVi ? 'echo [OK] 9Router da khoi dong.' : 'echo [OK] 9Router started.');
|
|
184
|
+
L.push('');
|
|
185
|
+
L.push(isVi ? 'echo [2b] Khoi dong sync smart-route...' : 'echo [2b] Starting smart-route sync...');
|
|
186
|
+
L.push(`echo $env:DATA_DIR = '%DATA_DIR%' > "%TEMP%\\oc-syncsmart.ps1"`);
|
|
187
|
+
L.push(`echo $sync = Join-Path '${projectDir}' '.openclaw\\9router-smart-route-sync.js' >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
188
|
+
L.push(`echo if ^(Test-Path $sync^) { Start-Process 'node' -WindowStyle Hidden -ArgumentList $sync } >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
189
|
+
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-syncsmart.ps1"');
|
|
190
|
+
L.push('del "%TEMP%\\oc-syncsmart.ps1" >nul 2>&1');
|
|
191
|
+
}
|
|
192
|
+
L.push('');
|
|
193
|
+
L.push(isVi ? 'echo [3] Khoi dong OpenClaw Gateway...' : 'echo [3] Starting OpenClaw Gateway...');
|
|
194
|
+
L.push('set "GW_LAUNCHER=%TEMP%\\openclaw-gateway-start.bat"');
|
|
195
|
+
L.push('> "%GW_LAUNCHER%" echo @echo off');
|
|
196
|
+
L.push('>> "%GW_LAUNCHER%" echo title openclaw-gateway');
|
|
197
|
+
L.push('>> "%GW_LAUNCHER%" echo setlocal EnableExtensions');
|
|
198
|
+
L.push('>> "%GW_LAUNCHER%" echo chcp 65001 ^>nul');
|
|
199
|
+
L.push('>> "%GW_LAUNCHER%" echo cd /d "%PROJECT_DIR%"');
|
|
200
|
+
L.push('>> "%GW_LAUNCHER%" echo set "PROJECT_DIR=%PROJECT_DIR%"');
|
|
201
|
+
L.push('>> "%GW_LAUNCHER%" echo set "OPENCLAW_HOME=%OPENCLAW_HOME%"');
|
|
202
|
+
L.push('>> "%GW_LAUNCHER%" echo set "OPENCLAW_STATE_DIR=%OPENCLAW_HOME%"');
|
|
203
|
+
L.push('>> "%GW_LAUNCHER%" echo set "DATA_DIR=%DATA_DIR%"');
|
|
204
|
+
L.push('>> "%GW_LAUNCHER%" echo set "PATH=%APPDATA%\\npm;%%PATH%%"');
|
|
205
|
+
L.push('>> "%GW_LAUNCHER%" echo if exist ".env" for /f "usebackq eol=# tokens=1,* delims==" %%%%A in ^(".env"^) do set "%%%%A=%%%%B"');
|
|
206
|
+
L.push('>> "%GW_LAUNCHER%" echo echo ===== OpenClaw Gateway =====');
|
|
207
|
+
L.push('>> "%GW_LAUNCHER%" echo echo Project: %%PROJECT_DIR%%');
|
|
208
|
+
L.push('>> "%GW_LAUNCHER%" echo echo.');
|
|
209
|
+
L.push('>> "%GW_LAUNCHER%" echo if exist "%%APPDATA%%\\npm\\openclaw.cmd" ^(call "%%APPDATA%%\\npm\\openclaw.cmd" gateway run^) else ^(openclaw gateway run^)');
|
|
210
|
+
L.push('>> "%GW_LAUNCHER%" echo echo.');
|
|
211
|
+
L.push(isVi
|
|
212
|
+
? '>> "%GW_LAUNCHER%" echo echo OpenClaw Gateway da dung voi ma loi %%ERRORLEVEL%%.'
|
|
213
|
+
: '>> "%GW_LAUNCHER%" echo echo OpenClaw Gateway exited with code %%ERRORLEVEL%%.');
|
|
214
|
+
L.push('>> "%GW_LAUNCHER%" echo pause');
|
|
215
|
+
L.push('start "openclaw-gateway" cmd /k call "%GW_LAUNCHER%"');
|
|
216
|
+
L.push('timeout /t 3 /nobreak >nul');
|
|
217
|
+
L.push('echo.');
|
|
218
|
+
L.push(isVi ? 'echo [OK] OpenClaw Gateway da khoi dong trong cua so moi!' : 'echo [OK] OpenClaw Gateway started in a new window!');
|
|
219
|
+
L.push('echo.');
|
|
220
|
+
L.push('echo OpenClaw Dashboard: http://127.0.0.1:18789');
|
|
221
|
+
if (is9Router) L.push('echo 9Router Dashboard: http://127.0.0.1:20128/dashboard');
|
|
222
|
+
L.push('echo.');
|
|
223
|
+
L.push(isVi ? 'echo Ban co the dong cua so nay.' : 'echo You may close this window.');
|
|
224
|
+
L.push('pause');
|
|
225
|
+
L.push('endlocal');
|
|
226
|
+
return L.join('\r\n');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function buildStartBotSh(opts = {}) {
|
|
230
|
+
const {
|
|
231
|
+
projectDir = '.',
|
|
232
|
+
is9Router = false,
|
|
233
|
+
isVi = true,
|
|
234
|
+
osChoice = 'linux',
|
|
235
|
+
isMultiBot = false,
|
|
236
|
+
appName = 'openclaw',
|
|
237
|
+
logFile9r = '/tmp/9router.log',
|
|
238
|
+
logFileGw = '/tmp/openclaw-gw.log',
|
|
239
|
+
} = opts;
|
|
240
|
+
if (osChoice === 'vps') {
|
|
241
|
+
const L = [];
|
|
242
|
+
L.push('#!/bin/bash');
|
|
243
|
+
L.push('set -euo pipefail');
|
|
244
|
+
L.push(`PROJECT_DIR="${projectDir}"`);
|
|
245
|
+
L.push('cd "$PROJECT_DIR"');
|
|
246
|
+
L.push('export OPENCLAW_HOME="$PROJECT_DIR/.openclaw"');
|
|
247
|
+
L.push('export OPENCLAW_STATE_DIR="$PROJECT_DIR/.openclaw"');
|
|
248
|
+
L.push('export DATA_DIR="$PROJECT_DIR/.9router"');
|
|
249
|
+
L.push('if [ -f ".env" ]; then set -a; . ./.env; set +a; fi');
|
|
250
|
+
L.push(`APP_NAME="${appName}"`);
|
|
251
|
+
L.push('');
|
|
252
|
+
L.push('if ! command -v pm2 >/dev/null 2>&1; then');
|
|
253
|
+
L.push(isVi ? ' echo "ERROR: Khong tim thay PM2. Chay: npm install -g pm2"' : ' echo "ERROR: PM2 not found. Run: npm install -g pm2"');
|
|
254
|
+
L.push(' exit 1');
|
|
255
|
+
L.push('fi');
|
|
256
|
+
L.push('');
|
|
257
|
+
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot qua PM2 ======"' : 'echo "====== OpenClaw - Restart Bot via PM2 ======"');
|
|
258
|
+
L.push('echo ""');
|
|
259
|
+
if (is9Router) {
|
|
260
|
+
L.push(isVi ? 'echo "[1] Khoi dong lai 9Router qua PM2..."' : 'echo "[1] Restarting 9Router via PM2..."');
|
|
261
|
+
L.push('NINE_ROUTER_BIN="$(command -v 9router 2>/dev/null || true)"');
|
|
262
|
+
L.push('NODE_BIN="$(command -v node 2>/dev/null || true)"');
|
|
263
|
+
L.push('if [ -z "$NINE_ROUTER_BIN" ] || [ -z "$NODE_BIN" ]; then');
|
|
264
|
+
L.push(isVi ? ' echo "ERROR: Thieu node hoac 9router. Chay: npm install -g 9router"' : ' echo "ERROR: Missing node or 9router. Run: npm install -g 9router"');
|
|
265
|
+
L.push(' exit 1');
|
|
266
|
+
L.push('fi');
|
|
267
|
+
L.push('pm2 delete "$APP_NAME-9router" "$APP_NAME-9router-sync" >/dev/null 2>&1 || true');
|
|
268
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
269
|
+
L.push(' "$NODE_BIN" "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
270
|
+
L.push('fi');
|
|
271
|
+
L.push('PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" pm2 start "$NINE_ROUTER_BIN" --name "$APP_NAME-9router" --interpreter "$NODE_BIN" -- -n -H 0.0.0.0 -p 20128 --skip-update');
|
|
272
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
273
|
+
L.push(' pm2 start "$NODE_BIN" --name "$APP_NAME-9router-sync" -- "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js"');
|
|
274
|
+
L.push('fi');
|
|
275
|
+
} else {
|
|
276
|
+
L.push(isVi ? 'echo "[1] Khong dung 9Router cho project nay."' : 'echo "[1] This project does not use 9Router."');
|
|
277
|
+
}
|
|
278
|
+
L.push('');
|
|
279
|
+
if (isMultiBot) {
|
|
280
|
+
L.push(isVi ? 'echo "[2] Khoi dong lai multi-bot gateway qua PM2..."' : 'echo "[2] Restarting multi-bot gateway via PM2..."');
|
|
281
|
+
L.push('pm2 delete "$APP_NAME" >/dev/null 2>&1 || true');
|
|
282
|
+
L.push('pm2 start ecosystem.config.js');
|
|
283
|
+
} else {
|
|
284
|
+
L.push(isVi ? 'echo "[2] Khoi dong lai OpenClaw gateway qua PM2..."' : 'echo "[2] Restarting OpenClaw gateway via PM2..."');
|
|
285
|
+
L.push('pm2 delete "$APP_NAME" >/dev/null 2>&1 || true');
|
|
286
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/start-gateway.sh" ]; then');
|
|
287
|
+
L.push(' pm2 start "$PROJECT_DIR/.openclaw/start-gateway.sh" --name "$APP_NAME" --interpreter bash');
|
|
288
|
+
L.push('else');
|
|
289
|
+
L.push(' OPENCLAW_HOME="$PROJECT_DIR/.openclaw" OPENCLAW_STATE_DIR="$PROJECT_DIR/.openclaw" pm2 start "$(command -v openclaw)" --name "$APP_NAME" --interpreter "$(command -v node)" -- gateway run');
|
|
290
|
+
L.push('fi');
|
|
291
|
+
}
|
|
292
|
+
L.push('pm2 save >/dev/null 2>&1 || true');
|
|
293
|
+
L.push('echo ""');
|
|
294
|
+
L.push('echo "OpenClaw Dashboard: http://127.0.0.1:18789"');
|
|
295
|
+
if (is9Router) L.push('echo "9Router Dashboard: http://127.0.0.1:20128/dashboard"');
|
|
296
|
+
L.push('echo ""');
|
|
297
|
+
L.push(isVi ? 'echo "Log gateway: pm2 logs $APP_NAME"' : 'echo "Gateway logs: pm2 logs $APP_NAME"');
|
|
298
|
+
if (is9Router) L.push(isVi ? 'echo "Log 9Router: pm2 logs $APP_NAME-9router"' : 'echo "9Router logs: pm2 logs $APP_NAME-9router"');
|
|
299
|
+
return L.join('\n');
|
|
300
|
+
}
|
|
301
|
+
const L = [];
|
|
302
|
+
L.push('#!/bin/bash');
|
|
303
|
+
L.push('set -euo pipefail');
|
|
304
|
+
L.push(`cd "${projectDir}"`);
|
|
305
|
+
L.push('export OPENCLAW_HOME="$PWD/.openclaw"');
|
|
306
|
+
L.push('export OPENCLAW_STATE_DIR="$PWD/.openclaw"');
|
|
307
|
+
L.push('export DATA_DIR="$PWD/.9router"');
|
|
308
|
+
L.push('if [ -f ".env" ]; then set -a; . ./.env; set +a; fi');
|
|
309
|
+
L.push('');
|
|
310
|
+
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot ======"' : 'echo "====== OpenClaw - Restart Bot ======"');
|
|
311
|
+
L.push('');
|
|
312
|
+
L.push(isVi ? 'echo "[1] Dung openclaw gateway cu (neu co)..."' : 'echo "[1] Stopping existing openclaw gateway (if any)..."');
|
|
313
|
+
L.push('openclaw gateway stop 2>/dev/null || true');
|
|
314
|
+
L.push('sleep 1');
|
|
315
|
+
if (is9Router) {
|
|
316
|
+
L.push('');
|
|
317
|
+
L.push(isVi ? 'echo "[2] Dung 9Router cu va khoi dong lai..."' : 'echo "[2] Stopping 9Router and restarting..."');
|
|
318
|
+
L.push('pkill -f "9router" 2>/dev/null || true');
|
|
319
|
+
L.push('sleep 1');
|
|
320
|
+
L.push('NINE_ROUTER_BIN="$(command -v 9router 2>/dev/null || true)"');
|
|
321
|
+
L.push('if [ -z "$NINE_ROUTER_BIN" ]; then');
|
|
322
|
+
L.push(isVi ? ' echo "ERROR: Khong tim thay 9router! Chay: npm install -g 9router"' : ' echo "ERROR: 9router not found! Run: npm install -g 9router"');
|
|
323
|
+
L.push(' exit 1');
|
|
324
|
+
L.push('fi');
|
|
325
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
326
|
+
L.push(' node "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
327
|
+
L.push('fi');
|
|
328
|
+
L.push(`nohup env PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" "$NINE_ROUTER_BIN" -n -H 0.0.0.0 -p 20128 --skip-update > "${logFile9r}" 2>&1 &`);
|
|
329
|
+
L.push('sleep 3');
|
|
330
|
+
L.push(isVi ? `echo "[OK] 9Router da khoi dong. Log: ${logFile9r}"` : `echo "[OK] 9Router started. Log: ${logFile9r}"`);
|
|
331
|
+
L.push('');
|
|
332
|
+
L.push(isVi ? 'echo "[2b] Khoi dong sync smart-route..."' : 'echo "[2b] Starting smart-route sync..."');
|
|
333
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
334
|
+
L.push(' nohup env DATA_DIR="$DATA_DIR" node "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" > /tmp/9router-sync.log 2>&1 &');
|
|
335
|
+
L.push('fi');
|
|
336
|
+
}
|
|
337
|
+
L.push('');
|
|
338
|
+
L.push(isVi ? 'echo "[3] Khoi dong OpenClaw Gateway..."' : 'echo "[3] Starting OpenClaw Gateway..."');
|
|
339
|
+
L.push(`nohup openclaw gateway run > "${logFileGw}" 2>&1 &`);
|
|
340
|
+
L.push('GW_PID=$!');
|
|
341
|
+
L.push('sleep 2');
|
|
342
|
+
L.push(isVi ? `echo "[OK] Gateway khoi dong (PID $GW_PID). Log: ${logFileGw}"` : `echo "[OK] Gateway started (PID $GW_PID). Log: ${logFileGw}"`);
|
|
343
|
+
L.push('');
|
|
344
|
+
L.push('echo ""');
|
|
345
|
+
L.push('echo "OpenClaw Dashboard: http://127.0.0.1:18789"');
|
|
346
|
+
if (is9Router) L.push('echo "9Router Dashboard: http://127.0.0.1:20128/dashboard"');
|
|
347
|
+
L.push('echo ""');
|
|
348
|
+
L.push(isVi ? 'echo "Bot dang chay background. Dung: openclaw gateway stop"' : 'echo "Bot running in background. Stop: openclaw gateway stop"');
|
|
349
|
+
return L.join('\n');
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function buildCliStartBotArtifacts(options = {}) {
|
|
353
|
+
return [
|
|
354
|
+
{
|
|
355
|
+
name: 'start-bot.bat',
|
|
356
|
+
content: buildStartBotBat(options),
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
name: 'start-bot.sh',
|
|
360
|
+
content: buildStartBotSh(options),
|
|
361
|
+
executable: true,
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
function buildUpgradePs1() {
|
|
368
|
+
return [
|
|
369
|
+
"# OpenClaw Upgrade Script — Windows (PowerShell)",
|
|
370
|
+
"# Cach dung:",
|
|
371
|
+
"# Nhan dup upgrade.ps1 hoac: .\\upgrade.ps1",
|
|
372
|
+
"# irm https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.ps1 | iex",
|
|
373
|
+
"# Chi danh cho Windows. Linux/macOS/Ubuntu: dung upgrade.sh",
|
|
374
|
+
"",
|
|
375
|
+
"$ErrorActionPreference = \"Stop\"",
|
|
376
|
+
"",
|
|
377
|
+
"# ── Version ──────────────────────────────────────────────────────────────────",
|
|
378
|
+
"$VER_STR = \"\"",
|
|
379
|
+
"try {",
|
|
380
|
+
" if (Test-Path \"package.json\") {",
|
|
381
|
+
" $pkg = Get-Content \"package.json\" -Raw | ConvertFrom-Json",
|
|
382
|
+
" if ($pkg.version) { $VER_STR = \" v$($pkg.version)\" }",
|
|
383
|
+
" }",
|
|
384
|
+
"} catch {}",
|
|
385
|
+
"",
|
|
386
|
+
"# ── Banner: LOGO + BOX ───────────────────────────────────────────────────────",
|
|
387
|
+
"Write-Host \"\"",
|
|
388
|
+
"$logo = @(",
|
|
389
|
+
" '████████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ███╗██╗███╗ ██╗██╗ ██╗██╗ ██╗ ██████╗ ██╗ ███████╗',",
|
|
390
|
+
" '╚══██╔══╝██║ ██║██╔══██╗████╗ ██║████╗ ████║██║████╗ ██║██║ ██║██║ ██║██╔═══██╗██║ ██╔════╝',",
|
|
391
|
+
" ' ██║ ██║ ██║███████║██╔██╗ ██║██╔████╔██║██║██╔██╗ ██║███████║███████║██║ ██║██║ █████╗ ',",
|
|
392
|
+
" ' ██║ ██║ ██║██╔══██║██║╚██╗██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║██╔══██║██║ ██║██║ ██╔══╝ ',",
|
|
393
|
+
" ' ██║ ╚██████╔╝██║ ██║██║ ╚████║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║██║ ██║╚██████╔╝███████╗███████╗',",
|
|
394
|
+
" ' ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝'",
|
|
395
|
+
")",
|
|
396
|
+
"foreach ($l in $logo) { Write-Host $l -ForegroundColor Red }",
|
|
397
|
+
"Write-Host \"\"",
|
|
398
|
+
"",
|
|
399
|
+
"# Box — node render (handles emoji visual width correctly on all terminals)",
|
|
400
|
+
"$env:L1 = \" 🦞 OpenClaw Setup$VER_STR | Upgrade Script\"",
|
|
401
|
+
"$env:L2 = \" Windows (PowerShell)\"",
|
|
402
|
+
"node -e @\"\nconst RED='\\x1b[0;31m',NC='\\x1b[0m';\nfunction vw(s){let w=0;for(const c of[...s]){const cp=c.codePointAt(0);w+=(cp>=0x1F000&&cp<=0x1FFFF?2:1);}return w;}\nconst L1=process.env.L1,L2=process.env.L2;\nconst INNER=Math.max(vw(L1),vw(L2))+2;\nconst D='─'.repeat(INNER);const pad=s=>' '.repeat(Math.max(0,INNER-vw(s)));\nconsole.log(RED+'╭'+D+'╮'+NC);\nconsole.log(RED+'│'+NC+L1+pad(L1)+RED+'│'+NC);\nconsole.log(RED+'│'+NC+L2+pad(L2)+RED+'│'+NC);\nconsole.log(RED+'╰'+D+'╯'+NC);\n\"@",
|
|
403
|
+
"Write-Host \"\"",
|
|
404
|
+
"",
|
|
405
|
+
"# ── 1. Kiem tra Node.js ──────────────────────────────────────────────────────",
|
|
406
|
+
"if (-not (Get-Command node -ErrorAction SilentlyContinue)) {",
|
|
407
|
+
" Write-Host \" ❌ Khong tim thay Node.js.\" -ForegroundColor Red",
|
|
408
|
+
" Write-Host \" Tai LTS: https://nodejs.org/\" -ForegroundColor Yellow",
|
|
409
|
+
" Read-Host \"Nhan Enter de dong\"; exit 1",
|
|
410
|
+
"}",
|
|
411
|
+
"$nodeVer = node -e \"process.stdout.write(process.version)\"",
|
|
412
|
+
"Write-Host \" ✅ Node.js $nodeVer\" -ForegroundColor Green",
|
|
413
|
+
"",
|
|
414
|
+
"# ── 2. Xac dinh thu muc project ──────────────────────────────────────────────",
|
|
415
|
+
"$ScriptDir = $PSScriptRoot",
|
|
416
|
+
"if (-not $ScriptDir -or $ScriptDir -eq \"\") {",
|
|
417
|
+
" $ProjectDir = (Get-Location).Path",
|
|
418
|
+
"} elseif ((Test-Path (Join-Path $ScriptDir \".openclaw\")) -or (Test-Path (Join-Path $ScriptDir \"docker\"))) {",
|
|
419
|
+
" $ProjectDir = $ScriptDir",
|
|
420
|
+
"} else {",
|
|
421
|
+
" $ProjectDir = (Get-Location).Path",
|
|
422
|
+
"}",
|
|
423
|
+
"Write-Host \" 📁 Project: $ProjectDir\" -ForegroundColor DarkGray",
|
|
424
|
+
"Write-Host \"\"",
|
|
425
|
+
"Set-Location $ProjectDir",
|
|
426
|
+
"",
|
|
427
|
+
"# ── 3. Chay upgrade ──────────────────────────────────────────────────────────",
|
|
428
|
+
"Write-Host \" 🔄 Dang lay CLI moi nhat va chay upgrade...\" -ForegroundColor Cyan",
|
|
429
|
+
"Write-Host \" npx luon tai create-openclaw-bot@latest — khong can cap nhat tay\" -ForegroundColor DarkGray",
|
|
430
|
+
"Write-Host \"\"",
|
|
431
|
+
"",
|
|
432
|
+
"try {",
|
|
433
|
+
" & npx create-openclaw-bot@latest upgrade",
|
|
434
|
+
" $exitCode = $LASTEXITCODE",
|
|
435
|
+
"} catch {",
|
|
436
|
+
" Write-Host \" ❌ Loi: $_\" -ForegroundColor Red",
|
|
437
|
+
" Read-Host \"Nhan Enter de dong\"; exit 1",
|
|
438
|
+
"}",
|
|
439
|
+
"",
|
|
440
|
+
"Write-Host \"\"",
|
|
441
|
+
"if ($exitCode -eq 0) {",
|
|
442
|
+
" Write-Host \" 🎉 Upgrade hoan tat!\" -ForegroundColor Green",
|
|
443
|
+
" Write-Host \" Dashboard: http://localhost:18789\" -ForegroundColor Cyan",
|
|
444
|
+
"} else {",
|
|
445
|
+
" Write-Host \" ⚠️ Ma loi: $exitCode — xem log o tren.\" -ForegroundColor Yellow",
|
|
446
|
+
"}",
|
|
447
|
+
"Write-Host \"\"",
|
|
448
|
+
"Read-Host \"Nhan Enter de dong\"",
|
|
449
|
+
""
|
|
450
|
+
].join('\r\n');
|
|
451
|
+
}
|
|
452
|
+
function buildUpgradeSh() {
|
|
453
|
+
return [
|
|
454
|
+
"#!/bin/bash",
|
|
455
|
+
"# OpenClaw Upgrade Script — Linux / macOS / Ubuntu",
|
|
456
|
+
"# Cach dung:",
|
|
457
|
+
"# bash upgrade.sh",
|
|
458
|
+
"# curl -fsSL https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.sh | bash",
|
|
459
|
+
"# wget -qO- https://raw.githubusercontent.com/tuanminhhole/openclaw-setup/main/upgrade.sh | bash",
|
|
460
|
+
"",
|
|
461
|
+
"set -e",
|
|
462
|
+
"",
|
|
463
|
+
"RED='\\033[0;31m'",
|
|
464
|
+
"GREEN='\\033[0;32m'",
|
|
465
|
+
"CYAN='\\033[0;36m'",
|
|
466
|
+
"YELLOW='\\033[1;33m'",
|
|
467
|
+
"GRAY='\\033[0;90m'",
|
|
468
|
+
"NC='\\033[0m'",
|
|
469
|
+
"",
|
|
470
|
+
"# ── Version ──────────────────────────────────────────────────────────────────",
|
|
471
|
+
"VER=\"\"",
|
|
472
|
+
"if [ -f \"package.json\" ] && command -v node &>/dev/null; then",
|
|
473
|
+
" VER=$(node -p \"try{JSON.parse(require('fs').readFileSync('package.json','utf8')).version}catch(e){''}\" 2>/dev/null || true)",
|
|
474
|
+
"fi",
|
|
475
|
+
"[ -n \"$VER\" ] && VER_STR=\" v${VER}\" || VER_STR=\"\"",
|
|
476
|
+
"",
|
|
477
|
+
"# ── Banner: LOGO + BOX ───────────────────────────────────────────────────────",
|
|
478
|
+
"echo -e \"${RED}\"",
|
|
479
|
+
"echo '████████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ███╗██╗███╗ ██╗██╗ ██╗██╗ ██╗ ██████╗ ██╗ ███████╗'",
|
|
480
|
+
"echo '╚══██╔══╝██║ ██║██╔══██╗████╗ ██║████╗ ████║██║████╗ ██║██║ ██║██║ ██║██╔═══██╗██║ ██╔════╝'",
|
|
481
|
+
"echo ' ██║ ██║ ██║███████║██╔██╗ ██║██╔████╔██║██║██╔██╗ ██║███████║███████║██║ ██║██║ █████╗ '",
|
|
482
|
+
"echo ' ██║ ██║ ██║██╔══██║██║╚██╗██║██║╚██╔╝██║██║██║╚██╗██║██╔══██║██╔══██║██║ ██║██║ ██╔══╝ '",
|
|
483
|
+
"echo ' ██║ ╚██████╔╝██║ ██║██║ ╚████║██║ ╚═╝ ██║██║██║ ╚████║██║ ██║██║ ██║╚██████╔╝███████╗███████╗'",
|
|
484
|
+
"echo ' ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝'",
|
|
485
|
+
"echo -e \"${NC}\"",
|
|
486
|
+
"",
|
|
487
|
+
"# Box — node render (handles emoji visual width correctly on all terminals)",
|
|
488
|
+
"L1=\" 🦞 OpenClaw Setup${VER_STR} | Upgrade Script\"",
|
|
489
|
+
"L2=\" Linux / macOS / Ubuntu\"",
|
|
490
|
+
"L1=\"$L1\" L2=\"$L2\" node -e \"\nconst RED='\\x1b[0;31m',NC='\\x1b[0m';\nfunction vw(s){let w=0;for(const c of[...s]){const cp=c.codePointAt(0);w+=(cp>=0x1F000&&cp<=0x1FFFF?2:1);}return w;}\nconst L1=process.env.L1,L2=process.env.L2;\nconst INNER=Math.max(vw(L1),vw(L2))+2;\nconst D='─'.repeat(INNER);const pad=s=>' '.repeat(Math.max(0,INNER-vw(s)));\nconsole.log(RED+'╭'+D+'╮'+NC);\nconsole.log(RED+'│'+NC+L1+pad(L1)+RED+'│'+NC);\nconsole.log(RED+'│'+NC+L2+pad(L2)+RED+'│'+NC);\nconsole.log(RED+'╰'+D+'╯'+NC);\n\"",
|
|
491
|
+
"echo \"\"",
|
|
492
|
+
"",
|
|
493
|
+
"# ── 1. Kiem tra Node.js ──────────────────────────────────────────────────────",
|
|
494
|
+
"if ! command -v node &> /dev/null; then",
|
|
495
|
+
" echo -e \"${RED} ❌ Khong tim thay Node.js.${NC}\"",
|
|
496
|
+
" echo -e \"${YELLOW} Cai dat: https://nodejs.org/${NC}\"",
|
|
497
|
+
" echo \"\"",
|
|
498
|
+
" echo -e \"${GRAY} Ubuntu/Debian:${NC}\"",
|
|
499
|
+
" echo -e \"${GRAY} curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -${NC}\"",
|
|
500
|
+
" echo -e \"${GRAY} sudo apt-get install -y nodejs${NC}\"",
|
|
501
|
+
" exit 1",
|
|
502
|
+
"fi",
|
|
503
|
+
"NODE_VER=$(node -e \"process.stdout.write(process.version)\")",
|
|
504
|
+
"echo -e \"${GREEN} ✅ Node.js ${NODE_VER}${NC}\"",
|
|
505
|
+
"",
|
|
506
|
+
"# ── 2. Xac dinh thu muc project ──────────────────────────────────────────────",
|
|
507
|
+
"if [[ \"${BASH_SOURCE[0]}\" == \"$0\" ]]; then",
|
|
508
|
+
" SCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"",
|
|
509
|
+
" if [ -d \"$SCRIPT_DIR/.openclaw\" ] || [ -d \"$SCRIPT_DIR/docker\" ]; then",
|
|
510
|
+
" PROJECT_DIR=\"$SCRIPT_DIR\"",
|
|
511
|
+
" else",
|
|
512
|
+
" PROJECT_DIR=\"$PWD\"",
|
|
513
|
+
" fi",
|
|
514
|
+
"else",
|
|
515
|
+
" PROJECT_DIR=\"$PWD\"",
|
|
516
|
+
"fi",
|
|
517
|
+
"echo -e \"${GRAY} 📁 Project: $PROJECT_DIR${NC}\"",
|
|
518
|
+
"echo \"\"",
|
|
519
|
+
"cd \"$PROJECT_DIR\"",
|
|
520
|
+
"",
|
|
521
|
+
"# ── 3. Chay upgrade ──────────────────────────────────────────────────────────",
|
|
522
|
+
"echo -e \"${CYAN} 🔄 Dang lay CLI moi nhat va chay upgrade...${NC}\"",
|
|
523
|
+
"echo -e \"${GRAY} npx luon tai create-openclaw-bot@latest — khong can cap nhat tay${NC}\"",
|
|
524
|
+
"echo \"\"",
|
|
525
|
+
"",
|
|
526
|
+
"npx create-openclaw-bot@latest upgrade",
|
|
527
|
+
"EXIT_CODE=$?",
|
|
528
|
+
"",
|
|
529
|
+
"echo \"\"",
|
|
530
|
+
"if [ $EXIT_CODE -eq 0 ]; then",
|
|
531
|
+
" echo -e \"${GREEN} 🎉 Upgrade hoan tat!${NC}\"",
|
|
532
|
+
" echo -e \"${CYAN} Dashboard: http://localhost:18789${NC}\"",
|
|
533
|
+
"else",
|
|
534
|
+
" echo -e \"${YELLOW} ⚠️ Ma loi: $EXIT_CODE — xem log o tren.${NC}\"",
|
|
535
|
+
"fi",
|
|
536
|
+
"echo \"\"",
|
|
537
|
+
""
|
|
538
|
+
].join('\n');
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function buildCliUpgradeArtifacts() {
|
|
542
|
+
return [
|
|
543
|
+
{ name: 'upgrade.ps1', content: buildUpgradePs1() },
|
|
544
|
+
{ name: 'upgrade.sh', content: buildUpgradeSh(), executable: true },
|
|
545
|
+
];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
root.__openclawInstall = {
|
|
549
|
+
buildSkillCatalogMarkdown,
|
|
550
|
+
buildChromeDebugBat,
|
|
551
|
+
buildChromeDebugSh,
|
|
552
|
+
buildCliChromeDebugArtifacts,
|
|
553
|
+
buildUninstallArtifact,
|
|
554
|
+
buildCliUninstallArtifacts,
|
|
555
|
+
buildStartBotBat,
|
|
556
|
+
buildStartBotSh,
|
|
557
|
+
buildCliStartBotArtifacts,
|
|
558
|
+
buildUpgradePs1,
|
|
559
|
+
buildUpgradeSh,
|
|
560
|
+
buildCliUpgradeArtifacts,
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
})(typeof globalThis !== 'undefined' ? globalThis : {});
|
|
564
|
+
if (typeof exports !== 'undefined' && typeof globalThis !== 'undefined' && globalThis.__openclawInstall) {
|
|
565
|
+
Object.assign(exports, globalThis.__openclawInstall);
|
|
566
|
+
}
|