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 +120 -120
- package/CHANGELOG.vi.md +118 -119
- package/README.md +2 -2
- package/README.vi.md +2 -2
- package/cli.js +13 -5
- package/package.json +1 -1
- package/setup.js +89 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,125 +1,125 @@
|
|
|
1
1
|
# Changelog (English)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **Fix
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## [5.1.
|
|
40
|
-
|
|
41
|
-
### π
|
|
42
|
-
|
|
43
|
-
- **
|
|
44
|
-
- **Dynamic
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- **
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- **
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
- **
|
|
108
|
-
- **Fix**:
|
|
109
|
-
- **Fix**:
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
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
|
-
//
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
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
|
-
|
|
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 (
|
|
3603
|
-
|
|
3604
|
-
sh
|
|
3605
|
-
|
|
3606
|
-
|
|
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('
|
|
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 "
|
|
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 > "
|
|
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`;
|