create-openclaw-bot 5.7.6 → 5.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -10
- package/README.vi.md +9 -10
- package/dist/cli.js +29 -27
- package/dist/setup/shared/bot-config-gen.js +9 -1
- package/dist/setup/shared/common-gen.js +1 -1
- package/dist/setup/shared/docker-gen.js +62 -47
- package/dist/setup.js +51 -18
- package/package.json +39 -39
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.7.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.7.7-0EA5E9?style=for-the-badge" alt="Version 5.7.7" /></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,19 +24,18 @@ 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.7.
|
|
27
|
+
## 🆕 What's new in v5.7.7
|
|
28
28
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
29
|
+
- 🛠️ **Infrastructure & Zalo Bot Stabilization** — Automatically pins `openclaw@2026.4.15` across all deployment scripts, completely eliminating gateway crashes caused by version mismatch when installing Zalo Personal.
|
|
30
|
+
- 📦 **Docker Volume & Gateway Deadlock Optimization** — Redesigned the `.openclaw` mount mechanism and implemented `tmpfs` for `plugin-runtime-deps`, entirely preventing I/O lock conditions on Windows/WSL2.
|
|
31
|
+
- 🔄 **9Router Smart-Sync** — Automatically detects and syncs models (Gemini, Claude, GPT) from active AI providers directly into the `smart-route` combination every time the system starts up.
|
|
31
32
|
|
|
32
33
|
<details>
|
|
33
|
-
<summary><b>Previous: What's new in v5.7.
|
|
34
|
+
<summary><b>Previous: What's new in v5.7.6</b></summary>
|
|
34
35
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- 🐛 **Removed `autoReply` bug** — The `autoReply: true` field that caused gateway startup crashes on Zalo Personal has been permanently removed from all generators.
|
|
39
|
-
- 💬 **Standardized Zalo Personal config** — Zalo Personal (`zalouser`) channel now uses production-matching config with `groups`, `groupPolicy`, `historyLimit`, and proper `bindings`.
|
|
36
|
+
- 🧹 **Automated Uninstall Scripts** — Generates an `uninstall-openclaw` script to cleanly remove system/container resources.
|
|
37
|
+
- 🐛 **Hotfix CLI Crash** — Permanently fixed the `channelKey is not defined` bug and double-encoding issues for Vietnamese texts.
|
|
38
|
+
- 🏗️ **Centralized config architecture** — All config logic is now unified through `bot-config-gen.js`, completely eradicating the `autoReply: true` bug.
|
|
40
39
|
|
|
41
40
|
## </details>
|
|
42
41
|
|
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.7.
|
|
6
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.7.7-0EA5E9?style=for-the-badge" alt="Version 5.7.7" /></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,19 +24,18 @@ 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.7.
|
|
27
|
+
## 🆕 Có gì mới trong v5.7.7
|
|
28
28
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
29
|
+
- 🛠️ **Ổn Định Infrastructure & Zalo Bot** — Tự động ghim `openclaw@2026.4.15` cho mọi nền tảng, loại bỏ hoàn toàn các lỗi crash do lệch version khi cài Zalo Personal.
|
|
30
|
+
- 📦 **Tối Ưu Docker Volume & Gateway Deadlock** — Thiết kế lại cơ chế mount thư mục `.openclaw` và triển khai `tmpfs` cho `plugin-runtime-deps`, triệt để ngăn chặn tình trạng I/O lock trên Windows/WSL2.
|
|
31
|
+
- 🔄 **9Router Smart-Sync** — Tự động nhận diện và đồng bộ danh sách models (Gemini, Claude, GPT) từ các AI provider đang kích hoạt trực tiếp vào combo `smart-route` mỗi khi khởi động hệ thống.
|
|
31
32
|
|
|
32
33
|
<details>
|
|
33
|
-
<summary><b>Trước đó: Có gì mới ở v5.7.
|
|
34
|
+
<summary><b>Trước đó: Có gì mới ở v5.7.6</b></summary>
|
|
34
35
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- 🐛 **Xóa lỗi `autoReply`** — Trường `autoReply: true` gây crash gateway khi khởi động Zalo Personal đã bị loại bỏ vĩnh viễn khỏi mọi generator.
|
|
39
|
-
- 💬 **Chuẩn hóa config Zalo Personal** — Kênh Zalo Personal (`zalouser`) giờ dùng config khớp production với `groups`, `groupPolicy`, `historyLimit`, và `bindings` đúng.
|
|
36
|
+
- 🧹 **Tự Động Tạo Script Gỡ Cài Đặt** — Sinh sẵn file `uninstall-openclaw` dọn sạch tài nguyên hệ thống/container.
|
|
37
|
+
- 🐛 **Hotfix CLI Crash** — Fix triệt để lỗi `channelKey is not defined` và double-encoding tiếng Việt.
|
|
38
|
+
- 🏗️ **Kiến trúc config tập trung** — Toàn bộ logic config giờ hợp nhất qua `bot-config-gen.js`, xoá triệt để lỗi `autoReply: true`.
|
|
40
39
|
|
|
41
40
|
## </details>
|
|
42
41
|
|
package/dist/cli.js
CHANGED
|
@@ -488,14 +488,18 @@ async function patchProjectDocker9Router(projectDir) {
|
|
|
488
488
|
await fs.writeFile(path.join(dockerDir, 'sync.js'), build9RouterSmartRouteSyncScript('/root/.9router/db.json'));
|
|
489
489
|
await fs.writeFile(path.join(dockerDir, 'patch-9router.js'), build9RouterPatchScript());
|
|
490
490
|
let compose = await fs.readFile(composePath, 'utf8');
|
|
491
|
-
compose = compose.replace(
|
|
492
|
-
/node -e "require\('fs'\)\.writeFileSync\('\/tmp\/sync\.js',Buffer\.from\('[^']*','base64'\)\.toString\(\)\)"/,
|
|
493
|
-
"cp /opt/sync.js /tmp/sync.js"
|
|
494
|
-
);
|
|
495
|
-
compose = compose.replace(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
);
|
|
491
|
+
compose = compose.replace(
|
|
492
|
+
/node -e "require\('fs'\)\.writeFileSync\('\/tmp\/sync\.js',Buffer\.from\('[^']*','base64'\)\.toString\(\)\)"/,
|
|
493
|
+
"cp /opt/sync.js /tmp/sync.js"
|
|
494
|
+
);
|
|
495
|
+
compose = compose.replace(
|
|
496
|
+
/\s*node -e "require\('fs'\)\.writeFileSync\('\/tmp\/patch-9router\.js',Buffer\.from\('[^']*','base64'\)\.toString\(\)\)"\n/,
|
|
497
|
+
''
|
|
498
|
+
);
|
|
499
|
+
compose = compose.replace(
|
|
500
|
+
/(npm install -g [^\n]+\n)/,
|
|
501
|
+
`$1 cp /opt/patch-9router.js /tmp/patch-9router.js\n`
|
|
502
|
+
);
|
|
499
503
|
if (!compose.includes('node /tmp/patch-9router.js || true')) {
|
|
500
504
|
compose = compose.replace(
|
|
501
505
|
/(\s*node \/tmp\/sync\.js > \/tmp\/sync\.log 2>&1 &\n)/,
|
|
@@ -2158,20 +2162,19 @@ async function main() {
|
|
|
2158
2162
|
|
|
2159
2163
|
|
|
2160
2164
|
// ── Docker artifacts: Dockerfile + docker-compose via shared buildDockerArtifacts() ──────
|
|
2161
|
-
const skillSlugs = SKILLS
|
|
2162
|
-
.filter(s => selectedSkills.includes(s.value) && s.slug)
|
|
2163
|
-
.map(s => s.slug);
|
|
2164
|
-
const skillInstallCmd = skillSlugs.length > 0
|
|
2165
|
-
? skillSlugs.map(s => `
|
|
2166
|
-
: '';
|
|
2165
|
+
const skillSlugs = SKILLS
|
|
2166
|
+
.filter(s => selectedSkills.includes(s.value) && s.slug)
|
|
2167
|
+
.map(s => s.slug);
|
|
2168
|
+
const skillInstallCmd = skillSlugs.length > 0
|
|
2169
|
+
? skillSlugs.map(s => `ensure_skill ${s}`).join('\n')
|
|
2170
|
+
: '';
|
|
2167
2171
|
const relayInstallCmd = (isMultiBot && channelKey === 'telegram')
|
|
2168
2172
|
? buildRelayPluginInstallCommand('openclaw')
|
|
2169
2173
|
: '';
|
|
2170
|
-
const zaloModInstallCmd = hasZaloPersonal(channelKey)
|
|
2171
|
-
? '
|
|
2172
|
-
: '';
|
|
2173
|
-
const
|
|
2174
|
-
const deviceApproveLoop = 'while true; do sleep 5; openclaw devices approve --latest 2>/dev/null || true; done >/dev/null 2>&1 &';
|
|
2174
|
+
const zaloModInstallCmd = hasZaloPersonal(channelKey)
|
|
2175
|
+
? 'ensure_plugin zalo-mod openclaw-zalo-mod'
|
|
2176
|
+
: '';
|
|
2177
|
+
const deviceApproveLoop = 'while true; do sleep 5; openclaw devices approve --latest 2>/dev/null || true; done >/dev/null 2>&1 &';
|
|
2175
2178
|
|
|
2176
2179
|
// buildDockerArtifacts joins runtimeCommandParts with spaces, then appends 'openclaw gateway run'
|
|
2177
2180
|
// Each part should be a standalone command fragment (no trailing &&)
|
|
@@ -2183,14 +2186,13 @@ async function main() {
|
|
|
2183
2186
|
isMultiBot,
|
|
2184
2187
|
hasBrowser: hasBrowserDesktop || hasBrowserServer,
|
|
2185
2188
|
selectedModel: modelsPrimary,
|
|
2186
|
-
agentId,
|
|
2187
|
-
runtimeCommandParts: [
|
|
2188
|
-
|
|
2189
|
-
relayInstallCmd
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
].filter(Boolean),
|
|
2189
|
+
agentId,
|
|
2190
|
+
runtimeCommandParts: [
|
|
2191
|
+
zaloModInstallCmd,
|
|
2192
|
+
relayInstallCmd,
|
|
2193
|
+
skillInstallCmd,
|
|
2194
|
+
deviceApproveLoop,
|
|
2195
|
+
].filter(Boolean),
|
|
2194
2196
|
volumeMount: '../..:/root/project',
|
|
2195
2197
|
singleComposeName: `oc-${agentId}`,
|
|
2196
2198
|
multiComposeName: 'oc-multibot',
|
|
@@ -261,6 +261,14 @@
|
|
|
261
261
|
channels.zalouser = {
|
|
262
262
|
enabled: true,
|
|
263
263
|
defaultAccount: 'default',
|
|
264
|
+
accounts: {
|
|
265
|
+
default: {
|
|
266
|
+
dmPolicy: 'open',
|
|
267
|
+
allowFrom: ['*'],
|
|
268
|
+
groupPolicy: 'allowlist',
|
|
269
|
+
groupAllowFrom: ['*'],
|
|
270
|
+
},
|
|
271
|
+
},
|
|
264
272
|
dmPolicy: 'open',
|
|
265
273
|
allowFrom: ['*'],
|
|
266
274
|
groupPolicy: 'allowlist',
|
|
@@ -304,6 +312,7 @@
|
|
|
304
312
|
enabled: true,
|
|
305
313
|
config: {
|
|
306
314
|
botName: botName,
|
|
315
|
+
ownerId: "",
|
|
307
316
|
groupNames: {},
|
|
308
317
|
zaloDisplayNames: [botName],
|
|
309
318
|
welcomeEnabled: true,
|
|
@@ -311,7 +320,6 @@
|
|
|
311
320
|
spamWindowSeconds: 300,
|
|
312
321
|
},
|
|
313
322
|
};
|
|
314
|
-
entries.zalouser = { enabled: true };
|
|
315
323
|
}
|
|
316
324
|
|
|
317
325
|
const plugins = { entries };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
(function (root) {
|
|
3
|
-
const OPENCLAW_NPM_SPEC = 'openclaw@
|
|
3
|
+
const OPENCLAW_NPM_SPEC = 'openclaw@2026.4.15';
|
|
4
4
|
const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
|
|
5
5
|
const NINE_ROUTER_NPM_SPEC = '9router@latest';
|
|
6
6
|
const NINE_ROUTER_PORT = 20128;
|
|
@@ -39,11 +39,26 @@ const sync = async () => {
|
|
|
39
39
|
if (!res.ok) { console.log('[sync-combo] API not ready, retrying...'); return; }
|
|
40
40
|
const d = await res.json();
|
|
41
41
|
const rawConnections = Array.isArray(d.connections) ? d.connections : Array.isArray(d.providerConnections) ? d.providerConnections : [];
|
|
42
|
-
const
|
|
43
|
-
|
|
42
|
+
const activeConns = rawConnections.filter(c => c && c.provider && c.isActive !== false && !c.disabled);
|
|
43
|
+
const a = [...new Set(activeConns.map(c => c.provider))];
|
|
44
|
+
if (!a.length) { console.log('[sync-combo] No active providers reported; keeping existing smart-route'); return; }
|
|
44
45
|
a.sort((x, y) => (PREF.indexOf(x) === -1 ? 99 : PREF.indexOf(x)) - (PREF.indexOf(y) === -1 ? 99 : PREF.indexOf(y)));
|
|
45
|
-
const m =
|
|
46
|
-
|
|
46
|
+
const m = [];
|
|
47
|
+
for (const pv of a) {
|
|
48
|
+
if (PM[pv]) m.push(...PM[pv]);
|
|
49
|
+
const conns = activeConns.filter(c => c.provider === pv);
|
|
50
|
+
for (const c of conns) {
|
|
51
|
+
if (Array.isArray(c.models)) {
|
|
52
|
+
for (const mdl of c.models) {
|
|
53
|
+
const mdlId = typeof mdl === 'string' ? mdl : mdl.id;
|
|
54
|
+
if (mdlId && !m.includes(mdlId) && !m.includes(pv + '/' + mdlId)) {
|
|
55
|
+
m.push(pv + '/' + mdlId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!m.length) { console.log('[sync-combo] No mapped models for active providers; keeping existing smart-route'); return; }
|
|
47
62
|
const c = { id: 'smart-route', name: 'smart-route', alias: 'smart-route', models: m };
|
|
48
63
|
const i = db.combos.findIndex(x => x.id === 'smart-route');
|
|
49
64
|
if (i >= 0) {
|
|
@@ -155,7 +170,7 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
|
|
|
155
170
|
dockerfilePlugins = [],
|
|
156
171
|
dockerfileSkillInstallMode = 'none',
|
|
157
172
|
runtimeCommandParts = [],
|
|
158
|
-
volumeMount = '
|
|
173
|
+
volumeMount = '../../.openclaw:/root/project/.openclaw\\n - ../../:/mnt/project',
|
|
159
174
|
singleComposeName = 'oc-bot',
|
|
160
175
|
multiComposeName = 'oc-multibot',
|
|
161
176
|
singleAppContainerName = 'openclaw-bot',
|
|
@@ -191,50 +206,50 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
|
|
|
191
206
|
: '';
|
|
192
207
|
const patchLine = `RUN node -e "const fs=require('fs');const path=require('path');const dir='/usr/local/lib/node_modules/openclaw/dist';const from='\\t\\t\\t\\t\\tonAgentRunStart: (runId) => {';const to='\\t\\t\\t\\t\\ttimeoutOverrideSeconds: Math.max(1, Math.ceil(timeoutMs / 1e3)),\\n\\t\\t\\t\\t\\tonAgentRunStart: (runId) => {';const files=fs.readdirSync(dir).filter(n=>/\\.js$/.test(n));let patched=0;for(const file of files){const p=path.join(dir,file);let s='';try{s=fs.readFileSync(p,'utf8');}catch{continue;}if(s.includes(to)||!s.includes(from))continue;s=s.replace(from,to);fs.writeFileSync(p,s);patched++;}if(!patched){process.exit(0);}"`;
|
|
193
208
|
|
|
194
|
-
// Dynamic runtime configuration: backup config before any first-run install, restore after.
|
|
195
|
-
// Missing plugin install may touch openclaw.json, so preserve critical fields.
|
|
209
|
+
// Dynamic runtime configuration: backup config before any first-run install, restore after.
|
|
210
|
+
// Missing plugin install may touch openclaw.json, so preserve critical fields.
|
|
196
211
|
const backupConfigScript = `const fs=require('fs'),path=require('path'),p=path.join(process.cwd(),'.openclaw','openclaw.json'),b=p.replace('openclaw.json','.openclaw-config-backup.json');if(fs.existsSync(p)){fs.copyFileSync(p,b);}`;
|
|
197
212
|
const backupConfigB64 = encodeBase64Utf8(backupConfigScript);
|
|
198
213
|
|
|
199
214
|
const restoreConfigScript = `const fs=require('fs'),os=require('os'),path=require('path'),p=path.join(process.cwd(),'.openclaw','openclaw.json'),b=p.replace('openclaw.json','.openclaw-config-backup.json');if(fs.existsSync(p)&&fs.existsSync(b)){const c=JSON.parse(fs.readFileSync(p,'utf8'));const bk=JSON.parse(fs.readFileSync(b,'utf8'));const keep=['agents','channels','bindings','commands','models','browser','skills'];for(const k of keep){if(bk[k]&&!c[k])c[k]=bk[k];}const a=new Set(['http://localhost:18791','http://127.0.0.1:18791','http://0.0.0.0:18791']);for(const entries of Object.values(os.networkInterfaces()||{})){for(const entry of entries||[]){if(!entry||entry.internal||entry.family!=='IPv4'||!entry.address)continue;a.add('http://'+entry.address+':18791');}}c.tools=Object.assign({},c.tools,{profile:'full',exec:{host:'gateway',security:'full',ask:'off'}});c.gateway=Object.assign({},c.gateway,{port:18791,bind:'custom',customBindHost:'0.0.0.0',mode:c.gateway?.mode||bk.gateway?.mode||'local',controlUi:Object.assign({},c.gateway?.controlUi,{allowedOrigins:Array.from(a).filter(Boolean)})});fs.writeFileSync(p,JSON.stringify(c,null,2));fs.unlinkSync(b);}`;
|
|
200
215
|
const restoreConfigB64 = encodeBase64Utf8(restoreConfigScript);
|
|
201
216
|
|
|
202
|
-
const runtimeParts = runtimeCommandParts.filter(Boolean);
|
|
203
|
-
const runtimePrelude = [
|
|
204
|
-
'export OPENCLAW_HOME="${OPENCLAW_HOME:-$PWD/.openclaw}"',
|
|
205
|
-
'export OPENCLAW_STATE_DIR="${OPENCLAW_STATE_DIR:-$OPENCLAW_HOME}"',
|
|
206
|
-
'mkdir -p "$OPENCLAW_HOME" "$OPENCLAW_STATE_DIR"',
|
|
207
|
-
'if [ "$OPENCLAW_STATE_DIR" != "$OPENCLAW_HOME" ]; then',
|
|
208
|
-
' for path in "$OPENCLAW_HOME"/*; do',
|
|
209
|
-
' [ -e "$path" ] || continue',
|
|
210
|
-
' name="$(basename "$path")"',
|
|
211
|
-
' [ "$name" = "plugin-runtime-deps" ] && continue',
|
|
212
|
-
' [ "$name" = "logs" ] && continue',
|
|
213
|
-
' [ -e "$OPENCLAW_STATE_DIR/$name" ] || ln -s "$path" "$OPENCLAW_STATE_DIR/$name"',
|
|
214
|
-
' done',
|
|
215
|
-
'fi',
|
|
216
|
-
'ensure_plugin() {',
|
|
217
|
-
' id="$1"',
|
|
218
|
-
' spec="$2"',
|
|
219
|
-
' if [ -d "$OPENCLAW_HOME/extensions/$id" ]; then',
|
|
220
|
-
' echo "[entrypoint] plugin $id already installed"',
|
|
221
|
-
' return 0',
|
|
222
|
-
' fi',
|
|
223
|
-
' echo "[entrypoint] plugin $id missing; installing $spec"',
|
|
224
|
-
' openclaw plugins install "$spec" 2>/dev/null || echo "[entrypoint] warning: failed to install plugin $spec"',
|
|
225
|
-
'}',
|
|
226
|
-
'ensure_skill() {',
|
|
227
|
-
' id="$1"',
|
|
228
|
-
' if find "$OPENCLAW_HOME" -maxdepth 4 -type d -path "*/skills/$id" -print -quit 2>/dev/null | grep -q .; then',
|
|
229
|
-
' echo "[entrypoint] skill $id already installed"',
|
|
230
|
-
' return 0',
|
|
231
|
-
' fi',
|
|
232
|
-
' echo "[entrypoint] skill $id missing; installing"',
|
|
233
|
-
' openclaw skills install "$id" 2>/dev/null || echo "[entrypoint] warning: failed to install skill $id"',
|
|
234
|
-
'}',
|
|
235
|
-
'echo "[entrypoint] ensuring runtime assets, then starting gateway"',
|
|
236
|
-
];
|
|
237
|
-
runtimeParts.unshift(...runtimePrelude);
|
|
217
|
+
const runtimeParts = runtimeCommandParts.filter(Boolean);
|
|
218
|
+
const runtimePrelude = [
|
|
219
|
+
'export OPENCLAW_HOME="${OPENCLAW_HOME:-$PWD/.openclaw}"',
|
|
220
|
+
'export OPENCLAW_STATE_DIR="${OPENCLAW_STATE_DIR:-$OPENCLAW_HOME}"',
|
|
221
|
+
'mkdir -p "$OPENCLAW_HOME" "$OPENCLAW_STATE_DIR"',
|
|
222
|
+
'if [ "$OPENCLAW_STATE_DIR" != "$OPENCLAW_HOME" ]; then',
|
|
223
|
+
' for path in "$OPENCLAW_HOME"/*; do',
|
|
224
|
+
' [ -e "$path" ] || continue',
|
|
225
|
+
' name="$(basename "$path")"',
|
|
226
|
+
' [ "$name" = "plugin-runtime-deps" ] && continue',
|
|
227
|
+
' [ "$name" = "logs" ] && continue',
|
|
228
|
+
' [ -e "$OPENCLAW_STATE_DIR/$name" ] || ln -s "$path" "$OPENCLAW_STATE_DIR/$name"',
|
|
229
|
+
' done',
|
|
230
|
+
'fi',
|
|
231
|
+
'ensure_plugin() {',
|
|
232
|
+
' id="$1"',
|
|
233
|
+
' spec="$2"',
|
|
234
|
+
' if [ -d "$OPENCLAW_HOME/extensions/$id" ]; then',
|
|
235
|
+
' echo "[entrypoint] plugin $id already installed"',
|
|
236
|
+
' return 0',
|
|
237
|
+
' fi',
|
|
238
|
+
' echo "[entrypoint] plugin $id missing; installing $spec"',
|
|
239
|
+
' openclaw plugins install "$spec" 2>/dev/null || echo "[entrypoint] warning: failed to install plugin $spec"',
|
|
240
|
+
'}',
|
|
241
|
+
'ensure_skill() {',
|
|
242
|
+
' id="$1"',
|
|
243
|
+
' if find "$OPENCLAW_HOME" -maxdepth 4 -type d -path "*/skills/$id" -print -quit 2>/dev/null | grep -q .; then',
|
|
244
|
+
' echo "[entrypoint] skill $id already installed"',
|
|
245
|
+
' return 0',
|
|
246
|
+
' fi',
|
|
247
|
+
' echo "[entrypoint] skill $id missing; installing"',
|
|
248
|
+
' openclaw skills install "$id" 2>/dev/null || echo "[entrypoint] warning: failed to install skill $id"',
|
|
249
|
+
'}',
|
|
250
|
+
'echo "[entrypoint] ensuring runtime assets, then starting gateway"',
|
|
251
|
+
];
|
|
252
|
+
runtimeParts.unshift(...runtimePrelude);
|
|
238
253
|
// Backup config BEFORE plugin installs (runtimeCommandParts may contain plugin install commands)
|
|
239
254
|
runtimeParts.unshift(`node -e 'eval(Buffer.from("${backupConfigB64}","base64").toString())'`);
|
|
240
255
|
// Restore config AFTER plugin installs (which may clobber openclaw.json)
|
|
@@ -253,7 +268,7 @@ RUN apt-get update && apt-get install -y git curl${browserAptExtra} && rm -rf /v
|
|
|
253
268
|
${browserInstallLines}
|
|
254
269
|
ARG OPENCLAW_VER="${openClawNpmSpec}"
|
|
255
270
|
ARG CACHE_BUST=""
|
|
256
|
-
RUN npm install -g $
|
|
271
|
+
RUN echo "CACHE_BUST=$CACHE_BUST" && npm install -g $OPENCLAW_VER ${openClawRuntimePackages}${skillLines}${pluginLines}
|
|
257
272
|
${patchLine}
|
|
258
273
|
RUN node -e "require('fs').writeFileSync('/usr/local/bin/openclaw-entrypoint.sh', Buffer.from('${runtimeScriptB64}','base64').toString())" && chmod +x /usr/local/bin/openclaw-entrypoint.sh
|
|
259
274
|
WORKDIR /root/project
|
|
@@ -264,12 +279,12 @@ CMD ["/bin/sh", "/usr/local/bin/openclaw-entrypoint.sh"]`;
|
|
|
264
279
|
|
|
265
280
|
const syncScript = build9RouterSmartRouteSyncScript('/root/.9router/db.json');
|
|
266
281
|
const syncScriptBase64 = encodeBase64Utf8(syncScript);
|
|
267
|
-
|
|
282
|
+
const patchScript = build9RouterPatchScript();
|
|
268
283
|
const patchScriptBase64 = encodeBase64Utf8(patchScript);
|
|
269
284
|
const docker9RouterEntrypointScript = build9RouterComposeEntrypointScript(syncScriptBase64, patchScriptBase64);
|
|
270
285
|
const extraHostsBlock = ` extra_hosts:\n - "host.docker.internal:host-gateway"`;
|
|
271
286
|
|
|
272
|
-
const appEnvironmentBlock = ' environment:\n - OPENCLAW_HOME=/root/project/.openclaw\n - OPENCLAW_STATE_DIR=/root/project/.openclaw\n';
|
|
287
|
+
const appEnvironmentBlock = ' environment:\n - OPENCLAW_HOME=/root/project/.openclaw\n - OPENCLAW_STATE_DIR=/root/project/.openclaw\n - OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1\n tmpfs:\n - /root/project/.openclaw/plugin-runtime-deps\n';
|
|
273
288
|
|
|
274
289
|
let compose;
|
|
275
290
|
if (isMultiBot) {
|
|
@@ -462,7 +477,7 @@ ${appEnvironmentBlock}${plainSingleExtraHosts ? `${extraHostsBlock}\n` : ''}
|
|
|
462
477
|
- "18791:18791"`;
|
|
463
478
|
}
|
|
464
479
|
|
|
465
|
-
return {
|
|
480
|
+
return {
|
|
466
481
|
dockerfile,
|
|
467
482
|
compose,
|
|
468
483
|
syncScript,
|
package/dist/setup.js
CHANGED
|
@@ -619,7 +619,7 @@
|
|
|
619
619
|
// ── Shared runtime constants, relay helpers, auth profile builders (setup/shared/common-gen.js)
|
|
620
620
|
// @ts-nocheck
|
|
621
621
|
(function (root) {
|
|
622
|
-
const OPENCLAW_NPM_SPEC = 'openclaw@
|
|
622
|
+
const OPENCLAW_NPM_SPEC = 'openclaw@2026.4.15';
|
|
623
623
|
const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
|
|
624
624
|
const NINE_ROUTER_NPM_SPEC = '9router@latest';
|
|
625
625
|
const NINE_ROUTER_PORT = 20128;
|
|
@@ -1699,6 +1699,14 @@ if (typeof exports !== 'undefined' && workspaceRoot.__openclawWorkspace) {
|
|
|
1699
1699
|
channels.zalouser = {
|
|
1700
1700
|
enabled: true,
|
|
1701
1701
|
defaultAccount: 'default',
|
|
1702
|
+
accounts: {
|
|
1703
|
+
default: {
|
|
1704
|
+
dmPolicy: 'open',
|
|
1705
|
+
allowFrom: ['*'],
|
|
1706
|
+
groupPolicy: 'allowlist',
|
|
1707
|
+
groupAllowFrom: ['*'],
|
|
1708
|
+
},
|
|
1709
|
+
},
|
|
1702
1710
|
dmPolicy: 'open',
|
|
1703
1711
|
allowFrom: ['*'],
|
|
1704
1712
|
groupPolicy: 'allowlist',
|
|
@@ -1742,6 +1750,7 @@ if (typeof exports !== 'undefined' && workspaceRoot.__openclawWorkspace) {
|
|
|
1742
1750
|
enabled: true,
|
|
1743
1751
|
config: {
|
|
1744
1752
|
botName: botName,
|
|
1753
|
+
ownerId: "",
|
|
1745
1754
|
groupNames: {},
|
|
1746
1755
|
zaloDisplayNames: [botName],
|
|
1747
1756
|
welcomeEnabled: true,
|
|
@@ -1749,7 +1758,6 @@ if (typeof exports !== 'undefined' && workspaceRoot.__openclawWorkspace) {
|
|
|
1749
1758
|
spamWindowSeconds: 300,
|
|
1750
1759
|
},
|
|
1751
1760
|
};
|
|
1752
|
-
entries.zalouser = { enabled: true };
|
|
1753
1761
|
}
|
|
1754
1762
|
|
|
1755
1763
|
const plugins = { entries };
|
|
@@ -2513,11 +2521,26 @@ const sync = async () => {
|
|
|
2513
2521
|
if (!res.ok) { console.log('[sync-combo] API not ready, retrying...'); return; }
|
|
2514
2522
|
const d = await res.json();
|
|
2515
2523
|
const rawConnections = Array.isArray(d.connections) ? d.connections : Array.isArray(d.providerConnections) ? d.providerConnections : [];
|
|
2516
|
-
const
|
|
2517
|
-
|
|
2524
|
+
const activeConns = rawConnections.filter(c => c && c.provider && c.isActive !== false && !c.disabled);
|
|
2525
|
+
const a = [...new Set(activeConns.map(c => c.provider))];
|
|
2526
|
+
if (!a.length) { console.log('[sync-combo] No active providers reported; keeping existing smart-route'); return; }
|
|
2518
2527
|
a.sort((x, y) => (PREF.indexOf(x) === -1 ? 99 : PREF.indexOf(x)) - (PREF.indexOf(y) === -1 ? 99 : PREF.indexOf(y)));
|
|
2519
|
-
const m =
|
|
2520
|
-
|
|
2528
|
+
const m = [];
|
|
2529
|
+
for (const pv of a) {
|
|
2530
|
+
if (PM[pv]) m.push(...PM[pv]);
|
|
2531
|
+
const conns = activeConns.filter(c => c.provider === pv);
|
|
2532
|
+
for (const c of conns) {
|
|
2533
|
+
if (Array.isArray(c.models)) {
|
|
2534
|
+
for (const mdl of c.models) {
|
|
2535
|
+
const mdlId = typeof mdl === 'string' ? mdl : mdl.id;
|
|
2536
|
+
if (mdlId && !m.includes(mdlId) && !m.includes(pv + '/' + mdlId)) {
|
|
2537
|
+
m.push(pv + '/' + mdlId);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
if (!m.length) { console.log('[sync-combo] No mapped models for active providers; keeping existing smart-route'); return; }
|
|
2521
2544
|
const c = { id: 'smart-route', name: 'smart-route', alias: 'smart-route', models: m };
|
|
2522
2545
|
const i = db.combos.findIndex(x => x.id === 'smart-route');
|
|
2523
2546
|
if (i >= 0) {
|
|
@@ -2629,7 +2652,7 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
|
|
|
2629
2652
|
dockerfilePlugins = [],
|
|
2630
2653
|
dockerfileSkillInstallMode = 'none',
|
|
2631
2654
|
runtimeCommandParts = [],
|
|
2632
|
-
volumeMount = '
|
|
2655
|
+
volumeMount = '../../.openclaw:/root/project/.openclaw\\n - ../../:/mnt/project',
|
|
2633
2656
|
singleComposeName = 'oc-bot',
|
|
2634
2657
|
multiComposeName = 'oc-multibot',
|
|
2635
2658
|
singleAppContainerName = 'openclaw-bot',
|
|
@@ -2727,7 +2750,7 @@ RUN apt-get update && apt-get install -y git curl${browserAptExtra} && rm -rf /v
|
|
|
2727
2750
|
${browserInstallLines}
|
|
2728
2751
|
ARG OPENCLAW_VER="${openClawNpmSpec}"
|
|
2729
2752
|
ARG CACHE_BUST=""
|
|
2730
|
-
RUN npm install -g $
|
|
2753
|
+
RUN echo "CACHE_BUST=$CACHE_BUST" && npm install -g $OPENCLAW_VER ${openClawRuntimePackages}${skillLines}${pluginLines}
|
|
2731
2754
|
${patchLine}
|
|
2732
2755
|
RUN node -e "require('fs').writeFileSync('/usr/local/bin/openclaw-entrypoint.sh', Buffer.from('${runtimeScriptB64}','base64').toString())" && chmod +x /usr/local/bin/openclaw-entrypoint.sh
|
|
2733
2756
|
WORKDIR /root/project
|
|
@@ -2738,12 +2761,12 @@ CMD ["/bin/sh", "/usr/local/bin/openclaw-entrypoint.sh"]`;
|
|
|
2738
2761
|
|
|
2739
2762
|
const syncScript = build9RouterSmartRouteSyncScript('/root/.9router/db.json');
|
|
2740
2763
|
const syncScriptBase64 = encodeBase64Utf8(syncScript);
|
|
2741
|
-
|
|
2764
|
+
const patchScript = build9RouterPatchScript();
|
|
2742
2765
|
const patchScriptBase64 = encodeBase64Utf8(patchScript);
|
|
2743
2766
|
const docker9RouterEntrypointScript = build9RouterComposeEntrypointScript(syncScriptBase64, patchScriptBase64);
|
|
2744
2767
|
const extraHostsBlock = ` extra_hosts:\n - "host.docker.internal:host-gateway"`;
|
|
2745
2768
|
|
|
2746
|
-
const appEnvironmentBlock = ' environment:\n - OPENCLAW_HOME=/root/project/.openclaw\n - OPENCLAW_STATE_DIR=/root/project/.openclaw\n';
|
|
2769
|
+
const appEnvironmentBlock = ' environment:\n - OPENCLAW_HOME=/root/project/.openclaw\n - OPENCLAW_STATE_DIR=/root/project/.openclaw\n - OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1\n tmpfs:\n - /root/project/.openclaw/plugin-runtime-deps\n';
|
|
2747
2770
|
|
|
2748
2771
|
let compose;
|
|
2749
2772
|
if (isMultiBot) {
|
|
@@ -3963,7 +3986,7 @@ function generateWinBat(ctx) {
|
|
|
3963
3986
|
'echo [1/5] Kiem tra Node.js...',
|
|
3964
3987
|
'where node >nul 2>&1 || (echo ERROR: Node.js chua cai! Tai tai: https://nodejs.org && pause && exit /b 1)',
|
|
3965
3988
|
'echo [2/5] Cai OpenClaw CLI...',
|
|
3966
|
-
`call npm install -g
|
|
3989
|
+
`call npm install -g ${OPENCLAW_NPM_SPEC} ${openClawRuntimePackages} || goto :fail`,
|
|
3967
3990
|
'echo [OK] OpenClaw da duoc cai dat thanh cong.',
|
|
3968
3991
|
];
|
|
3969
3992
|
|
|
@@ -4153,7 +4176,7 @@ function generateMacOsSh(ctx) {
|
|
|
4153
4176
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.zshrc" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.zshrc"',
|
|
4154
4177
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.profile" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.profile"',
|
|
4155
4178
|
'# Install openclaw (user-local first, sudo fallback)',
|
|
4156
|
-
`npm install -g
|
|
4179
|
+
`npm install -g ${OPENCLAW_NPM_SPEC} ${openClawRuntimePackages} || sudo npm install -g ${OPENCLAW_NPM_SPEC} ${openClawRuntimePackages}`,
|
|
4157
4180
|
];
|
|
4158
4181
|
providerLines(sh, 'sh');
|
|
4159
4182
|
if (pluginCmd) sh.push(pluginCmd);
|
|
@@ -4219,7 +4242,7 @@ function generateVpsSh(ctx) {
|
|
|
4219
4242
|
'export DATA_DIR="$PROJECT_DIR/.9router"',
|
|
4220
4243
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.bashrc" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.bashrc"',
|
|
4221
4244
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.profile" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.profile"',
|
|
4222
|
-
`npm install -g
|
|
4245
|
+
`npm install -g ${OPENCLAW_NPM_SPEC} ${openClawRuntimePackages} pm2@latest`,
|
|
4223
4246
|
];
|
|
4224
4247
|
providerLines(vps, 'sh');
|
|
4225
4248
|
if (pluginCmd) vps.push(pluginCmd);
|
|
@@ -4342,7 +4365,7 @@ function generateLinuxSh(ctx) {
|
|
|
4342
4365
|
'export DATA_DIR="$PROJECT_DIR/.9router"',
|
|
4343
4366
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.bashrc" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.bashrc"',
|
|
4344
4367
|
'grep -Fqx \'export PATH="$HOME/.local/bin:$PATH"\' "$HOME/.profile" 2>/dev/null || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> "$HOME/.profile"',
|
|
4345
|
-
`npm install -g
|
|
4368
|
+
`npm install -g ${OPENCLAW_NPM_SPEC} ${openClawRuntimePackages}`,
|
|
4346
4369
|
];
|
|
4347
4370
|
providerLines(lnx, 'sh');
|
|
4348
4371
|
if (pluginCmd) lnx.push(pluginCmd);
|
|
@@ -5832,7 +5855,7 @@ Write-Host "Chrome se tu dong bat Debug Mode moi khi ban dang nhap Windows (dela
|
|
|
5832
5855
|
};
|
|
5833
5856
|
clawConfig.plugins = {
|
|
5834
5857
|
entries: {
|
|
5835
|
-
...(ch.hasZaloPersonal ? { 'zalo-mod': { enabled: true, config: {} } } : {}),
|
|
5858
|
+
...(ch.hasZaloPersonal ? { 'zalo-mod': { enabled: true, config: { botName: botName, ownerId: "", groupNames: {}, zaloDisplayNames: [botName], welcomeEnabled: true, spamRepeatN: 3, spamWindowSeconds: 300 } } } : {}),
|
|
5836
5859
|
'memory-core': {
|
|
5837
5860
|
config: { dreaming: { enabled: state.config.skills.includes('memory') } },
|
|
5838
5861
|
},
|
|
@@ -5847,7 +5870,18 @@ Write-Host "Chrome se tu dong bat Debug Mode moi khi ban dang nhap Windows (dela
|
|
|
5847
5870
|
pluginEntries[plugin.package || pid] = { enabled: true };
|
|
5848
5871
|
});
|
|
5849
5872
|
if (ch.hasZaloPersonal) {
|
|
5850
|
-
pluginEntries['zalo-mod'] = {
|
|
5873
|
+
pluginEntries['zalo-mod'] = {
|
|
5874
|
+
enabled: true,
|
|
5875
|
+
config: {
|
|
5876
|
+
botName: botName,
|
|
5877
|
+
ownerId: "",
|
|
5878
|
+
groupNames: {},
|
|
5879
|
+
zaloDisplayNames: [botName],
|
|
5880
|
+
welcomeEnabled: true,
|
|
5881
|
+
spamRepeatN: 3,
|
|
5882
|
+
spamWindowSeconds: 300
|
|
5883
|
+
}
|
|
5884
|
+
};
|
|
5851
5885
|
}
|
|
5852
5886
|
pluginEntries['memory-core'] = {
|
|
5853
5887
|
config: { dreaming: { enabled: state.config.skills.includes('memory') } },
|
|
@@ -5925,7 +5959,6 @@ model:
|
|
|
5925
5959
|
dockerfileSkillInstallMode: 'build',
|
|
5926
5960
|
runtimeCommandParts: [
|
|
5927
5961
|
pluginInstallCmd,
|
|
5928
|
-
hasBrowser ? 'socat TCP-LISTEN:9222,fork,reuseaddr TCP:host.docker.internal:9222 &' : '',
|
|
5929
5962
|
'while true; do sleep 5; openclaw devices approve --latest 2>/dev/null || true; done >/dev/null 2>&1 &'
|
|
5930
5963
|
],
|
|
5931
5964
|
plainSingleExtraHosts: true,
|
|
@@ -6561,7 +6594,7 @@ fi
|
|
|
6561
6594
|
: 'Ubuntu / VPS: The script auto-installs Node.js 20 LTS, OpenClaw CLI, and PM2 to keep the bot running after reboot.');
|
|
6562
6595
|
}
|
|
6563
6596
|
steps.push(_isVi ? '✅ Kiểm tra Node.js (cài tự động trên Ubuntu/VPS nếu chưa có)' : '✅ Check Node.js (auto-install on Ubuntu/VPS if missing)');
|
|
6564
|
-
steps.push(_isVi ?
|
|
6597
|
+
steps.push(_isVi ? `📦 Cài OpenClaw CLI (<code>npm install -g ${common.OPENCLAW_NPM_SPEC}</code>)` : `📦 Install OpenClaw CLI (<code>npm install -g ${common.OPENCLAW_NPM_SPEC}</code>)`);
|
|
6565
6598
|
if (_is9Router) {
|
|
6566
6599
|
steps.push(_isVi ? '🔀 Cài 9Router (<code>npm install -g 9router</code>) và khởi động tự động' : '🔀 Install 9Router (<code>npm install -g 9router</code>) and start automatically');
|
|
6567
6600
|
} else if (_isOllama) {
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
"name": "create-openclaw-bot",
|
|
3
|
-
"version": "5.7.
|
|
4
|
-
"description": "Interactive CLI installer for OpenClaw Bot",
|
|
5
|
-
"main": "dist/cli.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"create-openclaw-bot": "./dist/cli.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "node src/build.mjs --deploy",
|
|
14
|
-
"dev": "node src/build.mjs --deploy --watch",
|
|
15
|
-
"test": "node src/tests/smoke-cli-logic.mjs && node src/tests/test-generation.mjs && node src/tests/test-matrix.mjs",
|
|
16
|
-
"bump": "node src/bump-version.mjs"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"openclaw",
|
|
20
|
-
"cli",
|
|
21
|
-
"bot",
|
|
22
|
-
"zalo",
|
|
23
|
-
"telegram",
|
|
24
|
-
"ai"
|
|
25
|
-
],
|
|
26
|
-
"author": "tuanminhhole",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"@inquirer/prompts": "^4.3.1",
|
|
30
|
-
"chalk": "^5.3.0",
|
|
31
|
-
"fs-extra": "^11.2.0"
|
|
32
|
-
},
|
|
33
|
-
"bundleDependencies": [
|
|
34
|
-
"@inquirer/prompts",
|
|
35
|
-
"chalk",
|
|
36
|
-
"fs-extra"
|
|
37
|
-
],
|
|
38
|
-
"type": "module"
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "create-openclaw-bot",
|
|
3
|
+
"version": "5.7.7",
|
|
4
|
+
"description": "Interactive CLI installer for OpenClaw Bot",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-openclaw-bot": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "node src/build.mjs --deploy",
|
|
14
|
+
"dev": "node src/build.mjs --deploy --watch",
|
|
15
|
+
"test": "node src/tests/smoke-cli-logic.mjs && node src/tests/test-generation.mjs && node src/tests/test-matrix.mjs",
|
|
16
|
+
"bump": "node src/bump-version.mjs"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"openclaw",
|
|
20
|
+
"cli",
|
|
21
|
+
"bot",
|
|
22
|
+
"zalo",
|
|
23
|
+
"telegram",
|
|
24
|
+
"ai"
|
|
25
|
+
],
|
|
26
|
+
"author": "tuanminhhole",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@inquirer/prompts": "^4.3.1",
|
|
30
|
+
"chalk": "^5.3.0",
|
|
31
|
+
"fs-extra": "^11.2.0"
|
|
32
|
+
},
|
|
33
|
+
"bundleDependencies": [
|
|
34
|
+
"@inquirer/prompts",
|
|
35
|
+
"chalk",
|
|
36
|
+
"fs-extra"
|
|
37
|
+
],
|
|
38
|
+
"type": "module"
|
|
39
|
+
}
|