create-openclaw-bot 5.1.12 β†’ 5.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,125 +1,125 @@
1
1
  # Changelog (English)
2
2
 
3
-
4
-
5
- ## [5.1.12] β€” 2026-04-07
6
-
7
- ### 🧠 Expanded Skills & Auto-Select Multi-Bot Relay Plugin
8
-
9
- - **3-Column Skill Grid**: Skill cards now display 3 per row instead of 4 β€” wider cards, better readability.
10
- - **7 New ClawHub Skills**: Added `Web Search`, `GitHub`, `Google Calendar`, `Google Drive`, `Google Sheets`, `Notion`, `Slack` β€” covering the most common productivity workflows available on the OpenClaw dashboard.
11
- - **Telegram Multi-Bot Relay Auto-Select**: When multiple Telegram bots are selected (botCount β‰₯ 2), the `telegram-multibot-relay` plugin is automatically checked and written to `openclaw.json β†’ plugins.entries`. Switching back to 1 bot deselects it.
12
- - **Plugin Selections β†’ openclaw.json**: All plugins selected by the user (Voice Call, Matrix, MS Teams, Nostr...) are now injected into `plugins.entries` so the OpenClaw Dashboard receives the correct `enabled` state. Unselected = disabled.
13
- - **Fix Step 3 "Next" disabled**: Removed mandatory `cfg-user-info` requirement (it's optional), fixed multi-bot validation to use `cfg-bot-tab-name`.
14
- - **Fix Step 4 multi-bot token validation**: Now validates `key-bot-token-0` instead of `key-bot-token` in Telegram multi-bot mode.
15
- - **Fix native multi-bot AGENTS.md missing security rules**: Security rules are now appended to each bot's AGENTS.md during native multi-bot deployment.
16
-
17
- ## [5.1.11] β€” 2026-04-07
18
-
19
- ### 🌟 Zalo Personal DM Policy
20
-
21
- - **Open Zalo Inboxes**: The default `dmPolicy` for Zalo Personal deployments has been changed from `pairing` to `open`. This allows any user on the Zalo network to interact with the AI assistant immediately without requiring explicit device pairing approvals natively.
22
-
23
-
24
- ## [5.1.10] β€” 2026-04-07
25
-
26
- ### 🌟 Native UI Auto-Approve Bypasser
27
-
28
- - **Native PM2 Auto-Approve Loop**: The strict `pairing required` security feature mandates that all users manually execute an approval command in their terminal for new web dashboard authentications. While Docker deployments already included an automated bypass, the Native setup did not. This release introduces a dedicated `auto-approve` PM2 background daemon that infinitely polls and accepts new device keys, delivering a frictionless, zero-touch login experience identical to Docker deployments.
29
-
30
-
31
- ## [5.1.9] β€” 2026-04-07
32
-
33
- ### 🌟 Strict Schema Fix & WebCrypto UX Improvement
34
-
35
- - **Revert Unrecognized Config Key**: OpenClaw v2026.x.x enforces strict Zod schema validation. The previously injected `requireDeviceIdentity` flag caused an immediate startup crash (`Config invalid`). This version surgically removes the offending flag, ensuring the gateway boots successfully.
36
- - **Dynamic SSH Tunnel Helper**: Since WebCrypto strictly demands a secure context (HTTPS/localhost), accessing the dashboard via raw VPS IP triggers a `1008` error natively. The CLI now dynamically generates and prints the exact `ssh -L 18791:localhost:18791 ...` Port Forwarding command right in the terminal, guaranteeing a flawless, secure login experience for remote server operators without needing SSL.
37
-
38
-
39
- ## [5.1.8] β€” 2026-04-07
40
-
41
- ### 🌟 Dashboard VPS Connectivity & Token Login Fix
42
-
43
- - **Fix `requireDeviceIdentity` Error on VPS**: OpenClaw's WebCrypto E2E identity check inherently demands a secure browser context (HTTPS or localhost). For raw IPv4 VPS deployments, the `crypto.subtle` browser limitation causes WebSocket `code=1008` rejection upon token login. The setup tool now seamlessly injects `requireDeviceIdentity: false` into the `gateway.controlUi` configuration, granting you flawless remote login capabilities over standard HTTP networks.
44
- - **Dynamic Terminal URLs**: The programmatic CLI will now intelligently scan and log your external, reachable IPv4 addresses in the console output alongside the local endpoints. This eliminates confusion and guarantees that the automatically generated tokenized dashboard links are ready for immediate copy-pasting.
45
-
46
-
47
- ## [5.1.7] β€” 2026-04-07
48
-
49
- ### 🌟 Fix Control UI CORS & Native 9Router Path Resolution
50
-
51
- - **Fix Control UI CORS Rejections**: OpenClaw v2026.3.x strict CORS policies blocked remote dashboard access. The setup configuration and Docker patching scripts now automatically resolve all active IPv4 interfaces (`os.networkInterfaces()`) alongside localhost to pre-populate the `gateway.controlUi.allowedOrigins` array. This ensures the Web UI works flawlessly out-of-the-box on remote VPS instances.
52
- - **Improved Native PM2 Path Resolution**: To prevent PM2 `$PATH` lookup failures with `nvm` on Linux, the script now bypasses the OS `9router` binary wrapper entirely. Instead, it computes the exact explicit path using `$(npm root -g)/9router/app/server.js` and executes it directly via the NodeJS interpreter.
53
-
54
-
55
- ## [5.1.6] β€” 2026-04-07
56
-
57
- ### 🐞 Fix PM2 SIGKILL on Native VPS Installs
58
-
59
- - **Fix `PM2 SIGKILL` Error**: Removed the `-t` (interactive TTY) flag from all background `9router` launches. This terminal-dependent flag could cause PM2 to hang and aggressively SIGKILL the spawned process on headless VPS environments.
60
- - **Robust PM2 Sync Helper**: Added a two-stage fallback for the 9Router smart-route sync script. If PM2 encounters `SIGKILL` or memory limits while spawning the sync helper, the setup gracefully falls back to a background `nohup node ... &` process instead of throwing a hard exception. If both fail, it logs a warning but allows the overall OpenClaw setup to finish successfully.
61
-
62
-
63
- ## [5.1.5] β€” 2026-04-06
64
-
65
- ### 🐞 Fix Native PM2 9Router Startup
66
-
67
- - **Fix**: Replaced shell string execution (`execSync`) with strict array arguments (`execFileSync`) when starting 9Router and its background sync script via PM2 on native systems. This guarantees reliable process spawning across both Linux (VPS) and Windows environments without PM2 shell-parsing errors on quotes or path spaces.
68
- - **Improved**: PM2 now explicitly runs the global `9router` binary via `--interpreter none` and the sync script via the current NodeJS runtime using `--interpreter process.execPath`.
69
-
70
-
71
- ## [5.1.4] β€” 2026-04-06
72
-
73
- ### 🐞 Fix CLI Startup BOM Error & Improve Docker Timeout Patch
74
-
75
- - **Fix CLI BOM**: Removed the unexpected byte order mark (BOM) `\uFEFF` at the beginning of `cli.js` which could cause the shebang `#!/usr/bin/env node` to fail resolving or cause SyntaxErrors in certain environments
76
- - **Improve Docker Timeout Patching**: The backend timeout override injection (`300s`) during Docker build now defensively scans all `.js` files in the `openclaw/dist` directory rather than trying to fuzzy-find a specific `gateway-cli-*` hash. This ensures the patch succeeds across different OpenClaw backend builds without noisy console warnings
77
-
78
-
79
- ## [5.1.3] β€” 2026-04-06
80
-
81
- ### 🐜 Fix Docker Compose Variable Interpolation Leak
82
-
83
- The previous base64 fix introduced a regression where the template literal `${Buffer.from(...)}` was mistakenly escaped in the composition script, causing the literal string to leak into `docker-compose.yml` instead of the actual base64 computed value.
84
-
85
- - **Fix**: Precompute the base64 string completely in JavaScript (`const syncScriptBase64 = encodeBase64Utf8(syncScript)`) before injecting it into the compose template
86
- - This guarantees the generated compose file receives the raw base64 string without any template interpolator conflicts
87
- - Also cleans up testing logic validating these fixes
88
-
89
-
90
- ## [5.1.2] β€” 2026-04-06
91
-
92
- ### πŸ› Fix Shell Injection: Sync Script Now Uses Base64 Encoding
93
-
94
- The `node -e "...JSON.stringify(script)..."` approach caused `/bin/sh: Syntax error: "(" unexpected` because `JSON.stringify` produces a double-quoted string that breaks out of the surrounding `node -e "..."` shell argument.
95
-
96
- - **Fix**: sync script content is now **base64-encoded at compose-generation time** using `Buffer.from(script).toString('base64')`
97
- - The generated entrypoint becomes: `node -e "require('fs').writeFileSync('/tmp/sync.js',Buffer.from('<b64>','base64').toString())"`
98
- - Base64 output contains only `[A-Za-z0-9+/=]` β€” zero shell quoting issues, works in YAML `|` blocks without escaping
99
- - Applies to all compose generation paths: Docker web wizard (`setup.js` Γ— 2) and Docker CLI (`cli.js` Γ— 2)
100
-
101
-
102
- ## [5.1.1] β€” 2026-04-06
103
-
104
- ### πŸ”§ 9Router Smart-Route Sync β€” Stable via API
105
-
106
- Fixed a critical bug where the sync script could not detect active providers, causing all requests to fall back to `openai` (resulting in `404 No active credentials`).
107
-
108
- - **Root cause**: sync script read `db.providerConnections` from `db.json`, but this field does not exist in 9Router v0.3.79+ β€” connections are only available via the REST API
109
- - **Fix**: sync script now calls `fetch('http://localhost:20128/api/providers')` β†’ `d.connections[]` to detect active providers dynamically
110
- - **Fix**: replaced fragile `cat << 'CLAWEOF'` heredoc injection (which caused `const p=undefined`) with `node -e require('fs').writeFileSync(...)` β€” zero quoting issues in YAML+shell
111
- - **Fix**: `build9RouterSmartRouteSyncScript()` in CLI docker flow now correctly passes `'/root/.9router/db.json'` as the db path
112
- - Applies to all three sync script locations: Docker web wizard (`setup.js`), Docker CLI (`cli.js`), and native (`cli.js`)
113
-
114
- ### πŸ“± Zalo Pairing β€” Auto-Approve During Gateway Run
115
-
116
- - Previously, auto-approve only ran during the initial login flow; new pairing requests while the gateway was already running were silently ignored
117
- - **Fix**: `openclaw gateway run` for Zalo Personal now pipes stdout/stderr and auto-calls `openclaw pairing approve zalouser <code>` whenever a new pairing code is detected
118
-
119
- ### 🧹 Cleaner Docker CLI Output
120
-
121
- - Removed redundant post-setup instructions (`docker compose build`, `openclaw gateway`, PM2 commands) that appeared after Docker auto-build; Docker mode is self-contained and needs no manual follow-up steps
122
-
3
+ ## [5.1.13] β€” 2026-04-08
4
+
5
+ ### πŸ› macOS Install Fixes & Wizard Stability
6
+
7
+ - **Fix macOS `mkdir: : No such file or directory`**: `generateSetupScript` was using `\${dir}` / `\${path}` (escaped), which created empty bash variables β€” now JS-interpolated so actual file paths are written correctly.
8
+ - **Fix macOS Docker script**: Added `docker info` daemon check before `docker compose up`; Docker mode now correctly calls `docker compose up` instead of `openclaw gateway run`.
9
+ - **Fix macOS Native npm prefix**: Removed `npm config set prefix` which breaks Homebrew-managed Node.js. Now uses `export npm_config_prefix` (per-session env var) + `sudo npm install -g` fallback.
10
+ - **Fix `window.__saveBotTabPersona is not a function`**: Added the missing `__saveBotTabPersona` function that HTML was calling but was never defined in `setup.js`.
11
+ - **Fix Step 3 Next button in 1-bot mode**: `bindFormEvents` now syncs `cfg-name` input directly to `state.config.botName` and `state.bots[0].name` on every keystroke, then calls `updateNavButtons()` β€” Next button reacts instantly without requiring navigation.
12
+ - **Fix persona per-bot isolation**: `saveBotTabMeta` and `syncBotTabMeta` now save/restore the `cfg-bot-tab-persona` field per-bot. Switching tabs correctly shows/hides each bot's persona; the value is persisted in `state.bots[i].persona` and used correctly in generated `.md` files.
13
+ - **Fix cli.js macOS global npm**: `ensureUserWritableGlobalNpm` skips `npm config set prefix` on darwin; `installGlobalPackage` adds `sudo npm install -g` as macOS fallback.
14
+
15
+ ## [5.1.12] β€” 2026-04-07
16
+
17
+ ### 🧠 Expanded Skills & Auto-Select Multi-Bot Relay Plugin
18
+
19
+ - **3-Column Skill Grid**: Skill cards now display 3 per row instead of 4 β€” wider cards, better readability.
20
+ - **7 New ClawHub Skills**: Added `Web Search`, `Notion`, `Slack` β€” covering the most common productivity workflows available on the OpenClaw dashboard.
21
+ - **Telegram Multi-Bot Relay Auto-Select**: When multiple Telegram bots are selected (botCount β‰₯ 2), the `telegram-multibot-relay` plugin is automatically checked and written to `openclaw.json β†’ plugins.entries`. Switching back to 1 bot deselects it.
22
+ - **Plugin Selections β†’ openclaw.json**: All plugins selected by the user (Voice Call, Matrix, MS Teams, Nostr...) are now injected into `plugins.entries` so the OpenClaw Dashboard receives the correct `enabled` state. Unselected = disabled.
23
+ - **Fix Step 3 "Next" disabled**: Removed mandatory `cfg-user-info` requirement (it's optional), fixed multi-bot validation to use `cfg-bot-tab-name`.
24
+ - **Fix Step 4 multi-bot token validation**: Now validates `key-bot-token-0` instead of `key-bot-token` in Telegram multi-bot mode.
25
+ - **Fix native multi-bot AGENTS.md missing security rules**: Security rules are now appended to each bot's AGENTS.md during native multi-bot deployment.
26
+
27
+ ## [5.1.11] β€” 2026-04-07
28
+
29
+ ### 🌟 Zalo Personal DM Policy
30
+
31
+ - **Open Zalo Inboxes**: The default `dmPolicy` for Zalo Personal deployments has been changed from `pairing` to `open`. This allows any user on the Zalo network to interact with the AI assistant immediately without requiring explicit device pairing approvals natively.
32
+
33
+ ## [5.1.10] β€” 2026-04-07
34
+
35
+ ### 🌟 Native UI Auto-Approve Bypasser
36
+
37
+ - **Native PM2 Auto-Approve Loop**: The strict `pairing required` security feature mandates that all users manually execute an approval command in their terminal for new web dashboard authentications. While Docker deployments already included an automated bypass, the Native setup did not. This release introduces a dedicated `auto-approve` PM2 background daemon that infinitely polls and accepts new device keys, delivering a frictionless, zero-touch login experience identical to Docker deployments.
38
+
39
+ ## [5.1.9] β€” 2026-04-07
40
+
41
+ ### 🌟 Strict Schema Fix & WebCrypto UX Improvement
42
+
43
+ - **Revert Unrecognized Config Key**: OpenClaw v2026.x.x enforces strict Zod schema validation. The previously injected `requireDeviceIdentity` flag caused an immediate startup crash (`Config invalid`). This version surgically removes the offending flag, ensuring the gateway boots successfully.
44
+ - **Dynamic SSH Tunnel Helper**: Since WebCrypto strictly demands a secure context (HTTPS/localhost), accessing the dashboard via raw VPS IP triggers a `1008` error natively. The CLI now dynamically generates and prints the exact `ssh -L 18791:localhost:18791 ...` Port Forwarding command right in the terminal, guaranteeing a flawless, secure login experience for remote server operators without needing SSL.
45
+
46
+ ## [5.1.8] β€” 2026-04-07
47
+
48
+ ### 🌟 Dashboard VPS Connectivity & Token Login Fix
49
+
50
+ - **Fix `requireDeviceIdentity` Error on VPS**: OpenClaw's WebCrypto E2E identity check inherently demands a secure browser context (HTTPS or localhost). For raw IPv4 VPS deployments, the `crypto.subtle` browser limitation causes WebSocket `code=1008` rejection upon token login. The setup tool now seamlessly injects `requireDeviceIdentity: false` into the `gateway.controlUi` configuration, granting you flawless remote login capabilities over standard HTTP networks.
51
+ - **Dynamic Terminal URLs**: The programmatic CLI will now intelligently scan and log your external, reachable IPv4 addresses in the console output alongside the local endpoints. This eliminates confusion and guarantees that the automatically generated tokenized dashboard links are ready for immediate copy-pasting.
52
+
53
+ ## [5.1.7] β€” 2026-04-07
54
+
55
+ ### 🌟 Fix Control UI CORS & Native 9Router Path Resolution
56
+
57
+ - **Fix Control UI CORS Rejections**: OpenClaw v2026.3.x strict CORS policies blocked remote dashboard access. The setup configuration and Docker patching scripts now automatically resolve all active IPv4 interfaces (`os.networkInterfaces()`) alongside localhost to pre-populate the `gateway.controlUi.allowedOrigins` array. This ensures the Web UI works flawlessly out-of-the-box on remote VPS instances.
58
+ - **Improved Native PM2 Path Resolution**: To prevent PM2 `$PATH` lookup failures with `nvm` on Linux, the script now bypasses the OS `9router` binary wrapper entirely. Instead, it computes the exact explicit path using `$(npm root -g)/9router/app/server.js` and executes it directly via the NodeJS interpreter.
59
+
60
+ ## [5.1.6] β€” 2026-04-07
61
+
62
+ ### 🐞 Fix PM2 SIGKILL on Native VPS Installs
63
+
64
+ - **Fix `PM2 SIGKILL` Error**: Removed the `-t` (interactive TTY) flag from all background `9router` launches. This terminal-dependent flag could cause PM2 to hang and aggressively SIGKILL the spawned process on headless VPS environments.
65
+ - **Robust PM2 Sync Helper**: Added a two-stage fallback for the 9Router smart-route sync script. If PM2 encounters `SIGKILL` or memory limits while spawning the sync helper, the setup gracefully falls back to a background `nohup node ... &` process instead of throwing a hard exception. If both fail, it logs a warning but allows the overall OpenClaw setup to finish successfully.
66
+
67
+ ## [5.1.5] β€” 2026-04-06
68
+
69
+ ### 🐞 Fix Native PM2 9Router Startup
70
+
71
+ - **Fix**: Replaced shell string execution (`execSync`) with strict array arguments (`execFileSync`) when starting 9Router and its background sync script via PM2 on native systems. This guarantees reliable process spawning across both Linux (VPS) and Windows environments without PM2 shell-parsing errors on quotes or path spaces.
72
+ - **Improved**: PM2 now explicitly runs the global `9router` binary via `--interpreter none` and the sync script via the current NodeJS runtime using `--interpreter process.execPath`.
73
+
74
+ ## [5.1.4] β€” 2026-04-06
75
+
76
+ ### 🐞 Fix CLI Startup BOM Error & Improve Docker Timeout Patch
77
+
78
+ - **Fix CLI BOM**: Removed the unexpected byte order mark (BOM) `\uFEFF` at the beginning of `cli.js` which could cause the shebang `#!/usr/bin/env node` to fail resolving or cause SyntaxErrors in certain environments
79
+ - **Improve Docker Timeout Patching**: The backend timeout override injection (`300s`) during Docker build now defensively scans all `.js` files in the `openclaw/dist` directory rather than trying to fuzzy-find a specific `gateway-cli-*` hash. This ensures the patch succeeds across different OpenClaw backend builds without noisy console warnings
80
+
81
+ ## [5.1.3] β€” 2026-04-06
82
+
83
+ ### 🐜 Fix Docker Compose Variable Interpolation Leak
84
+
85
+ The previous base64 fix introduced a regression where the template literal `${Buffer.from(...)}` was mistakenly escaped in the composition script, causing the literal string to leak into `docker-compose.yml` instead of the actual base64 computed value.
86
+
87
+ - **Fix**: Precompute the base64 string completely in JavaScript (`const syncScriptBase64 = encodeBase64Utf8(syncScript)`) before injecting it into the compose template
88
+ - This guarantees the generated compose file receives the raw base64 string without any template interpolator conflicts
89
+ - Also cleans up testing logic validating these fixes
90
+
91
+ ## [5.1.2] β€” 2026-04-06
92
+
93
+ ### πŸ› Fix Shell Injection: Sync Script Now Uses Base64 Encoding
94
+
95
+ The `node -e "...JSON.stringify(script)..."` approach caused `/bin/sh: Syntax error: "(" unexpected` because `JSON.stringify` produces a double-quoted string that breaks out of the surrounding `node -e "..."` shell argument.
96
+
97
+ - **Fix**: sync script content is now **base64-encoded at compose-generation time** using `Buffer.from(script).toString('base64')`
98
+ - The generated entrypoint becomes: `node -e "require('fs').writeFileSync('/tmp/sync.js',Buffer.from('<b64>','base64').toString())"`
99
+ - Base64 output contains only `[A-Za-z0-9+/=]` β€” zero shell quoting issues, works in YAML `|` blocks without escaping
100
+ - Applies to all compose generation paths: Docker web wizard (`setup.js` Γ— 2) and Docker CLI (`cli.js` Γ— 2)
101
+
102
+ ## [5.1.1] β€” 2026-04-06
103
+
104
+ ### πŸ”§ 9Router Smart-Route Sync β€” Stable via API
105
+
106
+ Fixed a critical bug where the sync script could not detect active providers, causing all requests to fall back to `openai` (resulting in `404 No active credentials`).
107
+
108
+ - **Root cause**: sync script read `db.providerConnections` from `db.json`, but this field does not exist in 9Router v0.3.79+ β€” connections are only available via the REST API
109
+ - **Fix**: sync script now calls `fetch('http://localhost:20128/api/providers')` β†’ `d.connections[]` to detect active providers dynamically
110
+ - **Fix**: replaced fragile `cat << 'CLAWEOF'` heredoc injection (which caused `const p=undefined`) with `node -e require('fs').writeFileSync(...)` β€” zero quoting issues in YAML+shell
111
+ - **Fix**: `build9RouterSmartRouteSyncScript()` in CLI docker flow now correctly passes `'/root/.9router/db.json'` as the db path
112
+ - Applies to all three sync script locations: Docker web wizard (`setup.js`), Docker CLI (`cli.js`), and native (`cli.js`)
113
+
114
+ ### πŸ“± Zalo Pairing β€” Auto-Approve During Gateway Run
115
+
116
+ - Previously, auto-approve only ran during the initial login flow; new pairing requests while the gateway was already running were silently ignored
117
+ - **Fix**: `openclaw gateway run` for Zalo Personal now pipes stdout/stderr and auto-calls `openclaw pairing approve zalouser <code>` whenever a new pairing code is detected
118
+
119
+ ### 🧹 Cleaner Docker CLI Output
120
+
121
+ - Removed redundant post-setup instructions (`docker compose build`, `openclaw gateway`, PM2 commands) that appeared after Docker auto-build; Docker mode is self-contained and needs no manual follow-up steps
122
+
123
123
  ## [5.1.0] β€” 2026-04-07
124
124
 
125
125
  ### πŸ€– Zalo Personal Login Improvements
package/CHANGELOG.vi.md CHANGED
@@ -1,124 +1,123 @@
1
1
  # Changelog (TiαΊΏng Việt)
2
2
 
3
-
4
-
5
- ## [5.1.12] β€” 2026-04-07
6
-
7
- ### 🧠 ThΓͺm Skills & Tα»± Δ‘α»™ng chọn Plugin Relay
8
-
9
- - **Grid Skills 3 cα»™t**: Layout mα»›i 3 card/hΓ ng thay vΓ¬ 4, card rα»™ng rΓ£i hΖ‘n, dα»… đọc hΖ‘n.
10
- - **7 Skills mα»›i tα»« ClawHub**: Bα»• sung Δ‘αΊ§y Δ‘α»§ `Web Search`, `GitHub`, `Google Calendar`, `Google Drive`, `Google Sheets`, `Notion`, `Slack` β€” phα»§ khαΊ―p cΓ‘c tΓ‘c vα»₯ nΔƒng suαΊ₯t phα»• biαΊΏn nhαΊ₯t trΓͺn OpenClaw dashboard.
11
- - **Plugin Telegram Multi-Bot Relay tα»± Δ‘α»™ng**: Khi chọn nhiều bot Telegram (botCount β‰₯ 2), plugin `telegram-multibot-relay` được tα»± Δ‘α»™ng tick chọn vΓ  ghi vΓ o `openclaw.json β†’ plugins.entries`. Khi quay về 1 bot, plugin bα»‹ bỏ chọn.
12
- - **Plugin selections β†’ openclaw.json**: TαΊ₯t cαΊ£ plugin được user chọn (Voice Call, Matrix, MS Teams, Nostr...) đều được inject vΓ o `plugins.entries` để Dashboard OpenClaw nhαΊ­n trαΊ‘ng thΓ‘i `enabled` Δ‘ΓΊng. KhΓ΄ng chọn = khΓ΄ng bαΊ­t.
13
- - **Fix Step 3 "TiαΊΏp theo" bα»‹ disabled**: Bỏ yΓͺu cαΊ§u bαΊ―t buα»™c `cfg-user-info` (optional), sα»­a multi-bot check dΓΉng `cfg-bot-tab-name`.
14
- - **Fix Step 4 multi-bot token**: Validate `key-bot-token-0` thay vì `key-bot-token` khi multi-bot Telegram.
15
- - **Fix AGENTS.md native multi-bot thiαΊΏu quy tαΊ―c bαΊ£o mαΊ­t**: Inject `securityRules` vΓ o cuα»‘i AGENTS.md cα»§a tα»«ng bot trong native multi-bot deployment.
16
-
17
-
18
- ### 🌟 Đổi ChΓ­nh SΓ‘ch BαΊ£o MαΊ­t Zalo Personal
19
-
20
- - **ThαΊ£ Ga Inbox Zalo CαΊ§m Tay**: Lược bỏ rΓ o cαΊ£n duyệt bαΊ£o mαΊ­t cα»§a Zalo Personal. ThΓ΄ng sα»‘ `dmPolicy` trΓͺn cΓ i Δ‘αΊ·t Zalo cΓ‘ nhΓ’n Δ‘Γ£ được chuyển mαΊ·c Δ‘α»‹nh tα»« `pairing` sang `open`. BΓ’y giờ bαΊ₯t cα»© ai trΓͺn mαΊ‘ng lΖ°α»›i Zalo nhαΊ―n tin vΓ o tΓ i khoαΊ£n cα»§a Bot đều sαΊ½ được AI tα»± Δ‘α»™ng tiαΊΏp Δ‘Γ³n ngay lαΊ­p tα»©c thay vΓ¬ bα»‹ chαΊ·n lαΊ‘i chờ bαΊ‘n duyệt lệnh kαΊΏt nα»‘i E2E!
21
-
22
-
23
- ## [5.1.10] β€” 2026-04-07
24
-
25
- ### 🌟 Tα»± Δ‘α»™ng Auto-Approve ThiαΊΏt Bα»‹ cho Native VPS
26
-
27
- - **Bỏ NhαΊ­p Lệnh Thα»§ CΓ΄ng TrαΊ£i Nghiệm PM2**: CαΊ£nh bΓ‘o `pairing required` (chờ duyệt thiαΊΏt bα»‹ ghΓ©p nα»‘i E2E) trΓͺn giao diện Web buα»™c người dΓΉng phαΊ£i gΓ΅ lệnh Δ‘α»“ng Γ½ dΖ°α»›i Terminal. Ở luα»“ng Docker, tΓ­nh nΔƒng nΓ y Δ‘Γ£ được vΓ΄ hiệu hΓ³a bαΊ±ng mα»™t Δ‘oαΊ‘n script chαΊ‘y ngαΊ§m tα»± gαΊ­t Δ‘αΊ§u. NhΖ°ng ở Native thΓ¬ chΖ°a! PhiΓͺn bαΊ£n nΓ y chΓ­nh thα»©c nhΓΊng thΓͺm 1 tiαΊΏn trΓ¬nh PM2 `auto-approve` siΓͺu nhαΊΉ chαΊ‘y kαΊΉp vα»›i cΓ‘c lệnh chΓ­nh, giΓΊp tα»± Δ‘α»™ng gαΊ­t Δ‘αΊ§u phΓͺ duyệt kαΊΏt nα»‘i web mα»—i 5 giΓ’y. Đảm bαΊ£o trαΊ£i nghiệm "Click lΓ  vΓ o" trΓͺn Native VPS mượt mΓ  y hệt Docker!
28
-
29
-
30
- ## [5.1.9] β€” 2026-04-07
31
-
32
- ### 🌟 TrαΊ£ lαΊ‘i Schema ChuαΊ©n & CαΊ£i thiện UX WebCrypto
33
-
34
- - **Sα»­a lα»—i sαΊ­p Gateway do sai lαΊ§m Config**: OpenClaw bαΊ£n mα»›i nhαΊ₯t dΓΉng Zod để khΓ³a chαΊ·t Schema cαΊ₯u hΓ¬nh. Cờ `requireDeviceIdentity` chΓͺm vΓ o bαΊ£n 5.1.8 Δ‘Γ£ bα»‹ Backend tα»« chα»‘i thαΊ³ng thα»«ng (`Unrecognized key`), dαΊ«n Δ‘αΊΏn server khΓ΄ng thể khởi Δ‘α»™ng vΓ²ng lαΊ·p. BαΊ£n 5.1.9 Δ‘Γ£ gα»‘ sαΊ‘ch cờ nΓ y, trαΊ£ lαΊ‘i mΓ΄i trường sαΊ‘ch để PM2 hoαΊ‘t Δ‘α»™ng 100%.
35
- - **Trợ lΓ½ SSH Tunnel Tα»± Động**: BΓΉ lαΊ‘i sα»± khαΊ―t khe cα»§a WebCrypto khi dΓΉng VPS/IP ngoΓ i, Console giờ Δ‘Γ’y sαΊ½ tα»± Δ‘α»™ng in sαΊ΅n thαΊ§n chΓΊ lệnh bαΊ» khΓ³a `ssh -L ...` y hệt IP vΓ  Username thαΊ­t cα»§a bαΊ‘n. BαΊ‘n chỉ cαΊ§n copy-paste để thΓ΄ng luα»“ng mα»™t cΓ‘ch ngαΊ§u lΓ²i, bαΊ£o mαΊ­t tuyệt Δ‘α»‘i mΓ  khΓ΄ng cαΊ§n mua TΓͺn miền HTTPS.
36
-
37
-
38
- ## [5.1.8] β€” 2026-04-07
39
-
40
- ### 🌟 Sα»­a lα»—i Đăng nhαΊ­p Token (1008) & CαΊ£i tiαΊΏn IP hiển thα»‹ trΓͺn VPS
41
-
42
- - **TαΊ―t `requireDeviceIdentity` để vượt tường WebCrypto**: Do cΖ‘ chαΊΏ bαΊ£o mαΊ­t mα»›i cα»§a Control UI bαΊ―t buα»™c trΓ¬nh duyệt phαΊ£i dΓΉng mΓ΄i trường HTTPS (hoαΊ·c localhost) thΓ¬ mα»›i cαΊ₯p quyền khởi tαΊ‘o key mΓ£ hΓ³a thiαΊΏt bα»‹ E2E. NαΊΏu dΓΉng IP thường (HTTP) thΓ¬ Dashboard sαΊ½ bΓ‘o lα»—i đỏ `code=1008`. BαΊ£n setup mα»›i nhαΊ₯t Δ‘Γ£ tα»± Δ‘α»™ng chΓ­ch cờ `requireDeviceIdentity: false` để tαΊ―t cΖ‘ chαΊΏ Γ©p buα»™c nΓ y Δ‘i, giΓΊp bαΊ‘n vΓ o thαΊ³ng Dashboard bαΊ±ng IP cα»§a VPS.
43
- - **Hiển thα»‹ Link Public ở Terminal**: CαΊ₯u trΓΊc bΓ‘o cΓ‘o cα»§a PM2 Δ‘Γ£ được viαΊΏt lαΊ‘i để tα»± Δ‘α»™ng tΓ¬m vΓ  sinh ra cΓ‘c đường dαΊ«n kΓ¨m IPv4 Public (thay vΓ¬ chỉ in mα»—i `localhost`). Giờ Δ‘Γ’y bαΊ‘n chỉ việc soi console vΓ  bαΊ₯m/copy thαΊ³ng link vΓ o trΓ¬nh duyệt mΓ  khΓ΄ng cαΊ§n phαΊ£i tα»± chαΊΏ nα»―a.
44
-
45
-
46
- ## [5.1.7] β€” 2026-04-07
47
-
48
- ### 🌟 Sα»­a lα»—i CORS Control UI & Đường dαΊ«n 9Router Native
49
-
50
- - **Sα»­a lα»—i dα»™i ngược CORS khi vΓ o Control UI**: OpenClaw v2026.3.x siαΊΏt chαΊ·t policy CORS khiαΊΏn việc truy cαΊ­p dashboard tα»« IP ngoΓ i bα»‹ block. CΓ‘c script tαΊ‘o config vΓ  vΓ‘ Docker giờ Δ‘Γ£ tα»± Δ‘α»™ng quΓ©t toΓ n bα»™ IPv4 hiện cΓ³ cα»§a server (`os.networkInterfaces()`) để nhΓΊng vΓ o mαΊ£ng `gateway.controlUi.allowedOrigins`. Đảm bαΊ£o người dΓΉng VPS vΓ o được thαΊ³ng Control UI mΓ  khΓ΄ng bα»‹ lα»—i mαΊ‘ng.
51
- - **Tα»‘i Ζ°u đường dαΊ«n PM2 Native**: Để trΓ‘nh trường hợp tΓ­nh nΔƒng PM2 khΓ΄ng nhαΊ­n diện Δ‘ΓΊng mΓ΄i trường (lα»—i `\$PATH` khi dΓΉng `nvm`), bα»™ cΓ i giờ bỏ qua file thα»±c thi `9router` cα»§a HĐH. Thay vΓ o Δ‘Γ³, bα»™ cΓ i tα»± tΓ­nh toΓ‘n đường dαΊ«n tuyệt Δ‘α»‘i `\$(npm root -g)/9router/app/server.js` vΓ  truyền thαΊ³ng vΓ o trΓ¬nh thΓ΄ng dα»‹ch Node, Δ‘αΊ£m bαΊ£o PM2 100% tΓ¬m thαΊ₯y file khởi chαΊ‘y 9Router.
52
-
53
-
54
- ## [5.1.6] β€” 2026-04-07
55
-
56
- ### 🐞 KhαΊ―c phα»₯c lα»—i PM2 ngαΊ―t cΓ i Δ‘αΊ·t (SIGKILL) trΓͺn VPS
57
-
58
- - **Sα»­a lα»—i `PM2 SIGKILL`**: LoαΊ‘i bỏ cờ `-t` (chαΊΏ Δ‘α»™ giao diện terminal) khỏi tαΊ₯t cαΊ£ cΓ‘c lệnh gọi `9router` chαΊ‘y ngαΊ§m. TrΓͺn cΓ‘c VPS khΓ΄ng giao diện (headless), cờ nΓ y cΓ³ thể khiαΊΏn PM2 bα»‹ treo vΓ  nΓ©m ra lα»—i SIGKILL lΓ m chαΊΏt toΓ n bα»™ quΓ‘ trΓ¬nh cΓ i Δ‘αΊ·t.
59
- - **Tα»‘i Ζ°u Sync Helper chαΊ‘y ngαΊ§m**: Bα»• sung cΖ‘ chαΊΏ dα»± phΓ²ng 2 lα»›p cho script tα»± Δ‘α»™ng Δ‘α»“ng bα»™ (sync helper). NαΊΏu PM2 bα»‹ giα»›i hαΊ‘n RAM hoαΊ·c quΓ‘ tαΊ£i gΓ’y lα»—i SIGKILL, script sαΊ½ khΓ΄ng vΔƒng lα»—i sαΊ­p Setup nα»―a mΓ  tα»± Δ‘α»™ng fallback xuα»‘ng chαΊ‘y αΊ©n bαΊ±ng `nohup node ... &`. Trong trường hợp xαΊ₯u nhαΊ₯t, bα»™ cΓ i chỉ bΓ‘o cαΊ£nh bΓ‘o vΓ ng vΓ  rαΊ½ nhΓ‘nh cho phΓ©p tiαΊΏn trΓ¬nh Setup tiαΊΏp tα»₯c tα»›i bΖ°α»›c cuα»‘i cΓΉng thΓ nh cΓ΄ng.
60
-
61
-
62
- ## [5.1.5] β€” 2026-04-06
63
-
64
- ### 🐞 Sα»­a lα»—i PM2 khởi Δ‘α»™ng 9Router trΓͺn Native
65
-
66
- - **Fix**: Chuyển tα»« việc chαΊ‘y chuα»—i bash (`execSync`) sang truyền mαΊ£ng tham sα»‘ rΓ΅ rΓ ng (`execFileSync`) khi khởi Δ‘α»™ng 9Router vΓ  script Δ‘α»“ng bα»™ (sync) qua PM2. Đảm bαΊ£o PM2 luΓ΄n chαΊ‘y được α»©ng dα»₯ng α»•n Δ‘α»‹nh trΓͺn cαΊ£ Linux (VPS) vΓ  Windows mΓ  khΓ΄ng bα»‹ vΖ°α»›ng lα»—i phΓ’n tΓ­ch cΓΊ phΓ‘p dαΊ₯u ngoαΊ·c kΓ©p hay khoαΊ£ng trαΊ―ng trong đường dαΊ«n.
67
- - **Tα»‘i Ζ°u**: PM2 giờ Δ‘Γ’y sαΊ½ phΓ’n tΓ‘ch rαΊ‘ch rΓ²i bαΊ±ng cΓ‘ch gọi file thα»±c thi `9router` vα»›i tham sα»‘ `--interpreter none`, vΓ  luΓ΄n chαΊ‘y sync script bαΊ±ng Δ‘ΓΊng phiΓͺn bαΊ£n NodeJS nα»™i tαΊ‘i thΓ΄ng qua `--interpreter process.execPath`.
68
-
69
-
70
- ## [5.1.4] β€” 2026-04-06
71
-
72
- ### 🐞 Sα»­a lα»—i BOM khởi Δ‘α»™ng CLI & Tα»‘i Ζ°u luα»“ng vΓ‘ Timeout trΓͺn Docker
73
-
74
- - **Sα»­a file CLI (BOM)**: XΓ³a tα»± Δ‘α»™ng chΓ¨n BOM (`\uFEFF`) ở Δ‘αΊ§u file `cli.js`. KΓ½ tα»± thα»«a nΓ y vα»‘n lΓ m hỏng shebang `#!/usr/bin/env node` vΓ  gΓ’y `SyntaxError: Unexpected token` trong nhiều mΓ΄i trường khi chαΊ‘y npx
75
- - **CαΊ£i thiện Docker Timeout Patch**: QuΓ‘ trΓ¬nh can thiệp timeout (`300s`) trong lΓΊc build Docker giờ chuyển sang scan quΓ©t toΓ n bα»™ cΓ‘c file `.js` trong thΖ° mα»₯c `openclaw/dist` thay vΓ¬ cα»‘ tΓ¬m file trΓΉng hash `gateway-cli-*`. GiΓΊp bαΊ£n vΓ‘ luΓ΄n Γ‘p dα»₯ng thΓ nh cΓ΄ng trΓͺn cΓ‘c phiΓͺn bαΊ£n backend khΓ‘c biệt mΓ  khΓ΄ng in ra warning rΓ‘c trΓͺn console
76
-
77
-
78
- ## [5.1.3] β€” 2026-04-06
79
-
80
- ### 🐜 Lα»—i lọt biαΊΏn nα»™i suy vΓ o giao diện Docker Compose
81
-
82
- BαΊ£n vΓ‘ lα»—i base64 trΖ°α»›c Δ‘Γ³ Δ‘Γ£ gΓ’y ra lα»—i mα»›i (regression) do dΓΉng ngoαΊ·c `${Buffer.from(...)}` bΓͺn trong chuα»—i string sinh ra docker-compose. Điều nΓ y lΓ m lọt nguyΓͺn Δ‘oαΊ‘n text nα»™i suy vΓ o `docker-compose.yml` thay vΓ¬ sinh ra chuα»—i base64 thαΊ­t.
83
-
84
- - **Fix**: Thα»±c hiện tαΊ‘o mΓ£ base64 hoΓ n chỉnh qua JavaScript (`const syncScriptBase64 = encodeBase64Utf8(syncScript)`) ngay tα»« ban Δ‘αΊ§u trΖ°α»›c khi ghΓ©p chuα»—i vΓ o file compose
85
- - Đảm bαΊ£o file compose tαΊ‘o thΓ nh nhαΊ­n chΓ­nh xΓ‘c mΓ£ base64 thuαΊ§n tΓΊy mΓ  khΓ΄ng bα»‹ lọt biαΊΏn mΓ΄i trường
86
- - Dọn dẹp lẑi script test tưƑng ứng
87
-
88
-
89
- ## [5.1.2] β€” 2026-04-06
90
-
91
- ### πŸ› Fix Shell Injection: Sync Script DΓΉng Base64
92
-
93
- Approach node -e JSON.stringify gÒy lỗi /bin/sh: Syntax error "(" unexpected vì JSON.stringify sinh chuỗi double-quoted phÑ vố shell argument.
94
-
95
- - **Fix**: nα»™i dung sync script nay được **base64-encode tαΊ‘i thời Δ‘iểm gen compose** bαΊ±ng Buffer.from(script).toString base64
96
- - Entrypoint sinh ra dαΊ‘ng: node -e writeFileSync Buffer.from b64 base64 toString
97
- - Base64 chỉ chα»©a [A-Za-z0-9+/=] β€” khΓ΄ng cΓ³ kΓ½ tα»± Δ‘αΊ·c biệt, hoαΊ‘t Δ‘α»™ng Δ‘ΓΊng trong YAML block
98
- - Áp dα»₯ng cho tαΊ₯t cαΊ£ luα»“ng gen compose: Docker web wizard (setup.js x2) vΓ  Docker CLI (cli.js x2)
99
-
100
-
101
- ## [5.1.1] β€” 2026-04-06
102
-
103
- ### πŸ”§ 9Router Smart-Route Sync β€” α»”n Δ‘α»‹nh qua API
104
-
105
- Sα»­a lα»—i nghiΓͺm trọng khiαΊΏn sync script khΓ΄ng nhαΊ­n ra provider Δ‘ang active, lΓ m tαΊ₯t cαΊ£ request fallback về `openai` (lα»—i `404 No active credentials`).
106
-
107
- - **NguyΓͺn nhΓ’n**: script đọc `db.providerConnections` tα»« `db.json` nhΖ°ng field nΓ y khΓ΄ng tα»“n tαΊ‘i trong 9Router v0.3.79+ β€” connections chỉ cΓ³ qua REST API
108
- - **Fix**: script giờ gọi `fetch('http://localhost:20128/api/providers')` β†’ `d.connections[]` để detect provider Δ‘ang active
109
- - **Fix**: thay heredoc `cat << 'CLAWEOF'` (gΓ’y ra `const p=undefined`) bαΊ±ng `node -e require('fs').writeFileSync(...)` β€” khΓ΄ng cΓ²n lα»—i escaping trong YAML+shell
110
- - **Fix**: `build9RouterSmartRouteSyncScript()` trong CLI docker flow giờ truyền Δ‘ΓΊng `'/root/.9router/db.json'` lΓ m db path
111
- - Áp dα»₯ng cho cαΊ£ 3 vα»‹ trΓ­: Docker web wizard (`setup.js`), Docker CLI (`cli.js`), vΓ  native (`cli.js`)
112
-
113
- ### πŸ“± Zalo Pairing β€” Tα»± Động Approve Khi Gateway Đang ChαΊ‘y
114
-
115
- - TrΖ°α»›c Δ‘Γ’y, auto-approve chỉ chαΊ‘y trong login flow ban Δ‘αΊ§u; pairing request mα»›i khi gateway Δ‘ang chαΊ‘y bα»‹ bỏ qua
116
- - **Fix**: `openclaw gateway run` vα»›i Zalo Personal giờ pipe stdout/stderr vΓ  tα»± gọi `openclaw pairing approve zalouser <code>` khi phΓ‘t hiện pairing code mα»›i
117
-
118
- ### 🧹 Output Docker CLI Gọn HƑn
119
-
120
- - XΓ³a cΓ‘c hΖ°α»›ng dαΊ«n thα»«a sau khi Docker build xong (`docker compose build`, `openclaw gateway`, PM2) β€” Docker mode tα»± chαΊ‘y hoΓ n toΓ n, khΓ΄ng cαΊ§n thao tΓ‘c thα»§ cΓ΄ng thΓͺm
121
-
3
+ ## [5.1.13] β€” 2026-04-08
4
+
5
+ ### πŸ› Sα»­a lα»—i cΓ i macOS & α»•n Δ‘α»‹nh Wizard
6
+
7
+ - **Sα»­a lα»—i `mkdir: : No such file or directory` trΓͺn macOS**: `generateSetupScript` dΓΉng `\${dir}` / `\${path}` (escaped) tαΊ‘o ra biαΊΏn bash rα»—ng β€” giờ dΓΉng JS interpolation đú́ng nΓͺn đường dαΊ«n thα»±c tαΊΏ được ghi vΓ o script.
8
+ - **Sα»­a script Docker macOS**: ThΓͺm kiểm tra Docker daemon `docker info` trΖ°α»›c khi chαΊ‘y `docker compose up`; chαΊΏ Δ‘α»™ Docker giờ gọi đú́ng `docker compose up` thay vΓ¬ `openclaw gateway run`.
9
+ - **Sα»­a npm prefix macOS Native**: Bỏ `npm config set prefix` gΓ’y xung Δ‘α»™t vα»›i Homebrew Node.js. Giờ dΓΉng `export npm_config_prefix` (env var cho session hiện tαΊ‘i) vΓ  fallback `sudo npm install -g`.
10
+ - **Sα»­a `window.__saveBotTabPersona is not a function`**: ThΓͺm hΓ m `__saveBotTabPersona` bα»‹ thiαΊΏu β€” HTML gọi nhΖ°ng JS chΖ°a Δ‘α»‹nh nghΔ©a.
11
+ - **Sα»­a nΓΊt TiαΊΏp theo Step 3 chαΊΏ Δ‘α»™ 1 bot**: `bindFormEvents` giờ sync `cfg-name` vΓ o `state.config.botName` vΓ  `state.bots[0].name` ngay khi gΓ΅, rα»“i gọi `updateNavButtons()` β€” nΓΊt TiαΊΏp phαΊ£n hα»“i ngay khΓ΄ng cαΊ§n chuyển bΖ°α»›c.
12
+ - **Sα»­a persona riΓͺng tα»«ng bot**: `saveBotTabMeta` vΓ  `syncBotTabMeta` giờ save/restore field `cfg-bot-tab-persona` cho tα»«ng bot. Chuyển tab hiển thα»‹ đú́ng nα»™i dung persona tΖ°Ζ‘ng α»©ng; giΓ‘ trα»‹ lΖ°u vΓ o `state.bots[i].persona` vΓ  được dΓΉng chΓ­nh xΓ‘c khi tαΊ‘o file `.md`.
13
+ - **Sα»­a cli.js npm macOS**: `ensureUserWritableGlobalNpm` bỏ `npm config set prefix` trΓͺn darwin; `installGlobalPackage` thΓͺm `sudo npm install -g` lΓ m fallback.
14
+
15
+ ## [5.1.12] β€” 2026-04-07
16
+
17
+ ### 🧠 ThΓͺm Skills & Tα»± Δ‘α»™ng chọn Plugin Relay
18
+
19
+ - **Grid Skills 3 cα»™t**: Layout mα»›i 3 card/hΓ ng thay vΓ¬ 4, card rα»™ng rΓ£i hΖ‘n, dα»… đọc hΖ‘n.
20
+ - **7 Skills mα»›i tα»« ClawHub**: Bα»• sung Δ‘αΊ§y Δ‘α»§ `Web Search`, `GitHub`, `Notion`, `Slack` β€” phα»§ khαΊ―p cΓ‘c tΓ‘c vα»₯ nΔƒng suαΊ₯t phα»• biαΊΏn nhαΊ₯t trΓͺn OpenClaw dashboard.
21
+ - **Plugin Telegram Multi-Bot Relay tα»± Δ‘α»™ng**: Khi chọn nhiều bot Telegram (botCount β‰₯ 2), plugin `telegram-multibot-relay` được tα»± Δ‘α»™ng tick chọn vΓ  ghi vΓ o `openclaw.json β†’ plugins.entries`. Khi quay về 1 bot, plugin bα»‹ bỏ chọn.
22
+ - **Plugin selections β†’ openclaw.json**: TαΊ₯t cαΊ£ plugin được user chọn (Voice Call, Matrix, MS Teams, Nostr...) đều được inject vΓ o `plugins.entries` để Dashboard OpenClaw nhαΊ­n trαΊ‘ng thΓ‘i `enabled` Δ‘ΓΊng. KhΓ΄ng chọn = khΓ΄ng bαΊ­t.
23
+ - **Fix Step 3 "TiαΊΏp theo" bα»‹ disabled**: Bỏ yΓͺu cαΊ§u bαΊ―t buα»™c `cfg-user-info` (optional), sα»­a multi-bot check dΓΉng `cfg-bot-tab-name`.
24
+ - **Fix Step 4 multi-bot token**: Validate `key-bot-token-0` thay vì `key-bot-token` khi multi-bot Telegram.
25
+ - **Fix AGENTS.md native multi-bot thiαΊΏu quy tαΊ―c bαΊ£o mαΊ­t**: Inject `securityRules` vΓ o cuα»‘i AGENTS.md cα»§a tα»«ng bot trong native multi-bot deployment.
26
+
27
+ ### 🌟 Đổi ChΓ­nh SΓ‘ch BαΊ£o MαΊ­t Zalo Personal
28
+
29
+ - **ThαΊ£ Ga Inbox Zalo CαΊ§m Tay**: Lược bỏ rΓ o cαΊ£n duyệt bαΊ£o mαΊ­t cα»§a Zalo Personal. ThΓ΄ng sα»‘ `dmPolicy` trΓͺn cΓ i Δ‘αΊ·t Zalo cΓ‘ nhΓ’n Δ‘Γ£ được chuyển mαΊ·c Δ‘α»‹nh tα»« `pairing` sang `open`. BΓ’y giờ bαΊ₯t cα»© ai trΓͺn mαΊ‘ng lΖ°α»›i Zalo nhαΊ―n tin vΓ o tΓ i khoαΊ£n cα»§a Bot đều sαΊ½ được AI tα»± Δ‘α»™ng tiαΊΏp Δ‘Γ³n ngay lαΊ­p tα»©c thay vΓ¬ bα»‹ chαΊ·n lαΊ‘i chờ bαΊ‘n duyệt lệnh kαΊΏt nα»‘i E2E!
30
+
31
+ ## [5.1.10] β€” 2026-04-07
32
+
33
+ ### 🌟 Tα»± Δ‘α»™ng Auto-Approve ThiαΊΏt Bα»‹ cho Native VPS
34
+
35
+ - **Bỏ NhαΊ­p Lệnh Thα»§ CΓ΄ng TrαΊ£i Nghiệm PM2**: CαΊ£nh bΓ‘o `pairing required` (chờ duyệt thiαΊΏt bα»‹ ghΓ©p nα»‘i E2E) trΓͺn giao diện Web buα»™c người dΓΉng phαΊ£i gΓ΅ lệnh Δ‘α»“ng Γ½ dΖ°α»›i Terminal. Ở luα»“ng Docker, tΓ­nh nΔƒng nΓ y Δ‘Γ£ được vΓ΄ hiệu hΓ³a bαΊ±ng mα»™t Δ‘oαΊ‘n script chαΊ‘y ngαΊ§m tα»± gαΊ­t Δ‘αΊ§u. NhΖ°ng ở Native thΓ¬ chΖ°a! PhiΓͺn bαΊ£n nΓ y chΓ­nh thα»©c nhΓΊng thΓͺm 1 tiαΊΏn trΓ¬nh PM2 `auto-approve` siΓͺu nhαΊΉ chαΊ‘y kαΊΉp vα»›i cΓ‘c lệnh chΓ­nh, giΓΊp tα»± Δ‘α»™ng gαΊ­t Δ‘αΊ§u phΓͺ duyệt kαΊΏt nα»‘i web mα»—i 5 giΓ’y. Đảm bαΊ£o trαΊ£i nghiệm "Click lΓ  vΓ o" trΓͺn Native VPS mượt mΓ  y hệt Docker!
36
+
37
+ ## [5.1.9] β€” 2026-04-07
38
+
39
+ ### 🌟 TrαΊ£ lαΊ‘i Schema ChuαΊ©n & CαΊ£i thiện UX WebCrypto
40
+
41
+ - **Sα»­a lα»—i sαΊ­p Gateway do sai lαΊ§m Config**: OpenClaw bαΊ£n mα»›i nhαΊ₯t dΓΉng Zod để khΓ³a chαΊ·t Schema cαΊ₯u hΓ¬nh. Cờ `requireDeviceIdentity` chΓͺm vΓ o bαΊ£n 5.1.8 Δ‘Γ£ bα»‹ Backend tα»« chα»‘i thαΊ³ng thα»«ng (`Unrecognized key`), dαΊ«n Δ‘αΊΏn server khΓ΄ng thể khởi Δ‘α»™ng vΓ²ng lαΊ·p. BαΊ£n 5.1.9 Δ‘Γ£ gα»‘ sαΊ‘ch cờ nΓ y, trαΊ£ lαΊ‘i mΓ΄i trường sαΊ‘ch để PM2 hoαΊ‘t Δ‘α»™ng 100%.
42
+ - **Trợ lΓ½ SSH Tunnel Tα»± Động**: BΓΉ lαΊ‘i sα»± khαΊ―t khe cα»§a WebCrypto khi dΓΉng VPS/IP ngoΓ i, Console giờ Δ‘Γ’y sαΊ½ tα»± Δ‘α»™ng in sαΊ΅n thαΊ§n chΓΊ lệnh bαΊ» khΓ³a `ssh -L ...` y hệt IP vΓ  Username thαΊ­t cα»§a bαΊ‘n. BαΊ‘n chỉ cαΊ§n copy-paste để thΓ΄ng luα»“ng mα»™t cΓ‘ch ngαΊ§u lΓ²i, bαΊ£o mαΊ­t tuyệt Δ‘α»‘i mΓ  khΓ΄ng cαΊ§n mua TΓͺn miền HTTPS.
43
+
44
+ ## [5.1.8] β€” 2026-04-07
45
+
46
+ ### 🌟 Sα»­a lα»—i Đăng nhαΊ­p Token (1008) & CαΊ£i tiαΊΏn IP hiển thα»‹ trΓͺn VPS
47
+
48
+ - **TαΊ―t `requireDeviceIdentity` để vượt tường WebCrypto**: Do cΖ‘ chαΊΏ bαΊ£o mαΊ­t mα»›i cα»§a Control UI bαΊ―t buα»™c trΓ¬nh duyệt phαΊ£i dΓΉng mΓ΄i trường HTTPS (hoαΊ·c localhost) thΓ¬ mα»›i cαΊ₯p quyền khởi tαΊ‘o key mΓ£ hΓ³a thiαΊΏt bα»‹ E2E. NαΊΏu dΓΉng IP thường (HTTP) thΓ¬ Dashboard sαΊ½ bΓ‘o lα»—i đỏ `code=1008`. BαΊ£n setup mα»›i nhαΊ₯t Δ‘Γ£ tα»± Δ‘α»™ng chΓ­ch cờ `requireDeviceIdentity: false` để tαΊ―t cΖ‘ chαΊΏ Γ©p buα»™c nΓ y Δ‘i, giΓΊp bαΊ‘n vΓ o thαΊ³ng Dashboard bαΊ±ng IP cα»§a VPS.
49
+ - **Hiển thα»‹ Link Public ở Terminal**: CαΊ₯u trΓΊc bΓ‘o cΓ‘o cα»§a PM2 Δ‘Γ£ được viαΊΏt lαΊ‘i để tα»± Δ‘α»™ng tΓ¬m vΓ  sinh ra cΓ‘c đường dαΊ«n kΓ¨m IPv4 Public (thay vΓ¬ chỉ in mα»—i `localhost`). Giờ Δ‘Γ’y bαΊ‘n chỉ việc soi console vΓ  bαΊ₯m/copy thαΊ³ng link vΓ o trΓ¬nh duyệt mΓ  khΓ΄ng cαΊ§n phαΊ£i tα»± chαΊΏ nα»―a.
50
+
51
+ ## [5.1.7] β€” 2026-04-07
52
+
53
+ ### 🌟 Sα»­a lα»—i CORS Control UI & Đường dαΊ«n 9Router Native
54
+
55
+ - **Sα»­a lα»—i dα»™i ngược CORS khi vΓ o Control UI**: OpenClaw v2026.3.x siαΊΏt chαΊ·t policy CORS khiαΊΏn việc truy cαΊ­p dashboard tα»« IP ngoΓ i bα»‹ block. CΓ‘c script tαΊ‘o config vΓ  vΓ‘ Docker giờ Δ‘Γ£ tα»± Δ‘α»™ng quΓ©t toΓ n bα»™ IPv4 hiện cΓ³ cα»§a server (`os.networkInterfaces()`) để nhΓΊng vΓ o mαΊ£ng `gateway.controlUi.allowedOrigins`. Đảm bαΊ£o người dΓΉng VPS vΓ o được thαΊ³ng Control UI mΓ  khΓ΄ng bα»‹ lα»—i mαΊ‘ng.
56
+ - **Tα»‘i Ζ°u đường dαΊ«n PM2 Native**: Để trΓ‘nh trường hợp tΓ­nh nΔƒng PM2 khΓ΄ng nhαΊ­n diện Δ‘ΓΊng mΓ΄i trường (lα»—i `\$PATH` khi dΓΉng `nvm`), bα»™ cΓ i giờ bỏ qua file thα»±c thi `9router` cα»§a HĐH. Thay vΓ o Δ‘Γ³, bα»™ cΓ i tα»± tΓ­nh toΓ‘n đường dαΊ«n tuyệt Δ‘α»‘i `\$(npm root -g)/9router/app/server.js` vΓ  truyền thαΊ³ng vΓ o trΓ¬nh thΓ΄ng dα»‹ch Node, Δ‘αΊ£m bαΊ£o PM2 100% tΓ¬m thαΊ₯y file khởi chαΊ‘y 9Router.
57
+
58
+ ## [5.1.6] β€” 2026-04-07
59
+
60
+ ### 🐞 KhαΊ―c phα»₯c lα»—i PM2 ngαΊ―t cΓ i Δ‘αΊ·t (SIGKILL) trΓͺn VPS
61
+
62
+ - **Sα»­a lα»—i `PM2 SIGKILL`**: LoαΊ‘i bỏ cờ `-t` (chαΊΏ Δ‘α»™ giao diện terminal) khỏi tαΊ₯t cαΊ£ cΓ‘c lệnh gọi `9router` chαΊ‘y ngαΊ§m. TrΓͺn cΓ‘c VPS khΓ΄ng giao diện (headless), cờ nΓ y cΓ³ thể khiαΊΏn PM2 bα»‹ treo vΓ  nΓ©m ra lα»—i SIGKILL lΓ m chαΊΏt toΓ n bα»™ quΓ‘ trΓ¬nh cΓ i Δ‘αΊ·t.
63
+ - **Tα»‘i Ζ°u Sync Helper chαΊ‘y ngαΊ§m**: Bα»• sung cΖ‘ chαΊΏ dα»± phΓ²ng 2 lα»›p cho script tα»± Δ‘α»™ng Δ‘α»“ng bα»™ (sync helper). NαΊΏu PM2 bα»‹ giα»›i hαΊ‘n RAM hoαΊ·c quΓ‘ tαΊ£i gΓ’y lα»—i SIGKILL, script sαΊ½ khΓ΄ng vΔƒng lα»—i sαΊ­p Setup nα»―a mΓ  tα»± Δ‘α»™ng fallback xuα»‘ng chαΊ‘y αΊ©n bαΊ±ng `nohup node ... &`. Trong trường hợp xαΊ₯u nhαΊ₯t, bα»™ cΓ i chỉ bΓ‘o cαΊ£nh bΓ‘o vΓ ng vΓ  rαΊ½ nhΓ‘nh cho phΓ©p tiαΊΏn trΓ¬nh Setup tiαΊΏp tα»₯c tα»›i bΖ°α»›c cuα»‘i cΓΉng thΓ nh cΓ΄ng.
64
+
65
+ ## [5.1.5] β€” 2026-04-06
66
+
67
+ ### 🐞 Sα»­a lα»—i PM2 khởi Δ‘α»™ng 9Router trΓͺn Native
68
+
69
+ - **Fix**: Chuyển tα»« việc chαΊ‘y chuα»—i bash (`execSync`) sang truyền mαΊ£ng tham sα»‘ rΓ΅ rΓ ng (`execFileSync`) khi khởi Δ‘α»™ng 9Router vΓ  script Δ‘α»“ng bα»™ (sync) qua PM2. Đảm bαΊ£o PM2 luΓ΄n chαΊ‘y được α»©ng dα»₯ng α»•n Δ‘α»‹nh trΓͺn cαΊ£ Linux (VPS) vΓ  Windows mΓ  khΓ΄ng bα»‹ vΖ°α»›ng lα»—i phΓ’n tΓ­ch cΓΊ phΓ‘p dαΊ₯u ngoαΊ·c kΓ©p hay khoαΊ£ng trαΊ―ng trong đường dαΊ«n.
70
+ - **Tα»‘i Ζ°u**: PM2 giờ Δ‘Γ’y sαΊ½ phΓ’n tΓ‘ch rαΊ‘ch rΓ²i bαΊ±ng cΓ‘ch gọi file thα»±c thi `9router` vα»›i tham sα»‘ `--interpreter none`, vΓ  luΓ΄n chαΊ‘y sync script bαΊ±ng Δ‘ΓΊng phiΓͺn bαΊ£n NodeJS nα»™i tαΊ‘i thΓ΄ng qua `--interpreter process.execPath`.
71
+
72
+ ## [5.1.4] β€” 2026-04-06
73
+
74
+ ### 🐞 Sα»­a lα»—i BOM khởi Δ‘α»™ng CLI & Tα»‘i Ζ°u luα»“ng vΓ‘ Timeout trΓͺn Docker
75
+
76
+ - **Sα»­a file CLI (BOM)**: XΓ³a tα»± Δ‘α»™ng chΓ¨n BOM (`\uFEFF`) ở Δ‘αΊ§u file `cli.js`. KΓ½ tα»± thα»«a nΓ y vα»‘n lΓ m hỏng shebang `#!/usr/bin/env node` vΓ  gΓ’y `SyntaxError: Unexpected token` trong nhiều mΓ΄i trường khi chαΊ‘y npx
77
+ - **CαΊ£i thiện Docker Timeout Patch**: QuΓ‘ trΓ¬nh can thiệp timeout (`300s`) trong lΓΊc build Docker giờ chuyển sang scan quΓ©t toΓ n bα»™ cΓ‘c file `.js` trong thΖ° mα»₯c `openclaw/dist` thay vΓ¬ cα»‘ tΓ¬m file trΓΉng hash `gateway-cli-*`. GiΓΊp bαΊ£n vΓ‘ luΓ΄n Γ‘p dα»₯ng thΓ nh cΓ΄ng trΓͺn cΓ‘c phiΓͺn bαΊ£n backend khΓ‘c biệt mΓ  khΓ΄ng in ra warning rΓ‘c trΓͺn console
78
+
79
+ ## [5.1.3] β€” 2026-04-06
80
+
81
+ ### 🐜 Lα»—i lọt biαΊΏn nα»™i suy vΓ o giao diện Docker Compose
82
+
83
+ BαΊ£n vΓ‘ lα»—i base64 trΖ°α»›c Δ‘Γ³ Δ‘Γ£ gΓ’y ra lα»—i mα»›i (regression) do dΓΉng ngoαΊ·c `${Buffer.from(...)}` bΓͺn trong chuα»—i string sinh ra docker-compose. Điều nΓ y lΓ m lọt nguyΓͺn Δ‘oαΊ‘n text nα»™i suy vΓ o `docker-compose.yml` thay vΓ¬ sinh ra chuα»—i base64 thαΊ­t.
84
+
85
+ - **Fix**: Thα»±c hiện tαΊ‘o mΓ£ base64 hoΓ n chỉnh qua JavaScript (`const syncScriptBase64 = encodeBase64Utf8(syncScript)`) ngay tα»« ban Δ‘αΊ§u trΖ°α»›c khi ghΓ©p chuα»—i vΓ o file compose
86
+ - Đảm bαΊ£o file compose tαΊ‘o thΓ nh nhαΊ­n chΓ­nh xΓ‘c mΓ£ base64 thuαΊ§n tΓΊy mΓ  khΓ΄ng bα»‹ lọt biαΊΏn mΓ΄i trường
87
+ - Dọn dẹp lẑi script test tưƑng ứng
88
+
89
+ ## [5.1.2] β€” 2026-04-06
90
+
91
+ ### πŸ› Fix Shell Injection: Sync Script DΓΉng Base64
92
+
93
+ Approach node -e JSON.stringify gÒy lỗi /bin/sh: Syntax error "(" unexpected vì JSON.stringify sinh chuỗi double-quoted phÑ vố shell argument.
94
+
95
+ - **Fix**: nα»™i dung sync script nay được **base64-encode tαΊ‘i thời Δ‘iểm gen compose** bαΊ±ng Buffer.from(script).toString base64
96
+ - Entrypoint sinh ra dαΊ‘ng: node -e writeFileSync Buffer.from b64 base64 toString
97
+ - Base64 chỉ chα»©a [A-Za-z0-9+/=] β€” khΓ΄ng cΓ³ kΓ½ tα»± Δ‘αΊ·c biệt, hoαΊ‘t Δ‘α»™ng Δ‘ΓΊng trong YAML block
98
+ - Áp dα»₯ng cho tαΊ₯t cαΊ£ luα»“ng gen compose: Docker web wizard (setup.js x2) vΓ  Docker CLI (cli.js x2)
99
+
100
+ ## [5.1.1] β€” 2026-04-06
101
+
102
+ ### πŸ”§ 9Router Smart-Route Sync β€” α»”n Δ‘α»‹nh qua API
103
+
104
+ Sα»­a lα»—i nghiΓͺm trọng khiαΊΏn sync script khΓ΄ng nhαΊ­n ra provider Δ‘ang active, lΓ m tαΊ₯t cαΊ£ request fallback về `openai` (lα»—i `404 No active credentials`).
105
+
106
+ - **NguyΓͺn nhΓ’n**: script đọc `db.providerConnections` tα»« `db.json` nhΖ°ng field nΓ y khΓ΄ng tα»“n tαΊ‘i trong 9Router v0.3.79+ β€” connections chỉ cΓ³ qua REST API
107
+ - **Fix**: script giờ gọi `fetch('http://localhost:20128/api/providers')` β†’ `d.connections[]` để detect provider Δ‘ang active
108
+ - **Fix**: thay heredoc `cat << 'CLAWEOF'` (gΓ’y ra `const p=undefined`) bαΊ±ng `node -e require('fs').writeFileSync(...)` β€” khΓ΄ng cΓ²n lα»—i escaping trong YAML+shell
109
+ - **Fix**: `build9RouterSmartRouteSyncScript()` trong CLI docker flow giờ truyền Δ‘ΓΊng `'/root/.9router/db.json'` lΓ m db path
110
+ - Áp dα»₯ng cho cαΊ£ 3 vα»‹ trΓ­: Docker web wizard (`setup.js`), Docker CLI (`cli.js`), vΓ  native (`cli.js`)
111
+
112
+ ### πŸ“± Zalo Pairing β€” Tα»± Động Approve Khi Gateway Đang ChαΊ‘y
113
+
114
+ - TrΖ°α»›c Δ‘Γ’y, auto-approve chỉ chαΊ‘y trong login flow ban Δ‘αΊ§u; pairing request mα»›i khi gateway Δ‘ang chαΊ‘y bα»‹ bỏ qua
115
+ - **Fix**: `openclaw gateway run` vα»›i Zalo Personal giờ pipe stdout/stderr vΓ  tα»± gọi `openclaw pairing approve zalouser <code>` khi phΓ‘t hiện pairing code mα»›i
116
+
117
+ ### 🧹 Output Docker CLI Gọn HƑn
118
+
119
+ - XΓ³a cΓ‘c hΖ°α»›ng dαΊ«n thα»«a sau khi Docker build xong (`docker compose build`, `openclaw gateway`, PM2) β€” Docker mode tα»± chαΊ‘y hoΓ n toΓ n, khΓ΄ng cαΊ§n thao tΓ‘c thα»§ cΓ΄ng thΓͺm
120
+
122
121
  ## [5.1.0] β€” 2026-04-07
123
122
 
124
123
  ### πŸ€– Zalo Personal Login Improvements
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # 🦞 OpenClaw Setup
4
4
 
5
5
  <p align="center">
6
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.11-0EA5E9?style=for-the-badge" alt="Version 5.1.11" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.13-0EA5E9?style=for-the-badge" alt="Version 5.1.13" /></a>
7
7
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
8
8
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
9
9
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -24,7 +24,7 @@ An interactive **CLI tool** and **Setup Wizard** to deploy your own free AI Bot
24
24
 
25
25
  ---
26
26
 
27
- ## πŸ†• What's new in v5.1.11
27
+ ## πŸ†• What's new in v5.1.13
28
28
 
29
29
  - πŸ’» **OS-First Setup** β€” Step 1 is now choosing your OS (Windows, macOS, Ubuntu, VPS). All scripts, configs, and instructions are generated to match.
30
30
  - 🧠 **Gemma 4 β€” 4 sizes** β€” `gemma4:e2b` (~4 GB), `gemma4:e4b` (~8 GB), `gemma4:26b` (~18 GB), `gemma4:31b` (~24 GB). Auto-pulled on first launch.
package/README.vi.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # 🦞 OpenClaw Setup
4
4
 
5
5
  <p align="center">
6
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.11-0EA5E9?style=for-the-badge" alt="Version 5.1.11" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.1.11-0EA5E9?style=for-the-badge" alt="Version 5.1.13" /></a>
7
7
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
8
8
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
9
9
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -24,7 +24,7 @@ CΓ΄ng cα»₯ **CLI tΖ°Ζ‘ng tΓ‘c** vΓ  **Setup Wizard** để tα»± triển khai Bot
24
24
 
25
25
  ---
26
26
 
27
- ## πŸ†• CΓ³ gΓ¬ mα»›i trong v5.1.11
27
+ ## πŸ†• CΓ³ gΓ¬ mα»›i trong v5.1.13
28
28
 
29
29
  - πŸ’» **OS-First Setup** β€” BΖ°α»›c Δ‘αΊ§u tiΓͺn bΓ’y giờ lΓ  chọn hệ Δ‘iều hΓ nh cα»§a bαΊ‘n (Windows, macOS, Ubuntu, VPS). ToΓ n bα»™ script, cαΊ₯u hΓ¬nh vΓ  hΖ°α»›ng dαΊ«n được tαΊ‘o ra phΓΉ hợp vα»›i lα»±a chọn Δ‘Γ³.
30
30
  - 🧠 **Gemma 4 β€” 4 kΓ­ch thΖ°α»›c** β€” `gemma4:e2b` (~4 GB), `gemma4:e4b` (~8 GB), `gemma4:26b` (~18 GB), `gemma4:31b` (~24 GB). Tα»± pull về khi bot khởi Δ‘α»™ng lαΊ§n Δ‘αΊ§u.
package/cli.js CHANGED
@@ -275,11 +275,15 @@ function ensureUserWritableGlobalNpm({ isVi, osChoice }) {
275
275
  process.env.npm_config_prefix = npmInfo.prefixDir;
276
276
  ensureBinDirOnPath(npmInfo.binDir);
277
277
 
278
- execSync(`npm config set prefix "${npmInfo.prefixDir.replace(/"/g, '\\"')}"`, {
279
- stdio: 'ignore',
280
- shell: true,
281
- env: process.env
282
- });
278
+ // On macOS (darwin), skip mutating global .npmrc prefix β€” conflicts with Homebrew.
279
+ // The npm_config_prefix env var set above is sufficient for this process.
280
+ if (process.platform !== 'darwin') {
281
+ execSync(`npm config set prefix "${npmInfo.prefixDir.replace(/"/g, '\\"')}"`, {
283
282
 
283
+ stdio: 'ignore',
284
284
 
285
+ shell: true,
285
286
 
287
+ env: process.env
286
288
 
289
+ });
290
+ }
287
291
 
288
292
  appendLineIfMissing(path.join(os.homedir(), '.profile'), 'export PATH="$HOME/.local/bin:$PATH"');
289
293
  appendLineIfMissing(
@@ -312,6 +316,10 @@ function installGlobalPackage(pkg, { isVi, osChoice, displayName }) {
312
316
  if (npmInfo) {
313
317
  installCommands.push(`npm install -g --prefix "${npmInfo.prefixDir.replace(/"/g, '\\"')}" ${pkg}`);
314
318
  }
319
+ // macOS: if user-writable npm install fails, try sudo as last resort
320
+ if (osChoice === 'macos' || process.platform === 'darwin') {
321
+ installCommands.push(`sudo npm install -g ${pkg}`);
322
+ }
315
323
  }
316
324
 
317
325
  for (const cmd of installCommands) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.1.12",
3
+ "version": "5.1.13",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "cli.js",
6
6
  "bin": {
package/setup.js CHANGED
@@ -656,10 +656,12 @@
656
656
  if (labelEl) labelEl.style.display = 'none';
657
657
  if (slashGroup) slashGroup.style.display = 'none';
658
658
 
659
- // Update fields
660
- const bot = state.bots[0] || { name: 'Bot 1', desc: '', persona: '', slashCmd: '' };
661
- document.getElementById('cfg-bot-tab-name').value = bot.name || '';
662
- document.getElementById('cfg-bot-tab-desc').value = bot.desc || '';
659
+ // Restore single-bot fields β€” fall back to state.config.botName so Next button
660
+ // is never falsely disabled just because state.bots[0].name is empty yet.
661
+ const bot = state.bots[0] || { name: '', desc: '', persona: '', slashCmd: '' };
662
+ const resolvedName = bot.name || state.config.botName || '';
663
+ document.getElementById('cfg-bot-tab-name').value = resolvedName;
664
+ document.getElementById('cfg-bot-tab-desc').value = bot.desc || state.config.description || '';
663
665
  document.getElementById('cfg-bot-tab-persona').value = bot.persona || '';
664
666
  return;
665
667
  }
@@ -690,9 +692,11 @@
690
692
  const nameEl = document.getElementById('cfg-bot-tab-name');
691
693
  const slashEl = document.getElementById('cfg-bot-tab-slash');
692
694
  const descEl = document.getElementById('cfg-bot-tab-desc');
695
+ const personaEl = document.getElementById('cfg-bot-tab-persona');
693
696
  if (nameEl) nameEl.value = bot.name || '';
694
697
  if (slashEl) slashEl.value = bot.slashCmd || '';
695
698
  if (descEl) descEl.value = bot.desc || '';
699
+ if (personaEl) personaEl.value = bot.persona || '';
696
700
 
697
701
  // Also sync global config fields from active bot (provider/model carry over)
698
702
  if (bot.provider) {
@@ -733,9 +737,11 @@
733
737
  const nameEl = document.getElementById('cfg-bot-tab-name');
734
738
  const slashEl = document.getElementById('cfg-bot-tab-slash');
735
739
  const descEl = document.getElementById('cfg-bot-tab-desc');
740
+ const personaEl = document.getElementById('cfg-bot-tab-persona');
736
741
  if (nameEl) bot.name = nameEl.value;
737
742
  if (slashEl) bot.slashCmd = slashEl.value;
738
743
  if (descEl) bot.desc = descEl.value;
744
+ if (personaEl) bot.persona = personaEl.value;
739
745
  }
740
746
 
741
747
  window.__saveBotTabName = function(val) {
@@ -761,6 +767,12 @@
761
767
  }
762
768
  };
763
769
 
770
+ window.__saveBotTabPersona = function(val) {
771
+ if (state.bots[state.activeBotIndex]) {
772
+ state.bots[state.activeBotIndex].persona = val;
773
+ }
774
+ };
775
+
764
776
 
765
777
 
766
778
  // ========== Step 1: Deploy Mode + OS ==========
@@ -976,12 +988,17 @@
976
988
  if (state.currentStep === 3) {
977
989
  if (state.botCount > 1) {
978
990
  // Multi-bot: require name for the currently active bot tab
979
- const tabNameVal = document.getElementById('cfg-bot-tab-name')?.value?.trim();
991
+ // Fallback to state.bots to handle re-render cases where DOM may not yet have the value
992
+ const activeTab = state._activeBotTab || 0;
993
+ const tabNameVal = document.getElementById('cfg-bot-tab-name')?.value?.trim()
994
+ || state.bots[activeTab]?.name?.trim();
980
995
  if (!tabNameVal) isDisabled = true;
981
996
  } else {
982
997
  // Single bot: require cfg-name or the shared tab name field
998
+ // Fallback to state.config.botName for cases where the DOM field was cleared on re-render
983
999
  const nameVal = document.getElementById('cfg-name')?.value?.trim()
984
- || document.getElementById('cfg-bot-tab-name')?.value?.trim();
1000
+ || document.getElementById('cfg-bot-tab-name')?.value?.trim()
1001
+ || state.config.botName?.trim();
985
1002
  if (!nameVal) isDisabled = true;
986
1003
  }
987
1004
  }
@@ -1128,6 +1145,17 @@
1128
1145
  prompt.value = DEFAULT_PROMPTS[lang].replace('{BOT_NAME}', nameVal).replace('{BOT_DESC}', descVal);
1129
1146
  autoExpand(prompt);
1130
1147
  }
1148
+ // Sync single-bot name to state + re-check Next button
1149
+ if (e.target.id === 'cfg-name') {
1150
+ state.config.botName = e.target.value;
1151
+ if (state.bots[0]) state.bots[0].name = e.target.value;
1152
+ }
1153
+ updateNavButtons();
1154
+ }
1155
+ // Also re-check Next when typing directly in the tab name field
1156
+ if (e.target.id === 'cfg-bot-tab-name') {
1157
+ if (state.bots[state.activeBotIndex]) state.bots[state.activeBotIndex].name = e.target.value;
1158
+ updateNavButtons();
1131
1159
  }
1132
1160
  if (e.target.id === 'cfg-prompt') {
1133
1161
  e.target.dataset.userEdited = 'true';
@@ -1227,6 +1255,12 @@
1227
1255
  state.config.systemPrompt = document.getElementById('cfg-prompt')?.value || state.config.systemPrompt || DEFAULT_PROMPTS['vi'];
1228
1256
  state.config.userInfo = document.getElementById('cfg-user-info')?.value?.trim() || state.config.userInfo || '';
1229
1257
  state.config.securityRules = document.getElementById('cfg-security')?.value || state.config.securityRules || DEFAULT_SECURITY_RULES['vi'];
1258
+ // Also save bot-tab-name β†’ bots[0].name so both state locations stay in sync
1259
+ const tabName = document.getElementById('cfg-bot-tab-name')?.value?.trim();
1260
+ if (tabName && state.bots[0]) state.bots[0].name = tabName;
1261
+ else if (state.config.botName && state.bots[0] && !state.bots[0].name) {
1262
+ state.bots[0].name = state.config.botName;
1263
+ }
1230
1264
  }
1231
1265
 
1232
1266
  // Save Step 4 credential inputs to state (persists across Back navigation)
@@ -3585,29 +3619,55 @@ ${selectedSkillNames.length ? selectedSkillNames.join('\n') : '- _(No skills ins
3585
3619
  } else if (state.nativeOs === 'linux') {
3586
3620
  const isDocker = state.deployMode === 'docker';
3587
3621
  scriptName = isDocker ? 'setup-openclaw-docker-macos.sh' : 'setup-openclaw-macos.sh';
3588
- const sh = [
3589
- '#!/usr/bin/env bash', 'set -e',
3590
- `echo "=== OpenClaw Setup β€” macOS${isDocker ? ' Docker' : ' Native'} ==="`,
3591
- 'command -v node > /dev/null 2>&1 || { echo "ERROR: Node.js chua cai! https://nodejs.org"; exit 1; }',
3592
- 'mkdir -p "$HOME/.local/bin"',
3593
- 'npm config set prefix "$HOME/.local"',
3594
- 'export PATH="$HOME/.local/bin:$PATH"',
3595
- 'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.zshrc" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.zshrc"',
3596
- 'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.profile" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.profile"',
3597
- 'npm install -g openclaw@latest',
3598
- ];
3599
- providerLines(sh, 'sh');
3600
- if (pluginCmd) sh.push(pluginCmd);
3601
3622
 
3602
- if (isMultiBot) {
3603
- appendShWriteCommands(sh, sharedNativeFileMap());
3604
- sh.push('echo "Starting shared multi-bot gateway..."');
3605
- sh.push('openclaw gateway run');
3606
- } else {
3623
+ if (isDocker) {
3624
+ // ── macOS Docker mode: write files then docker compose up ──────────────
3625
+ const sh = [
3626
+ '#!/usr/bin/env bash', 'set -e',
3627
+ 'echo "=== OpenClaw Setup \u2014 macOS Docker ==="',
3628
+ '# Check Docker Desktop is running',
3629
+ 'if ! docker info > /dev/null 2>&1; then',
3630
+ ' echo "\u274c Docker Desktop chua chay! Mo Docker Desktop roi chay lai script nay."',
3631
+ ' exit 1',
3632
+ 'fi',
3633
+ ];
3607
3634
  appendShWriteCommands(sh, botFiles(0));
3608
- sh.push('openclaw gateway run');
3635
+ sh.push('echo "Starting bot via Docker Compose..."');
3636
+ sh.push('if docker compose version > /dev/null 2>&1; then COMPOSE="docker compose"; else COMPOSE="docker-compose"; fi');
3637
+ sh.push('cd docker/openclaw');
3638
+ sh.push('$COMPOSE up --detach --build');
3639
+ sh.push('echo "\u2705 Bot dang chay via Docker. Xem log: docker logs -f openclaw-bot"');
3640
+ scriptContent = sh.filter(Boolean).join('\n');
3641
+ } else {
3642
+ // ── macOS Native mode: same approach as Ubuntu but no PM2, no apt ────────
3643
+ // Do NOT use 'npm config set prefix' on macOS β€” breaks Homebrew Node.
3644
+ // Use export npm_config_prefix per-session + sudo fallback.
3645
+ const sh = [
3646
+ '#!/usr/bin/env bash', 'set -e',
3647
+ 'echo "=== OpenClaw Setup \u2014 macOS Native ==="',
3648
+ 'command -v node > /dev/null 2>&1 || { echo "ERROR: Node.js chua cai! https://nodejs.org"; exit 1; }',
3649
+ '# User-local npm prefix (Homebrew-safe β€” no global npmrc mutation)',
3650
+ 'mkdir -p "$HOME/.local/bin"',
3651
+ 'export npm_config_prefix="$HOME/.local"',
3652
+ 'export PATH="$HOME/.local/bin:$PATH"',
3653
+ 'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.zshrc" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.zshrc"',
3654
+ 'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.profile" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.profile"',
3655
+ '# Install openclaw (user-local first, sudo fallback)',
3656
+ 'npm install -g openclaw@latest || sudo npm install -g openclaw@latest',
3657
+ ];
3658
+ providerLines(sh, 'sh');
3659
+ if (pluginCmd) sh.push(pluginCmd);
3660
+
3661
+ if (isMultiBot) {
3662
+ appendShWriteCommands(sh, sharedNativeFileMap());
3663
+ sh.push('echo "Starting shared multi-bot gateway..."');
3664
+ sh.push('openclaw gateway run');
3665
+ } else {
3666
+ appendShWriteCommands(sh, botFiles(0));
3667
+ sh.push('openclaw gateway run');
3668
+ }
3669
+ scriptContent = sh.filter(Boolean).join('\n');
3609
3670
  }
3610
- scriptContent = sh.filter(Boolean).join('\n');
3611
3671
 
3612
3672
  // ─── VPS/Ubuntu PM2 .SH ──────────────────────────────────────────────────
3613
3673
  } else if (state.nativeOs === 'vps') {
@@ -3957,14 +4017,14 @@ echo ""
3957
4017
 
3958
4018
  script += `# \${isVi ? 'TαΊ‘o thΖ° mα»₯c' : 'Create directories'}\n`;
3959
4019
  Array.from(dirs).sort().forEach(dir => {
3960
- script += `mkdir -p "\${dir}"\n`;
4020
+ script += `mkdir -p "${dir}"\n`;
3961
4021
  });
3962
4022
  script += '\n';
3963
4023
 
3964
4024
  Object.entries(files).forEach(([path, content]) => {
3965
4025
  script += `# \${path}\n`;
3966
4026
  const contentStr = typeof content === 'string' ? content : '';
3967
- script += `cat > "\${path}" << 'CLAWEOF'\n`;
4027
+ script += `cat > "${path}" << 'CLAWEOF'\n`;
3968
4028
  script += contentStr;
3969
4029
  if (!contentStr.endsWith('\n')) script += '\n';
3970
4030
  script += `CLAWEOF\n\n`;
@@ -3975,6 +4035,7 @@ echo ""
3975
4035
  script += `echo ""\n`;
3976
4036
  script += `echo "\${isVi ? '🐳 Đang khởi Δ‘α»™ng Docker (cΓ³ thể mαΊ₯t vΓ i phΓΊt)...' : '🐳 Starting Docker (may take a few minutes)...'}"\n`;
3977
4037
  script += `if docker compose version > /dev/null 2>&1; then\n COMPOSE_CMD="docker compose"\nelif docker-compose version > /dev/null 2>&1; then\n COMPOSE_CMD="docker-compose"\nelse\n echo "\${isVi ? '❌ KhΓ΄ng tΓ¬m thαΊ₯y Docker Compose! CΓ i bαΊ±ng: sudo apt-get install docker-compose-plugin' : '❌ Docker Compose not found! Install: sudo apt-get install docker-compose-plugin'}"\n exit 1\nfi\n`;
4038
+ script += `# Check Docker daemon is actually running\nif ! docker info > /dev/null 2>&1; then\n echo "${isVi ? '❌ Docker daemon chΖ°a chαΊ‘y! HΓ£y mở Docker Desktop rα»“i chαΊ‘y lαΊ‘i.' : '❌ Docker daemon is not running! Open Docker Desktop first, then re-run this script.'}"; exit 1\nfi\n`;
3978
4039
 
3979
4040
  if (isMultiBot) {
3980
4041
  script += `cd "docker/openclaw"\n`;