create-openclaw-bot 5.8.8 → 5.8.10

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 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.8.8-0EA5E9?style=for-the-badge" alt="Version 5.8.8" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.10-0EA5E9?style=for-the-badge" alt="Version 5.8.10" /></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>
@@ -23,12 +23,18 @@ A next-generation **Web UI Setup** and management dashboard that automates 100%
23
23
 
24
24
  ---
25
25
 
26
- ## 🆕 What's New in v5.8.8
26
+ ## 🆕 What's New in v5.8.10
27
27
 
28
- - 🔄 **Smart Header Update Button**: Instantly upgrades the setup wizard from the UI! The button queries the npm registry dynamically and only reveals itself when a newer release is published.
29
- - 📡 **Live Log-Streaming Upgrade**: Kicking off the update automatically executes the migration (running `git pull && npm install && npm run build` for Git clones, or `npm install -g create-openclaw-bot` for NPM installs) while streaming standard outputs in real-time straight to the dashboard's Logs terminal.
30
- - 🧹 **Restructured Dev/Test Environment**: Relocated all noisy build scripts (`build.mjs`, `bump-version.mjs`) and the test suite into the `.gitignore`'d `docs_dev/tests/` directory to preserve clean production builds.
31
- - ⚙️ **Robust Failure Rollback & Docker Fixes**: Strengthened installation crash recovery by inspecting process exit codes, and resolved dynamic Playwright browser bundle appending inside Dockerfiles.
28
+ ### 🚀 New Features: Deep Integration of Infographic Image Generator, Zalo Sticker & Auto-Tag Skills, and Workspace Docs Optimization
29
+
30
+ - **New: Infographic Poster Generator Skill**: Integrates automatic infographic and poster generation via 9Router API. Automatically generates the helper script `image-generator.js` (synchronizing API credentials from `openclaw.json`) and a comprehensive `SKILL.md` guiding agents on styling rules, Vietnamese font support, layouts, and image generation syntax.
31
+ - **New: Zalo Sticker & Auto-Tag Skill**:
32
+ - Automatically mentions the active sender in group chats (Agent doesn't need to manually prefix with `@Name` anymore, the system handles it).
33
+ - Enables agents to dynamically send Zalo stickers by appending `[Sticker: <keyword>]` at the end of their text responses.
34
+ - Automatically maps emotional keywords (such as `love`, `haha`, `ca khia`, `angry`, `thank you`, etc.) to actual Zalo sticker IDs.
35
+ - Generates the patch script `mentions.js` and a dedicated `SKILL.md` inside the agent's workspace.
36
+ - **Polish: Simplified TOOLS.md generation**: Streamlined the `TOOLS.md` generator to output a concise, static guide focusing on general principles and referencing the `./skills/` directory, rather than generating dynamic lists based on installed plugins.
37
+ - **Polish: Standardized Reference Docs list in AGENTS.md**: Updated the reference docs list in the generated `AGENTS.md` (for both single and relay variants in Vietnamese and English) to match the new structure, removing obsolete files (`TEAMS.md` for single-bot, `BROWSER.md`) and standardizing descriptions to keep exactly 9 core documents.
32
38
 
33
39
  <details>
34
40
  <summary><b>Previous: What's new in v5.8.0 (Major Release)</b></summary>
@@ -60,14 +66,19 @@ A next-generation **Web UI Setup** and management dashboard that automates 100%
60
66
  ## 🗺️ Quick Start
61
67
 
62
68
  ### 1️⃣ Method 1: Using NPX (Recommended)
69
+
63
70
  Open your terminal and run this single command:
71
+
64
72
  ```bash
65
73
  npx create-openclaw-bot
66
74
  ```
67
- *The bootstrapper will automatically download package files, launch the local backend server, and open the Setup UI in your browser.*
75
+
76
+ _The bootstrapper will automatically download package files, launch the local backend server, and open the Setup UI in your browser._
68
77
 
69
78
  ### 2️⃣ Method 2: Manual Clone
79
+
70
80
  If you downloaded or cloned the repository files locally:
81
+
71
82
  ```bash
72
83
  npm install
73
84
  npm start
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.8.8-0EA5E9?style=for-the-badge" alt="Version 5.8.8" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.10-0EA5E9?style=for-the-badge" alt="Version 5.8.10" /></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>
@@ -23,12 +23,18 @@ Trình cài đặt và quản trị **Web UI Setup** thế hệ mới giúp tự
23
23
 
24
24
  ---
25
25
 
26
- ## 🆕 Có gì mới trong v5.8.8
26
+ ## 🆕 Có gì mới trong v5.8.10
27
27
 
28
- - 🔄 **Nút cập nhật Header thông minh**: Nâng cấp trực tiếp setup wizard từ giao diện! Nút cập nhật tự truy vấn npm registry và chỉ hiển thị khi có phiên bản mới hơn.
29
- - 📡 **Nâng cấp Stream Log trực tiếp**: Khởi chạy cập nhật sẽ tự động nâng cấp (chạy `git pull && npm install && npm run build` cho bản Git, hoặc `npm install -g create-openclaw-bot` cho bản NPM) và đẩy dòng log theo thời gian thực về tab Logs.
30
- - 🧹 **Tái cấu trúc thư mục Dev/Test**: Di chuyển các file script build (`build.mjs`, `bump-version.mjs`) thư mục `tests` vào đường dẫn ẩn `.gitignore` `docs_dev/tests/` giúp bản build gọn gàng hơn.
31
- - ⚙️ **Tối ưu hóa Rollback lỗi & Docker**: Gia cố xử lý rollback khi cài đặt thất bại thông qua kiểm tra exit code của command, đồng thời sửa lỗi đóng gói thư viện browser trong Dockerfile.
28
+ ### 🚀 Tính năng mới: Tích hợp sâu Skill Tạo ảnh Infographic, Skill Sticker & Auto-Tag (Zalo) cùng Tối ưu hóa Workspace Docs
29
+
30
+ - **Mới: Hỗ trợ Skill Tạo ảnh Infographic chuyên nghiệp**: Tích hợp hoàn toàn công cụ tạo ảnh infographic, poster tự động thông qua API của 9Router. Tự động sinh mã nguồn script `image-generator.js` đồng bộ API credentials từ `openclaw.json` hướng dẫn `SKILL.md` cụ thể giúp Agent nắm vững cấu trúc prompt, font chữ tiếng Việt, layout và quy tắc thiết kế ảnh.
31
+ - **Mới: Hỗ trợ Skill Sticker & Auto-Tag (Zalo)**:
32
+ - Tự động tag tên người gửi tin nhắn gần nhất trong group chat Zalo (Agent không cần tự điền `@Tên` ở đầu câu trả lời nữa, hệ thống sẽ tự làm).
33
+ - Cho phép Agent gửi kèm Sticker Zalo trực tiếp trong câu trả lời thông qua thẻ `[Sticker: <từ_khóa>]` đặt ở cuối tin nhắn.
34
+ - Tích hợp bộ giải nghĩa từ khóa cảm xúc thông minh (như `love`, `haha`, `ca khia`, `angry`, `thank you`,...) để tự động map sang sticker Zalo phù hợp.
35
+ - Tự động sinh script vá logic `mentions.js` và tài liệu hướng dẫn `SKILL.md` trong workspace.
36
+ - **Tối ưu hóa: Đơn giản hóa sinh file TOOLS.md**: Điều chỉnh generator của `TOOLS.md` để sinh ra nội dung tĩnh gọn gàng, tập trung định hướng Agent đọc chi tiết các tài liệu hướng dẫn skill tương ứng nằm trong thư mục `./skills/`, loại bỏ các logic sinh danh sách động dựa trên plugin cũ.
37
+ - **Tối ưu hóa: Chuẩn hóa danh sách Tài liệu tham chiếu trong AGENTS.md**: Cập nhật danh sách tài liệu tham chiếu được tạo trong file `AGENTS.md` (cho cả 2 chế độ single/relay và cả tiếng Việt/tiếng Anh) để khớp chính xác cấu trúc mới gồm đúng 9 tài liệu cốt lõi, loại bỏ các file không còn phù hợp (`TEAMS.md` cho single-bot, `BROWSER.md`) và chuẩn hóa phần mô tả.
32
38
 
33
39
  <details>
34
40
  <summary><b>Trước đó: Có gì mới trong v5.8.0 (Bản nâng cấp lớn)</b></summary>
@@ -19,6 +19,31 @@ const { buildDockerArtifacts } = loadSharedModule('../setup/shared/docker-gen.js
19
19
  const { OPENCLAW_NPM_SPEC, NINE_ROUTER_NPM_SPEC, build9RouterProviderConfig, get9RouterBaseUrl } = loadSharedModule('../setup/shared/common-gen.js', '__openclawCommon');
20
20
  const dataExport = loadSharedModule('../setup/data/index.js', '__openclawData');
21
21
 
22
+ async function syncExecApprovals(projectDir, cfg) {
23
+ const openclawHome = join(projectDir, '.openclaw');
24
+ const agentMetas = (cfg.agents?.list || []).map((a) => ({ agentId: a.id }));
25
+ const approvals = buildExecApprovalsJson({ agentMetas });
26
+
27
+ const path1 = join(openclawHome, 'exec-approvals.json');
28
+ const nestedDir = join(openclawHome, '.openclaw');
29
+ const path2 = join(nestedDir, 'exec-approvals.json');
30
+
31
+ await fsp.mkdir(openclawHome, { recursive: true }).catch(() => {});
32
+ await fsp.writeFile(path1, JSON.stringify(approvals, null, 2), 'utf8');
33
+
34
+ await fsp.mkdir(nestedDir, { recursive: true }).catch(() => {});
35
+ let existing = {};
36
+ if (existsSync(path2)) {
37
+ try {
38
+ existing = JSON.parse(await fsp.readFile(path2, 'utf8'));
39
+ } catch (e) {}
40
+ }
41
+ if (existing.socket) {
42
+ approvals.socket = existing.socket;
43
+ }
44
+ await fsp.writeFile(path2, JSON.stringify(approvals, null, 2), 'utf8');
45
+ }
46
+
22
47
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
48
  const WEB_DIR = resolve(__dirname, '../web');
24
49
  const SETUP_VERSION = (() => { try { return JSON.parse(fs.readFileSync(resolve(__dirname, '../../package.json'), 'utf8')).version || '0.0.0'; } catch { return '0.0.0'; } })();
@@ -153,7 +178,9 @@ function recommendedMode(osChoice) {
153
178
  function commandExists(cmd, args = ['--version']) {
154
179
  return new Promise((resolve) => {
155
180
  const shell = process.platform === 'win32';
156
- execFile(resolveBinPath(cmd), args, { windowsHide: true, timeout: 5000, shell }, (err, stdout, stderr) => {
181
+ const rawBin = resolveBinPath(cmd);
182
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
183
+ execFile(bin, args, { windowsHide: true, timeout: 5000, shell }, (err, stdout, stderr) => {
157
184
  resolve({ ok: !err, output: String(stdout || stderr || '').trim() });
158
185
  });
159
186
  });
@@ -162,7 +189,10 @@ function commandExists(cmd, args = ['--version']) {
162
189
  function run(cmd, args, opts = {}) {
163
190
  return new Promise((resolve, reject) => {
164
191
  sendLog(`$ ${cmd} ${args.join(' ')}`);
165
- const child = spawn(resolveBinPath(cmd), args, { cwd: opts.cwd, shell: process.platform === 'win32', env: { ...process.env, ...(opts.env || {}) } });
192
+ const shell = process.platform === 'win32';
193
+ const rawBin = resolveBinPath(cmd);
194
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
195
+ const child = spawn(bin, args, { cwd: opts.cwd, shell, env: { ...process.env, ...(opts.env || {}) } });
166
196
  let stdout = '';
167
197
  let resolved = false;
168
198
  child.stdout.on('data', (d) => {
@@ -192,9 +222,12 @@ function run(cmd, args, opts = {}) {
192
222
 
193
223
  function startDetached(cmd, args, opts = {}) {
194
224
  sendLog(`$ ${cmd} ${args.join(' ')} &`);
195
- const child = spawn(resolveBinPath(cmd), args, {
225
+ const shell = process.platform === 'win32';
226
+ const rawBin = resolveBinPath(cmd);
227
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
228
+ const child = spawn(bin, args, {
196
229
  cwd: opts.cwd,
197
- shell: process.platform === 'win32',
230
+ shell,
198
231
  detached: true,
199
232
  stdio: 'ignore',
200
233
  windowsHide: opts.windowsHide ?? true,
@@ -253,9 +286,12 @@ async function resolveProjectRuntimeVersions(projectDir, mode = state.mode || 'd
253
286
 
254
287
  function runStreamed(cmd, args, opts = {}) {
255
288
  sendLog(`$ ${cmd} ${args.join(' ')}`);
256
- const child = spawn(cmd, args, {
289
+ const shell = opts.shell ?? process.platform === 'win32';
290
+ const rawBin = resolveBinPath(cmd);
291
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
292
+ const child = spawn(bin, args, {
257
293
  cwd: opts.cwd,
258
- shell: opts.shell ?? process.platform === 'win32',
294
+ shell,
259
295
  windowsHide: opts.windowsHide ?? true,
260
296
  env: { ...process.env, ...(opts.env || {}) },
261
297
  });
@@ -268,9 +304,12 @@ function runStreamed(cmd, args, opts = {}) {
268
304
 
269
305
  function runStreamedToLogFile(cmd, args, logFile, opts = {}) {
270
306
  sendLog(`$ ${cmd} ${args.join(' ')}`);
271
- const child = spawn(cmd, args, {
307
+ const shell = opts.shell ?? process.platform === 'win32';
308
+ const rawBin = resolveBinPath(cmd);
309
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
310
+ const child = spawn(bin, args, {
272
311
  cwd: opts.cwd,
273
- shell: opts.shell ?? process.platform === 'win32',
312
+ shell,
274
313
  windowsHide: opts.windowsHide ?? true,
275
314
  env: { ...process.env, ...(opts.env || {}) },
276
315
  });
@@ -293,9 +332,12 @@ function runCapture(cmd, args, opts = {}) {
293
332
  return new Promise((resolve) => {
294
333
  let stdout = '';
295
334
  let stderr = '';
296
- const child = spawn(resolveBinPath(cmd), args, {
335
+ const shell = opts.shell ?? process.platform === 'win32';
336
+ const rawBin = resolveBinPath(cmd);
337
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
338
+ const child = spawn(bin, args, {
297
339
  cwd: opts.cwd,
298
- shell: opts.shell ?? process.platform === 'win32',
340
+ shell,
299
341
  windowsHide: opts.windowsHide ?? true,
300
342
  env: { ...process.env, ...(opts.env || {}) },
301
343
  });
@@ -947,6 +989,7 @@ async function deleteBotInProject(projectDir, agentId) {
947
989
 
948
990
  if (existsSync(cfgPath)) await fsp.copyFile(cfgPath, `${cfgPath}.bak`);
949
991
  await fsp.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf8');
992
+ await syncExecApprovals(projectDir, cfg);
950
993
 
951
994
  // Also clear bot tokens in .env files if deleting the primary bot
952
995
  if (agentId === 'bot') {
@@ -1098,6 +1141,7 @@ async function createBotInProject(projectDir, body = {}, runtime = {}) {
1098
1141
  validateOpenclawConfig(cfg);
1099
1142
  if (existsSync(cfgPath)) await fsp.copyFile(cfgPath, `${cfgPath}.bak`);
1100
1143
  await fsp.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf8');
1144
+ await syncExecApprovals(projectDir, cfg);
1101
1145
 
1102
1146
  const hasScheduler = !!(cfg.tools?.alsoAllow || []).includes('group:automation');
1103
1147
  const hasImageGen = !!(cfg.skills?.entries?.['image-gen']?.enabled);
@@ -1109,7 +1153,7 @@ async function createBotInProject(projectDir, body = {}, runtime = {}) {
1109
1153
  emoji,
1110
1154
  userInfo,
1111
1155
  agentWorkspaceDir: workspaceDir,
1112
- workspacePath: `.openclaw/${workspaceDir}`,
1156
+ workspacePath: `/home/node/project/.openclaw/${workspaceDir}`,
1113
1157
  channel,
1114
1158
  hasZaloMod: channel === 'zalo-personal',
1115
1159
  hasZaloSticker: channel === 'zalo-personal',
@@ -1175,6 +1219,7 @@ async function updateBotInProject(projectDir, agentId, body = {}, runtime = {})
1175
1219
  validateOpenclawConfig(cfg);
1176
1220
  if (existsSync(cfgPath)) await fsp.copyFile(cfgPath, `${cfgPath}.bak`);
1177
1221
  await fsp.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf8');
1222
+ await syncExecApprovals(projectDir, cfg);
1178
1223
 
1179
1224
  // Synchronize the token to .env files for the primary bot to ensure Docker picks it up
1180
1225
  if (agentId === 'bot') {
@@ -1213,7 +1258,7 @@ async function updateBotInProject(projectDir, agentId, body = {}, runtime = {})
1213
1258
  emoji,
1214
1259
  userInfo,
1215
1260
  agentWorkspaceDir: workspaceDir,
1216
- workspacePath: `.openclaw/${workspaceDir}`,
1261
+ workspacePath: `/home/node/project/.openclaw/${workspaceDir}`,
1217
1262
  channel,
1218
1263
  hasZaloMod: channel === 'zalo-personal',
1219
1264
  hasZaloSticker: channel === 'zalo-personal',
@@ -1731,11 +1776,9 @@ async function writeCoreProject({ projectDir, osChoice, mode, gatewayPort = 1878
1731
1776
  const common = { channelKey: 'telegram', providerKey: '9router', model: DEFAULT_MODEL, deployMode: mode, osChoice, selectedSkills, skills: dataExport.SKILLS || [], agentMetas, gatewayPort, routerPort };
1732
1777
  const cfg = buildOpenclawJson(common);
1733
1778
  const env = buildEnvFileContent({ ...common, apiKey: '', botToken: '' });
1734
- const approvals = buildExecApprovalsJson({ agentMetas });
1735
-
1736
1779
  await fsp.writeFile(join(openclawHome, 'openclaw.json'), JSON.stringify(cfg, null, 2), 'utf8');
1737
1780
  await fsp.writeFile(join(projectDir, '.env'), env, 'utf8');
1738
- await fsp.writeFile(join(openclawHome, 'exec-approvals.json'), JSON.stringify(approvals, null, 2), 'utf8');
1781
+ await syncExecApprovals(projectDir, cfg);
1739
1782
 
1740
1783
  if (mode === 'docker') {
1741
1784
  const projectName = slugify(basename(projectDir)) || 'bot';
@@ -2996,10 +3039,13 @@ function restartInstaller() {
2996
3039
  args.push('--no-open');
2997
3040
  }
2998
3041
 
2999
- const child = spawn(process.argv[0], [entryFile, ...args], {
3042
+ const shell = process.platform === 'win32';
3043
+ const rawBin = process.argv[0];
3044
+ const bin = shell && rawBin.includes(' ') && !rawBin.startsWith('"') ? `"${rawBin}"` : rawBin;
3045
+ const child = spawn(bin, [entryFile, ...args], {
3000
3046
  detached: true,
3001
3047
  stdio: 'inherit',
3002
- shell: process.platform === 'win32'
3048
+ shell
3003
3049
  });
3004
3050
  child.unref();
3005
3051
 
@@ -3020,7 +3066,7 @@ export async function startLocalInstaller({ host = '127.0.0.1', preferredPort =
3020
3066
  if (openBrowser) openUrl(url);
3021
3067
  }
3022
3068
 
3023
- export { createBotInProject, deleteBotInProject, validateOpenclawConfig, startZaloUserLogin, readBotCredentials, resolveProject9RouterApiKey };
3069
+ export { createBotInProject, updateBotInProject, deleteBotInProject, validateOpenclawConfig, startZaloUserLogin, readBotCredentials, resolveProject9RouterApiKey };
3024
3070
 
3025
3071
 
3026
3072