create-openclaw-bot 5.16.7 → 5.16.9
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 +2 -2
- package/README.vi.md +2 -2
- package/dist/cli.js +34 -0
- package/dist/server/local-server.js +52 -2
- package/dist/setup/shared/bot-config-gen.js +21 -1
- package/dist/setup/shared/common-gen.js +1 -1
- package/dist/setup/shared/docker-gen.js +1 -1
- package/dist/web/app.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*Run one command → open the dashboard → your bot is live. Windows · macOS · Linux · VPS — Docker-powered, auto-installed for you.*
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
|
-
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.16.
|
|
10
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.16.9-0EA5E9?style=for-the-badge" alt="Version 5.16.9" /></a>
|
|
11
11
|
<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>
|
|
12
12
|
<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>
|
|
13
13
|
<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>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
## 🆕 What's New in v5.16.
|
|
40
|
+
## 🆕 What's New in v5.16.9
|
|
41
41
|
|
|
42
42
|
- 🩹 **Native installs on OpenClaw 2026.8 are smooth from the first run** - this wave patches the remaining chain of issues measured on fresh customer machines: generated configs pass the new strict checks 100%, install steps run in the right order, and restarts/plugin installs no longer get blocked midway.
|
|
43
43
|
- 🔑 **9Router login works on Docker**: the new 9Router blocks the default password for "remote" access - and inside Docker every request counts as remote, so 123456 could never log in. It works now (still change the password once you're in).
|
package/README.vi.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*Chạy một lệnh → mở dashboard → bot lên sóng. Windows · macOS · Linux · VPS — chạy trên Docker, tự cài giúp bạn.*
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
|
-
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.16.
|
|
10
|
+
<a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.16.9-0EA5E9?style=for-the-badge" alt="Version 5.16.9" /></a>
|
|
11
11
|
<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>
|
|
12
12
|
<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>
|
|
13
13
|
<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>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
## 🆕 Có gì mới trong v5.16.
|
|
40
|
+
## 🆕 Có gì mới trong v5.16.9
|
|
41
41
|
|
|
42
42
|
- 🩹 **Cài native trên OpenClaw 2026.8 mượt từ phát đầu** - đợt này vá nốt chuỗi lỗi đo được khi dựng máy khách mới: cấu hình sinh ra sạch 100% với bộ soát khắt khe của OpenClaw mới, các bước cài tự chạy đúng thứ tự, và mọi thao tác khởi động lại/cài plugin không còn bị chặn giữa chừng.
|
|
43
43
|
- 🔑 **Đăng nhập 9Router hoạt động trên Docker**: bản 9Router mới chặn mật khẩu mặc định với truy cập "từ xa" - mà trong Docker thì mọi truy cập đều bị tính là từ xa, nên trước đây không cách nào vào được bằng 123456. Giờ đăng nhập bình thường (vào rồi vẫn nên đổi mật khẩu).
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,40 @@ import { spawn } from 'child_process';
|
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = path.dirname(__filename);
|
|
10
10
|
|
|
11
|
+
// `--version` / `--help` phải TRẢ LỜI RỒI THOÁT, đứng trước mọi thứ khác.
|
|
12
|
+
//
|
|
13
|
+
// Trước đây CLI không biết hai cờ này: gõ `create-openclaw-bot --version` là nó lờ đi rồi chạy
|
|
14
|
+
// tiếp như thường — tạo thư mục project, dựng Setup UI, **chiếm cổng 51789 và treo vĩnh viễn**.
|
|
15
|
+
// Đo trên vps_minh-thu 07/09: hai tiến trình `cli.js --version` nằm đó từ 02/09 giữ cổng, nên
|
|
16
|
+
// systemd relaunch bản mới xong không bind được cổng — bấm "Cập nhật" thành công mà giao diện
|
|
17
|
+
// vẫn là bản cũ, không ai hiểu vì sao.
|
|
18
|
+
{
|
|
19
|
+
const rawArgs = process.argv.slice(2);
|
|
20
|
+
if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
|
|
21
|
+
let v = '0.0.0';
|
|
22
|
+
try {
|
|
23
|
+
v = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf8')).version || v;
|
|
24
|
+
} catch {}
|
|
25
|
+
console.log(v);
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
29
|
+
console.log([
|
|
30
|
+
'create-openclaw-bot — trình cài đặt OpenClaw Bot',
|
|
31
|
+
'',
|
|
32
|
+
'Cách dùng: create-openclaw-bot [tuỳ chọn]',
|
|
33
|
+
'',
|
|
34
|
+
' --host=<địa chỉ> Địa chỉ Setup UI lắng nghe (mặc định 127.0.0.1)',
|
|
35
|
+
' --port=<cổng> Cổng Setup UI (mặc định 51789)',
|
|
36
|
+
' --project-dir=<đường> Thư mục project',
|
|
37
|
+
' --no-open Không tự mở trình duyệt',
|
|
38
|
+
' -v, --version In phiên bản rồi thoát',
|
|
39
|
+
' -h, --help In trợ giúp này rồi thoát',
|
|
40
|
+
].join('\n'));
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
11
45
|
const runCmd = (cmd, cmdArgs, opts = {}) => {
|
|
12
46
|
return new Promise((resolve, reject) => {
|
|
13
47
|
const child = spawn(cmd, cmdArgs, {
|
|
@@ -47,11 +47,26 @@ function specMajorMinor(spec) {
|
|
|
47
47
|
return m ? Number(m[1]) * 100 + Number(m[2]) : 0;
|
|
48
48
|
}
|
|
49
49
|
let hostOcMajorMinorCache = null;
|
|
50
|
+
/**
|
|
51
|
+
* Drop the cached host version. MUST be called right after `npm i -g openclaw@…` changes the
|
|
52
|
+
* global install, because the cache below survives the upgrade and every version-gated
|
|
53
|
+
* decision after it would still see the OLD runtime.
|
|
54
|
+
*/
|
|
55
|
+
function invalidateHostOpenclawVersion() {
|
|
56
|
+
hostOcMajorMinorCache = null;
|
|
57
|
+
}
|
|
50
58
|
async function hostOpenclawMajorMinor() {
|
|
51
59
|
// Cache only a REAL version: during bot creation this is first called before
|
|
52
60
|
// `npm i -g openclaw` has run, and caching that 0 forever made prepareNativeStateHome
|
|
53
61
|
// skip the 2026.8 state-home move — daemon install then failed with "non-default
|
|
54
62
|
// state dir" (measured on a fresh native install, 03/09/2026).
|
|
63
|
+
//
|
|
64
|
+
// A real-but-STALE version is just as bad and does not self-heal: on a host that already
|
|
65
|
+
// had an older openclaw (vps_mkt ran 2026.7.1-2), the first call caches 202607, the
|
|
66
|
+
// installer then upgrades the global package to 2026.9.x, and prepareNativeStateHome still
|
|
67
|
+
// reads 202607 → skips the state-home move → `daemon install` dies with "non-default state
|
|
68
|
+
// dir or config path" and the gateway never starts. Measured on vps_mkt, 07/09/2026.
|
|
69
|
+
// Hence invalidateHostOpenclawVersion() after every global install/upgrade.
|
|
55
70
|
if (hostOcMajorMinorCache) return hostOcMajorMinorCache;
|
|
56
71
|
const r = await runCapture('openclaw', ['--version'], { shell: false }).catch(() => null);
|
|
57
72
|
hostOcMajorMinorCache = specMajorMinor(r && (r.stdout || r.stderr));
|
|
@@ -3030,9 +3045,30 @@ async function runNativeConfigMigrations(projectDir) {
|
|
|
3030
3045
|
shell: false,
|
|
3031
3046
|
});
|
|
3032
3047
|
if (res.code !== 0) sendLog(`[native] config migrations skipped: ${String(res.stderr || res.stdout || '').trim().slice(0, 200)}`);
|
|
3048
|
+
await runOpenclawDoctorFixIfNeeded(projectDir);
|
|
3033
3049
|
return res.code === 0;
|
|
3034
3050
|
}
|
|
3035
3051
|
|
|
3052
|
+
/**
|
|
3053
|
+
* OpenClaw 2026.9 từ chối khởi động khi workspace còn ở dạng cũ:
|
|
3054
|
+
* "Gateway failed to start: Legacy workspace setup state requires migration for
|
|
3055
|
+
* …/workspace-<agent>; run openclaw doctor --fix."
|
|
3056
|
+
* Đo trên vps_thuy-le 07/09 — bot chết cho tới khi chạy tay `doctor --fix`. Việc dọn này chỉ
|
|
3057
|
+
* OpenClaw biết cách làm, nên gọi thẳng nó trước mỗi lần (re)start thay vì tự đoán rồi sửa mò.
|
|
3058
|
+
* Chỉ chạy trên 2026.9+ (bản cũ không có phép migrate đó), và lỗi ở đây KHÔNG chặn boot —
|
|
3059
|
+
* gateway vẫn được thử khởi động, cùng lắm là báo đúng lỗi cũ.
|
|
3060
|
+
*/
|
|
3061
|
+
async function runOpenclawDoctorFixIfNeeded(projectDir) {
|
|
3062
|
+
try {
|
|
3063
|
+
const ver = await hostOpenclawMajorMinor();
|
|
3064
|
+
if (!ver || ver < 202609) return;
|
|
3065
|
+
sendLog('[native] openclaw doctor --fix (2026.9 yêu cầu migrate workspace trước khi boot)…');
|
|
3066
|
+
await run('openclaw', ['doctor', '--fix'], { cwd: projectDir, env: openclawProjectEnv(projectDir) });
|
|
3067
|
+
} catch (err) {
|
|
3068
|
+
sendLog(`[native] doctor --fix bỏ qua: ${err?.message || String(err)}`);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3036
3072
|
async function restartNativeRuntime(projectDir) {
|
|
3037
3073
|
// Every restart is a chance to repair a project installed before these fixes existed — the
|
|
3038
3074
|
// calls are no-ops once the service env is complete, stray files are adopted, and the config
|
|
@@ -3787,6 +3823,7 @@ async function updateRuntime(target, projectDir) {
|
|
|
3787
3823
|
if (isNativeProject(projectDir)) {
|
|
3788
3824
|
sendLog(`[native] Updating ${target} → ${spec}`);
|
|
3789
3825
|
await run('npm', ['install', '-g', spec]);
|
|
3826
|
+
if (!isRouter) invalidateHostOpenclawVersion();
|
|
3790
3827
|
if (isRouter) await startNative9Router(projectDir, { restart: true }).catch((e) => sendLog(`[native] 9router restart: ${e.message}`));
|
|
3791
3828
|
else await restartNativeRuntime(projectDir);
|
|
3792
3829
|
await syncRuntimeState(projectDir, { full: true }).catch(() => {});
|
|
@@ -5373,6 +5410,9 @@ async function installCore({ osChoice, mode, projectDir, gatewayPort = 18789, ro
|
|
|
5373
5410
|
if (mode !== 'native') await ensureDockerInstalled(osChoice);
|
|
5374
5411
|
await writeCoreProject({ projectDir, osChoice, mode, gatewayPort, routerPort, userTimezone });
|
|
5375
5412
|
await run('npm', ['install', '-g', OPENCLAW_NPM_SPEC]);
|
|
5413
|
+
// The global runtime just changed — every version gate after this point (notably
|
|
5414
|
+
// prepareNativeStateHome) must read the NEW version, not the one this host booted with.
|
|
5415
|
+
invalidateHostOpenclawVersion();
|
|
5376
5416
|
await run('npm', ['install', '-g', NINE_ROUTER_NPM_SPEC]);
|
|
5377
5417
|
if (mode === 'docker') {
|
|
5378
5418
|
const dockerDir = join(projectDir, 'docker', 'openclaw');
|
|
@@ -6962,8 +7002,18 @@ async function handler(req, res, rootProjectDir) {
|
|
|
6962
7002
|
} else if (isGlobalNpm) {
|
|
6963
7003
|
// Pull the latest from npm in place, then exit — the service manager (or the
|
|
6964
7004
|
// respawn path for a hand-run UI) relaunches onto the freshly installed dist.
|
|
6965
|
-
|
|
6966
|
-
|
|
7005
|
+
// Cài vào ĐÚNG prefix của bản đang chạy, không phải prefix mà `npm` trong PATH
|
|
7006
|
+
// của service trỏ tới. Máy khách hay có HAI npm global (nvm + npm hệ thống): đo trên
|
|
7007
|
+
// vps_thuy-le 07/09 — bản đang chạy ở `/usr/lib/node_modules` (5.16.5) mà `npm i -g`
|
|
7008
|
+
// lại cài vào `/root/.nvm/versions/node/v24.20.0/lib/node_modules` (5.16.7). Log báo
|
|
7009
|
+
// "updated successfully", service restart, mà giao diện vẫn bản cũ — không ai hiểu nổi.
|
|
7010
|
+
// installerDir = <prefix>/lib/node_modules/create-openclaw-bot ⇒ lùi 3 cấp là prefix.
|
|
7011
|
+
const npmPrefix = resolve(installerDir, '..', '..', '..');
|
|
7012
|
+
const prefixArgs = /[\\/]lib[\\/]node_modules[\\/]create-openclaw-bot[\\/]?$/.test(installerDir)
|
|
7013
|
+
? ['--prefix', npmPrefix]
|
|
7014
|
+
: [];
|
|
7015
|
+
sendLog(`[update-setup] Global npm install detected — npm i -g create-openclaw-bot@latest${prefixArgs.length ? ` (prefix ${npmPrefix})` : ''}…`);
|
|
7016
|
+
await run('npm', ['i', '-g', 'create-openclaw-bot@latest', '--no-audit', '--no-fund', ...prefixArgs], { cwd: installerDir });
|
|
6967
7017
|
} else {
|
|
6968
7018
|
// Ephemeral `npx github:…` install: nothing to pull in place — the relaunch
|
|
6969
7019
|
// re-runs `npx github:…`, which fetches the latest from GitHub.
|
|
@@ -224,9 +224,29 @@
|
|
|
224
224
|
// reacts to messages that address the bot, since non-addressed ones are buffered as
|
|
225
225
|
// passive context before the reaction step.
|
|
226
226
|
if (isZaloPersonal(channelKey)) {
|
|
227
|
-
|
|
227
|
+
// KHÔNG khai `removeAckAfterReply`: OpenClaw 2026.9 bỏ khoá này và schema chặt từ chối
|
|
228
|
+
// khoá lạ — máy nâng lên 2026.9.2 sẽ chết với "messages: Unrecognized key" (đo trên
|
|
229
|
+
// vps_thuy-le 07/09, gateway không khởi động được cho tới khi gỡ khoá ra).
|
|
230
|
+
cfg.messages = { ackReaction: '/-heart', ackReactionScope: 'all' };
|
|
228
231
|
}
|
|
229
232
|
|
|
233
|
+
// ── session scope ─────────────────────────────────────────────────────────
|
|
234
|
+
// OpenClaw's own default (`main`) funnels EVERY direct message from EVERY person into a
|
|
235
|
+
// single shared session. Its runtime calls that out as a security problem verbatim:
|
|
236
|
+
// "⚠️ SECURITY: Multiple users sharing DM session.
|
|
237
|
+
// Configure \"session.dmScope: per-channel-peer\" in OpenClaw config."
|
|
238
|
+
// Two things go wrong in practice, both measured on vps_thuy-le 07/09/2026: the Control
|
|
239
|
+
// UI shows no DM session at all (there is nothing per-peer to list, so only groups
|
|
240
|
+
// appear), and the one shared session grows without bound until the model answers with
|
|
241
|
+
// an empty turn — "incomplete turn … payloads=0 tools=0" surfacing to the user as
|
|
242
|
+
// "⚠️ Agent couldn't generate a response".
|
|
243
|
+
// per-channel-peer (not per-peer) is the vendor's own wording and is the right split for
|
|
244
|
+
// a bot wired to several channels: the same person on Zalo and on Telegram stays apart.
|
|
245
|
+
// The key exists since 2026.7, so this is safe on every runtime setup installs.
|
|
246
|
+
// Only NEW configs get it — existing customer bots keep their current scope until
|
|
247
|
+
// someone changes it deliberately, because splitting sessions drops the old context.
|
|
248
|
+
cfg.session = { ...(cfg.session || {}), dmScope: 'per-channel-peer' };
|
|
249
|
+
|
|
230
250
|
// ── commands ──────────────────────────────────────────────────────────────
|
|
231
251
|
// No `ownerDisplay`: openclaw 2026.8.x strict schema rejects it as an unrecognized key
|
|
232
252
|
// and refuses to start (measured on vps_c-thu, 02/09/2026).
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// migration, va bot khach chet ngay sau mot lan bam rebuild vo hai (ca that 103.98.149.154,
|
|
6
6
|
// 31/08/2026: rebuild keo 2026.7.1-2 → 2026.8.1, gateway tu choi boot, 66 lan restart).
|
|
7
7
|
// Nang version = doi spec nay MOT CACH CO Y trong mot ban phat hanh setup, kem kiem chung.
|
|
8
|
-
const OPENCLAW_NPM_SPEC = 'openclaw@2026.
|
|
8
|
+
const OPENCLAW_NPM_SPEC = 'openclaw@2026.9.2';
|
|
9
9
|
const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
|
|
10
10
|
const NINE_ROUTER_NPM_SPEC = '9router@latest';
|
|
11
11
|
const NINE_ROUTER_PORT = 20128;
|
|
@@ -207,7 +207,7 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
|
|
|
207
207
|
// Gio gate theo version openclaw THAT trong container: <2026.8 thi backfill nhu cu, ≥2026.8 thi
|
|
208
208
|
// GO key neu con (tu chua cac project da nhiem). Khong doc duoc version thi KHONG dong nao chay
|
|
209
209
|
// — tha thieu mot default con hon gieo key lam gateway tu choi boot.
|
|
210
|
-
const contextDefaultsScript = `const fs=require('fs'),path=require('path');const p=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));let ch=false;c.skills=c.skills||{};c.skills.workshop=c.skills.workshop||{};if(!c.skills.workshop.approvalPolicy){c.skills.workshop.approvalPolicy='auto';ch=true;}if(c.browser&&c.browser.enabled!==false){c.tools=c.tools||{};const dn=Array.isArray(c.tools.deny)?c.tools.deny:[];if(!dn.includes('browser')){dn.push('browser');c.tools.deny=dn;ch=true;}}let ocMajorMinor=0;try{const v=String(require('child_process').execSync('openclaw --version',{stdio:['ignore','pipe','ignore']})).match(/(\\d{4})\\.(\\d+)/);if(v)ocMajorMinor=Number(v[1])*100+Number(v[2]);}catch(e){}const d=(c.agents&&c.agents.defaults)?c.agents.defaults:null;if(d){if(d.imageMaxDimensionPx===undefined){d.imageMaxDimensionPx=1024;ch=true;}if(d.imageQuality===undefined){d.imageQuality='efficient';ch=true;}if(ocMajorMinor&&ocMajorMinor<202608){d.contextLimits=d.contextLimits||{};if(d.contextLimits.toolResultMaxChars===undefined){d.contextLimits.toolResultMaxChars=12000;ch=true;}}else if(ocMajorMinor>=202608&&d.contextLimits&&d.contextLimits.toolResultMaxChars!==undefined){delete d.contextLimits.toolResultMaxChars;ch=true;}}c.gateway=(c.gateway&&typeof c.gateway==='object')?c.gateway:{};if(c.gateway.mode===undefined){c.gateway.mode='local';ch=true;console.log('[migrate] gateway.mode=local (2026.9 tu choi chay neu thieu)');}c.tools=c.tools||{};c.tools.sessions=(c.tools.sessions&&typeof c.tools.sessions==='object')?c.tools.sessions:{};if(c.tools.sessions.visibility===undefined){c.tools.sessions.visibility='agent';ch=true;console.log('[migrate] tools.sessions.visibility=agent (khong cho bot doc phien cua bot khac)');}if(ocMajorMinor>=202608&&d&&d.modelSelectionScope===undefined){d.modelSelectionScope='session';ch=true;console.log('[migrate] agents.defaults.modelSelectionScope=session (khong ghi de model trong config)');}if(ocMajorMinor>=202608){const ag=c.agents||{};const nEntries=(Array.isArray(ag.list)?ag.list.length:0)+(ag.entries&&typeof ag.entries==='object'?Object.keys(ag.entries).length:0);if(nEntries>1&&ag.ownership!=='explicit'){ag.ownership='explicit';c.agents=ag;ch=true;}try{const agRoot=path.join(process.cwd(),'.openclaw','agents');for(const id of fs.readdirSync(agRoot)){const sf=path.join(agRoot,id,'sessions','sessions.json');if(fs.existsSync(sf)){fs.renameSync(sf,sf+'.bak-legacy-'+Date.now());console.log('[migrate] parked legacy session store '+sf);}}}catch(e){}if(c.commands&&c.commands.ownerDisplay!==undefined){delete c.commands.ownerDisplay;ch=true;}if(c.plugins&&c.plugins.bundledDiscovery!==undefined){delete c.plugins.bundledDiscovery;ch=true;}if(Array.isArray(ag.list)){ag.entries=(ag.entries&&typeof ag.entries==='object'&&!Array.isArray(ag.entries))?ag.entries:{};for(const a of ag.list){if(a&&a.id&&!ag.entries[a.id]){const{id:_aid,...rest}=a;ag.entries[_aid]=rest;}}delete ag.list;c.agents=ag;ch=true;console.log('[migrate] moved agents.list into agents.entries');}try{const ea=path.join(process.cwd(),'.openclaw','exec-approvals.json');if(fs.existsSync(ea)){fs.renameSync(ea,ea+'.bak-legacy-'+Date.now());console.log('[migrate] parked legacy exec approvals '+ea);}}catch(e){}try{const ag2=c.agents||{};const ids=(ag2.entries&&typeof ag2.entries==='object')?Object.keys(ag2.entries):(Array.isArray(ag2.list)?ag2.list.map(function(a){return a&&a.id;}).filter(Boolean):[]);if(ids.length>1&&d){if(!(d.heartbeat&&d.heartbeat.agentId)){d.heartbeat=(d.heartbeat&&typeof d.heartbeat==='object')?d.heartbeat:{};d.heartbeat.agentId=ids[0];ch=true;console.log('[migrate] agents.defaults.heartbeat.agentId='+ids[0]+' (khong thi heartbeat tat cam)');}if(!(d.systemAgent&&d.systemAgent.agentId)){d.systemAgent=(d.systemAgent&&typeof d.systemAgent==='object')?d.systemAgent:{};d.systemAgent.agentId=ids[0];ch=true;console.log('[migrate] agents.defaults.systemAgent.agentId='+ids[0]+' (khong thi cron.list vo ca trang Automations)');}const tk=(c.talk&&typeof c.talk==='object')?c.talk:{};if(!tk.agentId){tk.agentId=ids[0];c.talk=tk;ch=true;console.log('[migrate] talk.agentId='+ids[0]+' (khong thi talk.catalog loi khi mo Control UI)');}}}catch(e){}}const pr=c.models&&c.models.providers&&c.models.providers['9router'];if(pr&&Array.isArray(pr.models)){for(const m of pr.models){if(m&&m.id==='smart-route'&&(m.contextWindow===200000||m.contextWindow===131072)){m.contextWindow=1048576;ch=true;}}}if(ch)fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
|
|
210
|
+
const contextDefaultsScript = `const fs=require('fs'),path=require('path');const p=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));let ch=false;c.skills=c.skills||{};c.skills.workshop=c.skills.workshop||{};if(!c.skills.workshop.approvalPolicy){c.skills.workshop.approvalPolicy='auto';ch=true;}if(c.browser&&c.browser.enabled!==false){c.tools=c.tools||{};const dn=Array.isArray(c.tools.deny)?c.tools.deny:[];if(!dn.includes('browser')){dn.push('browser');c.tools.deny=dn;ch=true;}}let ocMajorMinor=0;try{const v=String(require('child_process').execSync('openclaw --version',{stdio:['ignore','pipe','ignore']})).match(/(\\d{4})\\.(\\d+)/);if(v)ocMajorMinor=Number(v[1])*100+Number(v[2]);}catch(e){}const d=(c.agents&&c.agents.defaults)?c.agents.defaults:null;if(d){if(d.imageMaxDimensionPx===undefined){d.imageMaxDimensionPx=1024;ch=true;}if(d.imageQuality===undefined){d.imageQuality='efficient';ch=true;}if(ocMajorMinor&&ocMajorMinor<202608){d.contextLimits=d.contextLimits||{};if(d.contextLimits.toolResultMaxChars===undefined){d.contextLimits.toolResultMaxChars=12000;ch=true;}}else if(ocMajorMinor>=202608&&d.contextLimits&&d.contextLimits.toolResultMaxChars!==undefined){delete d.contextLimits.toolResultMaxChars;ch=true;}}if(ocMajorMinor>=202609){if(c.messages&&c.messages.removeAckAfterReply!==undefined){delete c.messages.removeAckAfterReply;ch=true;console.log('[migrate] go messages.removeAckAfterReply (2026.9 khong con nhan khoa nay)');}if(c.meta&&c.meta.lastTouchedAt!==undefined){delete c.meta.lastTouchedAt;ch=true;console.log('[migrate] go meta.lastTouchedAt (2026.9 khong con nhan khoa nay)');}if(c.browser&&c.browser.profiles&&typeof c.browser.profiles==='object'){for(const pn of Object.keys(c.browser.profiles)){const bp=c.browser.profiles[pn];if(bp&&typeof bp==='object'&&bp.color!==undefined){delete bp.color;ch=true;console.log('[migrate] go browser.profiles.'+pn+'.color (2026.9 khong con nhan khoa nay)');}}}}c.gateway=(c.gateway&&typeof c.gateway==='object')?c.gateway:{};if(c.gateway.mode===undefined){c.gateway.mode='local';ch=true;console.log('[migrate] gateway.mode=local (2026.9 tu choi chay neu thieu)');}c.tools=c.tools||{};c.tools.sessions=(c.tools.sessions&&typeof c.tools.sessions==='object')?c.tools.sessions:{};if(c.tools.sessions.visibility===undefined){c.tools.sessions.visibility='agent';ch=true;console.log('[migrate] tools.sessions.visibility=agent (khong cho bot doc phien cua bot khac)');}if(ocMajorMinor>=202608&&d&&d.modelSelectionScope===undefined){d.modelSelectionScope='session';ch=true;console.log('[migrate] agents.defaults.modelSelectionScope=session (khong ghi de model trong config)');}if(ocMajorMinor>=202608){const ag=c.agents||{};const nEntries=(Array.isArray(ag.list)?ag.list.length:0)+(ag.entries&&typeof ag.entries==='object'?Object.keys(ag.entries).length:0);if(nEntries>1&&ag.ownership!=='explicit'){ag.ownership='explicit';c.agents=ag;ch=true;}try{const agRoot=path.join(process.cwd(),'.openclaw','agents');for(const id of fs.readdirSync(agRoot)){const sf=path.join(agRoot,id,'sessions','sessions.json');if(fs.existsSync(sf)){fs.renameSync(sf,sf+'.bak-legacy-'+Date.now());console.log('[migrate] parked legacy session store '+sf);}}}catch(e){}if(c.commands&&c.commands.ownerDisplay!==undefined){delete c.commands.ownerDisplay;ch=true;}if(c.plugins&&c.plugins.bundledDiscovery!==undefined){delete c.plugins.bundledDiscovery;ch=true;}if(Array.isArray(ag.list)){ag.entries=(ag.entries&&typeof ag.entries==='object'&&!Array.isArray(ag.entries))?ag.entries:{};for(const a of ag.list){if(a&&a.id&&!ag.entries[a.id]){const{id:_aid,...rest}=a;ag.entries[_aid]=rest;}}delete ag.list;c.agents=ag;ch=true;console.log('[migrate] moved agents.list into agents.entries');}try{const ea=path.join(process.cwd(),'.openclaw','exec-approvals.json');if(fs.existsSync(ea)){fs.renameSync(ea,ea+'.bak-legacy-'+Date.now());console.log('[migrate] parked legacy exec approvals '+ea);}}catch(e){}try{const ag2=c.agents||{};const ids=(ag2.entries&&typeof ag2.entries==='object')?Object.keys(ag2.entries):(Array.isArray(ag2.list)?ag2.list.map(function(a){return a&&a.id;}).filter(Boolean):[]);if(ids.length>1&&d){if(!(d.heartbeat&&d.heartbeat.agentId)){d.heartbeat=(d.heartbeat&&typeof d.heartbeat==='object')?d.heartbeat:{};d.heartbeat.agentId=ids[0];ch=true;console.log('[migrate] agents.defaults.heartbeat.agentId='+ids[0]+' (khong thi heartbeat tat cam)');}if(!(d.systemAgent&&d.systemAgent.agentId)){d.systemAgent=(d.systemAgent&&typeof d.systemAgent==='object')?d.systemAgent:{};d.systemAgent.agentId=ids[0];ch=true;console.log('[migrate] agents.defaults.systemAgent.agentId='+ids[0]+' (khong thi cron.list vo ca trang Automations)');}const tk=(c.talk&&typeof c.talk==='object')?c.talk:{};if(!tk.agentId){tk.agentId=ids[0];c.talk=tk;ch=true;console.log('[migrate] talk.agentId='+ids[0]+' (khong thi talk.catalog loi khi mo Control UI)');}}}catch(e){}}const pr=c.models&&c.models.providers&&c.models.providers['9router'];if(pr&&Array.isArray(pr.models)){for(const m of pr.models){if(m&&m.id==='smart-route'&&(m.contextWindow===200000||m.contextWindow===131072)){m.contextWindow=1048576;ch=true;}}}if(ch)fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
|
|
211
211
|
|
|
212
212
|
function buildDockerArtifacts(options) {
|
|
213
213
|
const {
|
package/dist/web/app.js
CHANGED
|
@@ -455,9 +455,9 @@ function topbarActionsHtml() {
|
|
|
455
455
|
<button class="seg__btn ${state.lang==='en'?'is-active':''}" data-pref="lang" data-value="en">EN</button>
|
|
456
456
|
</div>
|
|
457
457
|
${hasNewVersion ? `
|
|
458
|
-
<button class="topbar__btn seg__btn" data-update-setup style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 6px; border: 1px solid var(--ok); background: rgba(46, 230, 166, 0.08); color: var(--ok); font-weight: 600; cursor: pointer; transition: background 0.2s;">
|
|
458
|
+
<button class="topbar__btn seg__btn" data-update-setup title="${t('Đang dùng', 'Currently on')} ${setupVer} — ${t('bấm để lên', 'click to upgrade to')} ${latestSetupVer}" style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 6px; border: 1px solid var(--ok); background: rgba(46, 230, 166, 0.08); color: var(--ok); font-weight: 600; cursor: pointer; transition: background 0.2s;">
|
|
459
459
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" style="width:14px; height:14px;"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>
|
|
460
|
-
<span>${t('Cập nhật', 'Update')}</span>
|
|
460
|
+
<span>${t('Cập nhật', 'Update')} ${latestSetupVer}</span>
|
|
461
461
|
</button>
|
|
462
462
|
` : ''}
|
|
463
463
|
`;
|