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 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.7-0EA5E9?style=for-the-badge" alt="Version 5.16.7" /></a>
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.7
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.7-0EA5E9?style=for-the-badge" alt="Version 5.16.7" /></a>
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.7
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
- sendLog('[update-setup] Global npm install detected npm i -g create-openclaw-bot@latest…');
6966
- await run('npm', ['i', '-g', 'create-openclaw-bot@latest', '--no-audit', '--no-fund'], { cwd: installerDir });
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
- cfg.messages = { ackReaction: '/-heart', ackReactionScope: 'all', removeAckAfterReply: false };
227
+ // KHÔNG khai `removeAckAfterReply`: OpenClaw 2026.9 bỏ khoá này 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.1';
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
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.16.7",
3
+ "version": "5.16.9",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {