create-openclaw-bot 5.16.6 → 5.16.8
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 +33 -2
- package/dist/setup/shared/bot-config-gen.js +40 -2
- package/dist/setup/shared/common-gen.js +1 -1
- package/dist/setup/shared/docker-gen.js +1 -1
- package/dist/setup/shared/workspace-gen.js +10 -9
- 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.8-0EA5E9?style=for-the-badge" alt="Version 5.16.8" /></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.8
|
|
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.8-0EA5E9?style=for-the-badge" alt="Version 5.16.8" /></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.8
|
|
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, {
|
|
@@ -3030,9 +3030,30 @@ async function runNativeConfigMigrations(projectDir) {
|
|
|
3030
3030
|
shell: false,
|
|
3031
3031
|
});
|
|
3032
3032
|
if (res.code !== 0) sendLog(`[native] config migrations skipped: ${String(res.stderr || res.stdout || '').trim().slice(0, 200)}`);
|
|
3033
|
+
await runOpenclawDoctorFixIfNeeded(projectDir);
|
|
3033
3034
|
return res.code === 0;
|
|
3034
3035
|
}
|
|
3035
3036
|
|
|
3037
|
+
/**
|
|
3038
|
+
* OpenClaw 2026.9 từ chối khởi động khi workspace còn ở dạng cũ:
|
|
3039
|
+
* "Gateway failed to start: Legacy workspace setup state requires migration for
|
|
3040
|
+
* …/workspace-<agent>; run openclaw doctor --fix."
|
|
3041
|
+
* Đ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ỉ
|
|
3042
|
+
* 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ò.
|
|
3043
|
+
* 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 —
|
|
3044
|
+
* gateway vẫn được thử khởi động, cùng lắm là báo đúng lỗi cũ.
|
|
3045
|
+
*/
|
|
3046
|
+
async function runOpenclawDoctorFixIfNeeded(projectDir) {
|
|
3047
|
+
try {
|
|
3048
|
+
const ver = await hostOpenclawMajorMinor();
|
|
3049
|
+
if (!ver || ver < 202609) return;
|
|
3050
|
+
sendLog('[native] openclaw doctor --fix (2026.9 yêu cầu migrate workspace trước khi boot)…');
|
|
3051
|
+
await run('openclaw', ['doctor', '--fix'], { cwd: projectDir, env: openclawProjectEnv(projectDir) });
|
|
3052
|
+
} catch (err) {
|
|
3053
|
+
sendLog(`[native] doctor --fix bỏ qua: ${err?.message || String(err)}`);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3036
3057
|
async function restartNativeRuntime(projectDir) {
|
|
3037
3058
|
// Every restart is a chance to repair a project installed before these fixes existed — the
|
|
3038
3059
|
// calls are no-ops once the service env is complete, stray files are adopted, and the config
|
|
@@ -6962,8 +6983,18 @@ async function handler(req, res, rootProjectDir) {
|
|
|
6962
6983
|
} else if (isGlobalNpm) {
|
|
6963
6984
|
// Pull the latest from npm in place, then exit — the service manager (or the
|
|
6964
6985
|
// respawn path for a hand-run UI) relaunches onto the freshly installed dist.
|
|
6965
|
-
|
|
6966
|
-
|
|
6986
|
+
// Cài vào ĐÚNG prefix của bản đang chạy, không phải prefix mà `npm` trong PATH
|
|
6987
|
+
// của service trỏ tới. Máy khách hay có HAI npm global (nvm + npm hệ thống): đo trên
|
|
6988
|
+
// vps_thuy-le 07/09 — bản đang chạy ở `/usr/lib/node_modules` (5.16.5) mà `npm i -g`
|
|
6989
|
+
// lại cài vào `/root/.nvm/versions/node/v24.20.0/lib/node_modules` (5.16.7). Log báo
|
|
6990
|
+
// "updated successfully", service restart, mà giao diện vẫn bản cũ — không ai hiểu nổi.
|
|
6991
|
+
// installerDir = <prefix>/lib/node_modules/create-openclaw-bot ⇒ lùi 3 cấp là prefix.
|
|
6992
|
+
const npmPrefix = resolve(installerDir, '..', '..', '..');
|
|
6993
|
+
const prefixArgs = /[\\/]lib[\\/]node_modules[\\/]create-openclaw-bot[\\/]?$/.test(installerDir)
|
|
6994
|
+
? ['--prefix', npmPrefix]
|
|
6995
|
+
: [];
|
|
6996
|
+
sendLog(`[update-setup] Global npm install detected — npm i -g create-openclaw-bot@latest${prefixArgs.length ? ` (prefix ${npmPrefix})` : ''}…`);
|
|
6997
|
+
await run('npm', ['i', '-g', 'create-openclaw-bot@latest', '--no-audit', '--no-fund', ...prefixArgs], { cwd: installerDir });
|
|
6967
6998
|
} else {
|
|
6968
6999
|
// Ephemeral `npx github:…` install: nothing to pull in place — the relaunch
|
|
6969
7000
|
// re-runs `npx github:…`, which fetches the latest from GitHub.
|
|
@@ -149,6 +149,26 @@
|
|
|
149
149
|
// we use. This is the turn budget — a DIFFERENT layer from 9router's per-request
|
|
150
150
|
// timeout, so raising it does not conflict with / overrun 9router.
|
|
151
151
|
timeoutSeconds: 900,
|
|
152
|
+
// Đổi model trong Control UI KHÔNG được ghi vào config. OpenClaw mặc định "dính" lựa
|
|
153
|
+
// chọn model vào `agents.defaults.model` ([agents/sticky-model-selection] … target=defaults),
|
|
154
|
+
// nên một lần bấm nhầm là bot rời 9router vĩnh viễn, restart cũng không về. "session"
|
|
155
|
+
// giữ lựa chọn trong phiên đang chat. Khoá có từ OpenClaw 2026.8 (setup cài 2026.8.1).
|
|
156
|
+
modelSelectionScope: 'session',
|
|
157
|
+
// Nhiều agent mà không khai chủ thì OpenClaw TẮT heartbeat và chỉ ghi một dòng log:
|
|
158
|
+
// "[heartbeat] disabled — multi-agent config has no ambient heartbeat owner". Bot mất
|
|
159
|
+
// nhịp tự kiểm tra mà không ai hay. Chủ là bot THẬT đầu tiên, không phải agent `main`.
|
|
160
|
+
// Roster nhiều agent mà không khai chủ thì hỏng ba chỗ, đo được từng cái trên máy thật:
|
|
161
|
+
// • [heartbeat] disabled — bot mất nhịp tự kiểm tra, không báo gì
|
|
162
|
+
// • cron.list ✗ "Agent-less cron job has no resolvable owner" — VỠ CẢ TRANG Automations
|
|
163
|
+
// trong Control UI, vì job hệ thống (memory-dreaming…) không gắn agent nào
|
|
164
|
+
// • talk.catalog ✗ "Talk session ownership has no explicit owner"
|
|
165
|
+
// Chủ là bot THẬT đầu tiên, không phải agent `main` của gateway chat.
|
|
166
|
+
...(agentMetas.length > 1 && agentMetas[0]?.agentId
|
|
167
|
+
? {
|
|
168
|
+
heartbeat: { agentId: agentMetas[0].agentId },
|
|
169
|
+
systemAgent: { agentId: agentMetas[0].agentId },
|
|
170
|
+
}
|
|
171
|
+
: {}),
|
|
152
172
|
...(isLocal ? { llm: { idleTimeoutSeconds: 300 } } : {}),
|
|
153
173
|
},
|
|
154
174
|
list: agentsList,
|
|
@@ -204,7 +224,10 @@
|
|
|
204
224
|
// reacts to messages that address the bot, since non-addressed ones are buffered as
|
|
205
225
|
// passive context before the reaction step.
|
|
206
226
|
if (isZaloPersonal(channelKey)) {
|
|
207
|
-
|
|
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' };
|
|
208
231
|
}
|
|
209
232
|
|
|
210
233
|
// ── commands ──────────────────────────────────────────────────────────────
|
|
@@ -236,7 +259,15 @@
|
|
|
236
259
|
}
|
|
237
260
|
|
|
238
261
|
// ── tools ────────────────────────────────────────────────────────────────
|
|
239
|
-
cfg.tools = {
|
|
262
|
+
cfg.tools = {
|
|
263
|
+
profile: 'full',
|
|
264
|
+
exec: { host: 'gateway', security: 'full', ask: 'off' },
|
|
265
|
+
// Mặc định của OpenClaw là "all" — nguyên văn schema: "any session on the Gateway, including
|
|
266
|
+
// other agents and users". Máy khách hay chạy nhiều bot cho nhiều người, để nguyên là bot này
|
|
267
|
+
// đọc được hội thoại của bot kia qua sessions_history/sessions_search. "agent" giới hạn trong
|
|
268
|
+
// đúng agent của mình. (Khoá có ở cả 2026.7 lẫn 2026.8.)
|
|
269
|
+
sessions: { visibility: 'agent' },
|
|
270
|
+
};
|
|
240
271
|
const alsoAllow = [];
|
|
241
272
|
if (selectedSkills.includes('scheduler') || selectedSkills.includes('cron')) {
|
|
242
273
|
alsoAllow.push('group:automation');
|
|
@@ -291,6 +322,13 @@
|
|
|
291
322
|
// `osChoice === 'vps'` clause predates native mode; keep native on loopback and reach it through
|
|
292
323
|
// an SSH tunnel, which is what docker-on-a-VPS effectively does too.
|
|
293
324
|
const openGatewayBind = deployMode === 'docker' || (osChoice === 'vps' && deployMode !== 'native');
|
|
325
|
+
// Talk (thoại) cũng cần chủ khi có nhiều agent: "Multiple agents are configured, but Talk
|
|
326
|
+
// session ownership has no explicit owner. Set talk.agentId…" — không khai là talk.catalog
|
|
327
|
+
// lỗi ngay lúc mở Control UI.
|
|
328
|
+
if (agentMetas.length > 1 && agentMetas[0]?.agentId) {
|
|
329
|
+
cfg.talk = { ...(cfg.talk || {}), agentId: agentMetas[0].agentId };
|
|
330
|
+
}
|
|
331
|
+
|
|
294
332
|
cfg.gateway = {
|
|
295
333
|
port: gatewayPort,
|
|
296
334
|
mode: 'local',
|
|
@@ -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;}}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){}}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)');}}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 {
|
|
@@ -865,7 +865,7 @@ Skills cung cấp công cụ cho bạn. Cần cái nào, đọc \`SKILL.md\` c
|
|
|
865
865
|
|
|
866
866
|
Khi nhận heartbeat poll, đừng chỉ trả \`HEARTBEAT_OK\` mọi lần. Dùng heartbeat có ích!
|
|
867
867
|
|
|
868
|
-
|
|
868
|
+
Muốn nhớ việc gì giữa các nhịp, ghi checklist ngắn vào phần ghi chú (scratch) của chính automation đó — \`openclaw cron scratch\`. Giữ nó nhỏ để tiết kiệm token.
|
|
869
869
|
|
|
870
870
|
### Heartbeat vs Cron: dùng cái nào
|
|
871
871
|
|
|
@@ -873,7 +873,7 @@ Bạn được tự do sửa \`HEARTBEAT.md\` với checklist/ghi chú ngắn. G
|
|
|
873
873
|
|
|
874
874
|
**Cron khi:** cần giờ chính xác ("9:00 sáng thứ Hai"); task cần tách khỏi lịch sử main session; muốn model/thinking khác; nhắc một lần ("nhắc sau 20 phút"); kết quả gửi thẳng vào channel.
|
|
875
875
|
|
|
876
|
-
**Mẹo:** Gộp các check định kỳ tương tự vào
|
|
876
|
+
**Mẹo:** Gộp các check định kỳ tương tự vào MỘT automation thay vì tạo nhiều cron job.
|
|
877
877
|
|
|
878
878
|
**Nên check (xoay vòng, 2-4 lần/ngày):** email khẩn, lịch 24-48h tới, mentions, thời tiết (nếu chủ sắp ra ngoài).
|
|
879
879
|
|
|
@@ -911,8 +911,7 @@ Mục tiêu: hữu ích mà không phiền. Check vài lần một ngày, làm v
|
|
|
911
911
|
- 👤 **USER.md** — Thông tin và bối cảnh về User
|
|
912
912
|
- 💭 **MEMORY.md** — Bộ nhớ dài hạn
|
|
913
913
|
- ✨ **DREAMS.md** — Tự tổng hợp hoạt động trong ngày
|
|
914
|
-
-
|
|
915
|
-
- 🚀 **BOOTSTRAP.md** — Khởi động và thiết lập
|
|
914
|
+
- 🚀 **BOOTSTRAP.md** — Khởi động và thiết lập${otherAgents.length > 0 ? '\n- 👥 **TEAMS.md** — Các trợ lý khác cùng máy và cách gọi nhau' : ''}
|
|
916
915
|
|
|
917
916
|
## Make It Yours
|
|
918
917
|
|
|
@@ -1075,7 +1074,7 @@ Skills provide your tools. When you need one, check its \`SKILL.md\`. Keep local
|
|
|
1075
1074
|
|
|
1076
1075
|
When you receive a heartbeat poll, don't just reply \`HEARTBEAT_OK\` every time. Use heartbeats productively!
|
|
1077
1076
|
|
|
1078
|
-
|
|
1077
|
+
To remember things between beats, keep a short checklist in the automation's own scratch (\`openclaw cron scratch\`). Keep it small to limit token burn.
|
|
1079
1078
|
|
|
1080
1079
|
### Heartbeat vs Cron: When to Use Each
|
|
1081
1080
|
|
|
@@ -1083,7 +1082,7 @@ You are free to edit \`HEARTBEAT.md\` with a short checklist or reminders. Keep
|
|
|
1083
1082
|
|
|
1084
1083
|
**Use cron when:** exact timing matters ("9:00 AM sharp every Monday"); task needs isolation from main session history; you want a different model or thinking level; one-shot reminders ("remind me in 20 minutes"); output should deliver directly to a channel.
|
|
1085
1084
|
|
|
1086
|
-
**Tip:** Batch similar periodic checks into
|
|
1085
|
+
**Tip:** Batch similar periodic checks into ONE automation instead of creating multiple cron jobs.
|
|
1087
1086
|
|
|
1088
1087
|
**Things to check (rotate, 2-4 times per day):** urgent emails, calendar next 24-48h, mentions, weather (if your human might go out).
|
|
1089
1088
|
|
|
@@ -1121,8 +1120,7 @@ The goal: Be helpful without being annoying. Check in a few times a day, do usef
|
|
|
1121
1120
|
- 👤 **USER.md** — User info and context
|
|
1122
1121
|
- 💭 **MEMORY.md** — Long-term memory
|
|
1123
1122
|
- ✨ **DREAMS.md** — Daily activity self-summarization
|
|
1124
|
-
-
|
|
1125
|
-
- 🚀 **BOOTSTRAP.md** — Startup instructions
|
|
1123
|
+
- 🚀 **BOOTSTRAP.md** — Startup instructions${otherAgents.length > 0 ? '\n- 👥 **TEAMS.md** — Other assistants on this machine and how to reach them' : ''}
|
|
1126
1124
|
|
|
1127
1125
|
## Make It Yours
|
|
1128
1126
|
|
|
@@ -1425,7 +1423,10 @@ Add whatever helps you do your job. This is your cheat sheet.
|
|
|
1425
1423
|
isVi, skillListStr, workspacePath, variant, agentWorkspaceDir, hasBrowser, hasScheduler, hasZaloMod, browserDocVariant,
|
|
1426
1424
|
}),
|
|
1427
1425
|
'MEMORY.md': buildMemoryDoc({ isVi, variant: memoryVariant }),
|
|
1428
|
-
|
|
1426
|
+
// KHÔNG sinh HEARTBEAT.md nữa: từ OpenClaw 2026.8, nhịp kiểm tra định kỳ nằm trong scratch
|
|
1427
|
+
// của chính cron job, và doctor `core/doctor/heartbeat-scratch-migration` dời nội dung file
|
|
1428
|
+
// này sang đó rồi XOÁ file (`LEGACY_HEARTBEAT_FILENAME`). Setup mà cứ sinh lại thì mỗi lần
|
|
1429
|
+
// dựng workspace là một lần tái nhiễm — đúng vết xe của `toolResultMaxChars` hồi 5.16.1.
|
|
1429
1430
|
'BOOTSTRAP.md': buildBootstrapDoc({ isVi, botName }),
|
|
1430
1431
|
'DREAMS.md': buildDreamsDoc({ isVi }),
|
|
1431
1432
|
};
|
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
|
`;
|