@qingchencloud/openclaw-zh 2026.1.29-nightly.202601301956 → 2026.1.29-nightly.202601302059

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +10 -9
  2. package/README.md +86 -20
  3. package/dist/agents/system-prompt.js +1 -1
  4. package/dist/build-info.json +3 -3
  5. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  6. package/dist/cli/cli-utils.js +10 -0
  7. package/dist/cli/models-cli.js +20 -8
  8. package/dist/cli/skills-cli.js +7 -7
  9. package/dist/commands/models/auth-order.js +2 -2
  10. package/dist/commands/models/list.status-command.js +37 -17
  11. package/dist/commands/models/shared.js +14 -0
  12. package/dist/control-ui/assets/{index-CNKLKKXX.js → index-Bpe27rQF.js} +2 -2
  13. package/dist/control-ui/assets/{index-CNKLKKXX.js.map → index-Bpe27rQF.js.map} +1 -1
  14. package/dist/control-ui/index.html +1 -1
  15. package/docs/cli/index.md +1 -1
  16. package/docs/cli/models.md +4 -0
  17. package/docs/cli/skills.md +1 -2
  18. package/docs/concepts/agent.md +2 -2
  19. package/docs/concepts/system-prompt.md +1 -1
  20. package/docs/docs.json +10 -2
  21. package/docs/help/faq.md +16 -16
  22. package/docs/install/installer.md +2 -2
  23. package/docs/providers/github-copilot.md +1 -1
  24. package/docs/start/hubs.md +1 -1
  25. package/docs/start/lore.md +1 -1
  26. package/docs/start/showcase.md +14 -14
  27. package/docs/start/wizard.md +8 -8
  28. package/docs/tools/{clawdhub.md → clawhub.md} +39 -39
  29. package/docs/tools/creating-skills.md +1 -1
  30. package/docs/tools/skills.md +9 -9
  31. package/package.json +1 -1
  32. package/skills/1password/SKILL.md +1 -1
  33. package/skills/bluebubbles/SKILL.md +1 -1
  34. package/skills/canvas/SKILL.md +3 -3
  35. package/skills/clawhub/SKILL.md +53 -0
  36. package/skills/nano-banana-pro/SKILL.md +1 -1
  37. package/skills/openai-whisper-api/SKILL.md +1 -1
  38. package/skills/session-logs/SKILL.md +6 -6
  39. package/skills/sherpa-onnx-tts/SKILL.md +6 -6
  40. package/skills/tmux/SKILL.md +4 -4
  41. package/skills/tmux/scripts/find-sessions.sh +2 -2
  42. package/skills/clawdhub/SKILL.md +0 -53
package/CHANGELOG.md CHANGED
@@ -41,11 +41,12 @@ Status: stable.
41
41
  - Routing: add per-account DM session scope and document multi-account isolation. (#3095) Thanks @jarvis-sam.
42
42
  - Routing: precompile session key regexes. (#1697) Thanks @Ray0907.
43
43
  - CLI: use Node's module compile cache for faster startup. (#2808) Thanks @pi0.
44
+ - CLI: add per-agent model status and auth order scoping. (#4780) Thanks @jlowin.
44
45
  - Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla.
45
46
  - Agents: add Kimi K2.5 to the synthetic model catalog. (#4407) Thanks @manikv12.
46
47
  - TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein.
47
48
  - macOS: finish OpenClaw app rename for macOS sources, bundle identifiers, and shared kit paths. (#2844) Thanks @fal3.
48
- - Branding: update launchd labels, mobile bundle IDs, and logging subsystems to bot.molt (legacy com.clawdbot migrations). Thanks @thewilloftheshadow.
49
+ - Branding: update launchd labels, mobile bundle IDs, and logging subsystems to bot.molt (legacy bundle ID migrations). Thanks @thewilloftheshadow.
49
50
  - macOS: limit project-local `node_modules/.bin` PATH preference to debug builds (reduce PATH hijacking risk).
50
51
  - macOS: keep custom SSH usernames in remote target. (#2046) Thanks @algal.
51
52
  - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn.
@@ -417,7 +418,7 @@ Status: stable.
417
418
  - Security: warn when <=300B models run without sandboxing while web tools are enabled. https://docs.openclaw.ai/cli/security
418
419
  - Exec: add host/security/ask routing for gateway + node exec. https://docs.openclaw.ai/tools/exec
419
420
  - Exec: add `/exec` directive for per-session exec defaults (host/security/ask/node). https://docs.openclaw.ai/tools/exec
420
- - Exec approvals: migrate approvals to `~/.clawdbot/exec-approvals.json` with per-agent allowlists + skill auto-allow toggle, and add approvals UI + node exec lifecycle events. https://docs.openclaw.ai/tools/exec-approvals
421
+ - Exec approvals: migrate approvals to `~/.openclaw/exec-approvals.json` with per-agent allowlists + skill auto-allow toggle, and add approvals UI + node exec lifecycle events. https://docs.openclaw.ai/tools/exec-approvals
421
422
  - Nodes: add headless node host (`openclaw node start`) for `system.run`/`system.which`. https://docs.openclaw.ai/cli/node
422
423
  - Nodes: add node daemon service install/status/start/stop/restart. https://docs.openclaw.ai/cli/node
423
424
  - Bridge: add `skills.bins` RPC to support node host auto-allow skill bins.
@@ -441,7 +442,7 @@ Status: stable.
441
442
  - Android: remove legacy bridge transport code now that nodes use the gateway protocol.
442
443
  - Android: bump okhttp + dnsjava to satisfy lint dependency checks.
443
444
  - Build: update workspace + core/plugin deps.
444
- - Build: use tsgo for dev/watch builds by default (opt out with `CLAWDBOT_TS_COMPILER=tsc`).
445
+ - Build: use tsgo for dev/watch builds by default (opt out with `OPENCLAW_TS_COMPILER=tsc`).
445
446
  - Repo: remove the Peekaboo git submodule now that the SPM release is used.
446
447
  - macOS: switch PeekabooBridge integration to the tagged Swift Package Manager release.
447
448
  - macOS: stop syncing Peekaboo in postinstall.
@@ -569,7 +570,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
569
570
  - **BREAKING:** Drop legacy `chatType: "room"` support; use `chatType: "channel"`.
570
571
  - **BREAKING:** remove legacy provider-specific target resolution fallbacks; target resolution is centralized with plugin hints + directory lookups.
571
572
  - **BREAKING:** `openclaw hooks` is now `openclaw webhooks`; hooks live under `openclaw hooks`. https://docs.openclaw.ai/cli/webhooks
572
- - **BREAKING:** `openclaw plugins install <path>` now copies into `~/.clawdbot/extensions` (use `--link` to keep path-based loading).
573
+ - **BREAKING:** `openclaw plugins install <path>` now copies into `~/.openclaw/extensions` (use `--link` to keep path-based loading).
573
574
 
574
575
  ### Changes
575
576
  - Plugins: ship bundled plugins disabled by default and allow overrides by installed versions. (#1066) — thanks @ItzR3NO.
@@ -804,7 +805,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
804
805
  - TUI: render picker overlays via the overlay stack so /models and /settings display. (#921) — thanks @grizzdank.
805
806
  - TUI: add a bright spinner + elapsed time in the status line for send/stream/run states.
806
807
  - TUI: show LLM error messages (rate limits, auth, etc.) instead of `(no output)`.
807
- - Gateway/Dev: ensure `pnpm gateway:dev` always uses the dev profile config + state (`~/.clawdbot-dev`).
808
+ - Gateway/Dev: ensure `pnpm gateway:dev` always uses the dev profile config + state (`~/.openclaw-dev`).
808
809
 
809
810
  #### Agents / Auth / Tools / Sandbox
810
811
  - Agents: make user time zone and 24-hour time explicit in the system prompt. (#859) — thanks @CashWilliams.
@@ -865,7 +866,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
865
866
 
866
867
  ### New & Improved
867
868
  - Memory: add custom OpenAI-compatible embedding endpoints; support OpenAI/local `node-llama-cpp` embeddings with per-agent overrides and provider metadata in tools/CLI. (#819) — thanks @mukhtharcm.
868
- - Memory: new `openclaw memory` CLI plus `memory_search`/`memory_get` tools with snippets + line ranges; index stored under `~/.clawdbot/memory/{agentId}.sqlite` with watch-on-by-default.
869
+ - Memory: new `openclaw memory` CLI plus `memory_search`/`memory_get` tools with snippets + line ranges; index stored under `~/.openclaw/memory/{agentId}.sqlite` with watch-on-by-default.
869
870
  - Agents: strengthen memory recall guidance; make workspace bootstrap truncation configurable (default 20k) with warnings; add default sub-agent model config.
870
871
  - Tools/Sandbox: add tool profiles + group shorthands; support tool-policy groups in `tools.sandbox.tools`; drop legacy `memory` shorthand; allow Docker bind mounts via `docker.binds`. (#790) — thanks @akonyer.
871
872
  - Tools: add provider/model-specific tool policy overrides (`tools.byProvider`) to trim tool exposure per provider.
@@ -1113,7 +1114,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
1113
1114
  - CLI UX: logs output modes (pretty/plain/JSONL) + colorized health/daemon output; global `--no-color`; lobster palette in onboarding/config.
1114
1115
  - Dev ergonomics: gateway `--dev/--reset` + dev profile auto-config; C-3PO dev templates; dev gateway/TUI helper scripts.
1115
1116
  - Sandbox/Workspace: sandbox list/recreate commands; sync skills into sandbox workspace; sandbox browser auto-start.
1116
- - Config/Onboarding: inline env vars; OpenAI API key flow to shared `~/.clawdbot/.env`; Opus 4.5 default prompt for Anthropic auth; QuickStart auto-install gateway (Node-only) + provider picker tweaks + skip-systemd flags; TUI bootstrap prompt (`tui --message`); remove Bun runtime choice.
1117
+ - Config/Onboarding: inline env vars; OpenAI API key flow to shared `~/.openclaw/.env`; Opus 4.5 default prompt for Anthropic auth; QuickStart auto-install gateway (Node-only) + provider picker tweaks + skip-systemd flags; TUI bootstrap prompt (`tui --message`); remove Bun runtime choice.
1117
1118
  - Providers: Microsoft Teams provider (polling, attachments, outbound sends, requireMention, config reload/DM policy). (#404) — thanks @onutc
1118
1119
  - Providers: WhatsApp broadcast groups for multi-agent replies (#547) — thanks @pasogott; inbound media size cap configurable (#505) — thanks @koala73; identity-based message prefixes (#578) — thanks @p6l-richard.
1119
1120
  - Providers: Telegram inline keyboard buttons + callback payload routing (#491) — thanks @azade-c; cron topic delivery targets (#474/#478) — thanks @mitschabaude-bot, @nachoiacovino; `[[audio_as_voice]]` tag support (#490) — thanks @jarvis-medmatic.
@@ -1182,7 +1183,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
1182
1183
  - **Control UI/Web:** logs tab, focus mode polish, config form resilience, streaming stability, tool output caps, windowed chat history, and reconnect/password URL auth.
1183
1184
  - **macOS/Android/TUI/Build:** macOS gateway races, QR bundling, JSON5 config safety, Voice Wake hardening; Android EXIF rotation + APK naming/versioning; TUI key handling; tooling/bundling fixes.
1184
1185
  - **Packaging/compat:** npm dist folder coverage, Node 25 qrcode-terminal import fixes, Bun/Playwright/WebSocket patches, and Docker Bun install.
1185
- - **Docs:** new FAQ/ClawdHub/config examples/showcase entries and clarified auth, sandbox, and systemd docs.
1186
+ - **Docs:** new FAQ/ClawHub/config examples/showcase entries and clarified auth, sandbox, and systemd docs.
1186
1187
 
1187
1188
  ### Maintenance
1188
1189
  - Skills additions (Himalaya email, CodexBar, 1Password).
@@ -1212,7 +1213,7 @@ Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @Nic
1212
1213
  - WhatsApp: mark offline history sync messages as read without auto-reply. (#193) — thanks @mcinteerj
1213
1214
  - Discord: avoid duplicate replies when a provider emits late streaming `text_end` events (OpenAI/GPT).
1214
1215
  - CLI: use tailnet IP for local gateway calls when bind is tailnet/auto (fixes #176).
1215
- - Env: load global `$CLAWDBOT_STATE_DIR/.env` (`~/.clawdbot/.env`) as a fallback after CWD `.env`.
1216
+ - Env: load global `$OPENCLAW_STATE_DIR/.env` (`~/.openclaw/.env`) as a fallback after CWD `.env`.
1216
1217
  - Env: optional login-shell env fallback (opt-in; imports expected keys without overriding existing env).
1217
1218
  - Agent tools: OpenAI-compatible tool JSON Schemas (fix `browser`, normalize union schemas).
1218
1219
  - Onboarding: when running from source, auto-build missing Control UI assets (`bun run ui:build`).
package/README.md CHANGED
@@ -270,26 +270,99 @@ openclaw --help # 查看帮助
270
270
 
271
271
  ## 🐳 Docker 部署指南
272
272
 
273
- ### 快速启动
273
+ ### 方式 1:一键部署脚本(推荐)
274
+
275
+ 自动完成初始化、配置远程访问、启动容器:
274
276
 
275
277
  ```bash
276
- # 基础运行
278
+ # Linux / macOS
279
+ curl -fsSL https://cdn.jsdelivr.net/gh/1186258278/OpenClawChineseTranslation@main/docker-deploy.sh | bash
280
+
281
+ # Windows PowerShell
282
+ irm https://cdn.jsdelivr.net/gh/1186258278/OpenClawChineseTranslation@main/docker-deploy.ps1 | iex
283
+ ```
284
+
285
+ ### 方式 2:快速启动(本地访问)
286
+
287
+ 适用于在本机运行并通过 `localhost` 访问:
288
+
289
+ ```bash
290
+ # 基础运行(数据不持久化)
277
291
  docker run -d \
278
292
  --name openclaw \
279
293
  -p 18789:18789 \
280
294
  ghcr.io/qingchencloud/openclaw-zh:latest
281
295
 
282
- # 带数据持久化
296
+ # 带数据持久化(推荐)
283
297
  docker run -d \
284
298
  --name openclaw \
285
299
  -p 18789:18789 \
286
- -v openclaw-data:/home/node/.openclaw \
300
+ -v openclaw-data:/root/.openclaw \
287
301
  ghcr.io/qingchencloud/openclaw-zh:latest
288
302
  ```
289
303
 
304
+ 访问:`http://localhost:18789`
305
+
306
+ ### 方式 3:服务器部署(远程访问)
307
+
308
+ 部署到服务器并从其他设备访问时,需要额外配置。
309
+
310
+ **手动配置步骤:**
311
+
312
+ ```bash
313
+ # 1. 创建数据卷
314
+ docker volume create openclaw-data
315
+
316
+ # 2. 初始化配置
317
+ docker run --rm -v openclaw-data:/root/.openclaw \
318
+ ghcr.io/qingchencloud/openclaw-zh:latest openclaw setup
319
+
320
+ # 3. 配置远程访问参数
321
+ docker run --rm -v openclaw-data:/root/.openclaw \
322
+ ghcr.io/qingchencloud/openclaw-zh:latest openclaw config set gateway.mode local
323
+
324
+ docker run --rm -v openclaw-data:/root/.openclaw \
325
+ ghcr.io/qingchencloud/openclaw-zh:latest openclaw config set gateway.bind lan
326
+
327
+ docker run --rm -v openclaw-data:/root/.openclaw \
328
+ ghcr.io/qingchencloud/openclaw-zh:latest openclaw config set gateway.controlUi.allowInsecureAuth true
329
+
330
+ # 4. 启动容器
331
+ docker run -d \
332
+ --name openclaw \
333
+ -p 18789:18789 \
334
+ -v openclaw-data:/root/.openclaw \
335
+ -e OPENCLAW_GATEWAY_TOKEN=your-secure-token \
336
+ --restart unless-stopped \
337
+ ghcr.io/qingchencloud/openclaw-zh:latest \
338
+ openclaw gateway run
339
+ ```
340
+
341
+ 访问:`http://服务器IP:18789?token=your-secure-token`
342
+
343
+ ### 远程访问注意事项
344
+
345
+ 通过 HTTP 从非 localhost 访问时,浏览器会限制某些安全功能(设备身份验证)。
346
+
347
+ | 方案 | 说明 | 适用场景 |
348
+ |------|------|----------|
349
+ | **启用 allowInsecureAuth** | 仅使用 Token 认证 | 内网/测试环境 |
350
+ | **使用 HTTPS** | Tailscale Serve 或 Nginx 反向代理 | 生产环境(推荐) |
351
+ | **SSH 端口转发** | `ssh -L 18789:127.0.0.1:18789 user@server` | 临时访问 |
352
+
290
353
  ### 使用 Docker Compose
291
354
 
292
- 创建 `docker-compose.yml`:
355
+ 项目提供了开箱即用的 `docker-compose.yml`:
356
+
357
+ ```bash
358
+ # 下载配置文件
359
+ curl -fsSL https://cdn.jsdelivr.net/gh/1186258278/OpenClawChineseTranslation@main/docker-compose.yml -o docker-compose.yml
360
+
361
+ # 启动(首次会自动初始化)
362
+ docker-compose up -d
363
+ ```
364
+
365
+ 或手动创建 `docker-compose.yml`:
293
366
 
294
367
  ```yaml
295
368
  version: '3.8'
@@ -300,21 +373,17 @@ services:
300
373
  ports:
301
374
  - "18789:18789"
302
375
  volumes:
303
- - openclaw-data:/home/node/.openclaw
376
+ - openclaw-data:/root/.openclaw
304
377
  environment:
305
- - OPENCLAW_GATEWAY_TOKEN=your-secure-token # 可选:设置访问令牌
378
+ - OPENCLAW_GATEWAY_TOKEN=your-secure-token # 设置访问令牌
306
379
  restart: unless-stopped
380
+ # 远程访问时使用以下命令(需先手动初始化配置)
381
+ # command: openclaw gateway run
307
382
 
308
383
  volumes:
309
384
  openclaw-data:
310
385
  ```
311
386
 
312
- 启动:
313
-
314
- ```bash
315
- docker-compose up -d
316
- ```
317
-
318
387
  ### 自行构建 Docker 镜像
319
388
 
320
389
  如果需要自定义或使用最新代码:
@@ -335,7 +404,7 @@ cd openclaw
335
404
  docker build -t openclaw-zh:local .
336
405
 
337
406
  # 5. 运行
338
- docker run -d --name openclaw -p 18789:18789 openclaw-zh:local
407
+ docker run -d --name openclaw -p 18789:18789 -v openclaw-data:/root/.openclaw openclaw-zh:local
339
408
  ```
340
409
 
341
410
  ### 常用 Docker 命令
@@ -355,13 +424,10 @@ docker exec -it openclaw sh
355
424
 
356
425
  # 删除容器
357
426
  docker stop openclaw && docker rm openclaw
358
- ```
359
-
360
- ### 访问 Dashboard
361
427
 
362
- 启动后访问:`http://localhost:18789`
363
-
364
- 如果设置了令牌,使用:`http://localhost:18789/?token=your-secure-token`
428
+ # 查看配置
429
+ docker run --rm -v openclaw-data:/root/.openclaw alpine cat /root/.openclaw/openclaw.json
430
+ ```
365
431
 
366
432
  ---
367
433
 
@@ -99,7 +99,7 @@ function buildDocsSection(params) {
99
99
  "Mirror: https://docs.openclaw.ai",
100
100
  "Source: https://github.com/openclaw/openclaw",
101
101
  "Community: https://discord.com/invite/clawd",
102
- "Find new skills: https://clawdhub.com",
102
+ "Find new skills: https://clawhub.com",
103
103
  "For OpenClaw behavior, commands, config, or architecture: consult local docs first.",
104
104
  "When diagnosing issues, run `openclaw status` yourself when possible; only ask the user if you lack access (e.g., sandboxed).",
105
105
  "",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026.1.29-nightly.202601301956",
3
- "commit": "6522de6ce045e0166d3136880b26004a04e44f91",
4
- "builtAt": "2026-01-30T19:57:23.641Z"
2
+ "version": "2026.1.29-nightly.202601302059",
3
+ "commit": "7c96bde3b3db74dcf57bff0138eefd5d03ba1d08",
4
+ "builtAt": "2026-01-30T21:00:23.151Z"
5
5
  }
@@ -1 +1 @@
1
- d59f24e4a21a391e6b92f94e99745f90e19490d4d659a41095bb1ddc97411f53
1
+ 9f71946c42dd48cbf433eb302e8b0824f989785de8f9750671ce2f34c097396d
@@ -32,3 +32,13 @@ export async function runCommandWithRuntime(runtime, action, onError) {
32
32
  runtime.exit(1);
33
33
  }
34
34
  }
35
+ export function resolveOptionFromCommand(command, key) {
36
+ let current = command;
37
+ while (current) {
38
+ const opts = (current.opts?.() ?? {});
39
+ if (opts[key] !== undefined)
40
+ return opts[key];
41
+ current = current.parent ?? undefined;
42
+ }
43
+ return undefined;
44
+ }
@@ -2,7 +2,7 @@ import { githubCopilotLoginCommand, modelsAliasesAddCommand, modelsAliasesListCo
2
2
  import { defaultRuntime } from "../runtime.js";
3
3
  import { formatDocsLink } from "../terminal/links.js";
4
4
  import { theme } from "../terminal/theme.js";
5
- import { runCommandWithRuntime } from "./cli-utils.js";
5
+ import { resolveOptionFromCommand, runCommandWithRuntime } from "./cli-utils.js";
6
6
  function runModelsCommand(action) {
7
7
  return runCommandWithRuntime(defaultRuntime, action);
8
8
  }
@@ -12,6 +12,7 @@ export function registerModelsCli(program) {
12
12
  .description("Model discovery, scanning, and configuration")
13
13
  .option("--status-json", "Output JSON (alias for `models status --json`)", false)
14
14
  .option("--status-plain", "Plain output (alias for `models status --plain`)", false)
15
+ .option("--agent <id>", "Agent id to inspect (overrides OPENCLAW_AGENT_DIR/PI_CODING_AGENT_DIR)")
15
16
  .addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/models", "docs.openclaw.ai/cli/models")}\n`);
16
17
  models
17
18
  .command("list")
@@ -42,7 +43,9 @@ export function registerModelsCli(program) {
42
43
  .option("--probe-timeout <ms>", "Per-probe timeout in ms")
43
44
  .option("--probe-concurrency <n>", "Concurrent probes")
44
45
  .option("--probe-max-tokens <n>", "Probe max tokens (best-effort)")
45
- .action(async (opts) => {
46
+ .option("--agent <id>", "Agent id to inspect (overrides OPENCLAW_AGENT_DIR/PI_CODING_AGENT_DIR)")
47
+ .action(async (opts, command) => {
48
+ const agent = resolveOptionFromCommand(command, "agent") ?? opts.agent;
46
49
  await runModelsCommand(async () => {
47
50
  await modelsStatusCommand({
48
51
  json: Boolean(opts.json),
@@ -54,6 +57,7 @@ export function registerModelsCli(program) {
54
57
  probeTimeout: opts.probeTimeout,
55
58
  probeConcurrency: opts.probeConcurrency,
56
59
  probeMaxTokens: opts.probeMaxTokens,
60
+ agent,
57
61
  }, defaultRuntime);
58
62
  });
59
63
  });
@@ -206,10 +210,15 @@ export function registerModelsCli(program) {
206
210
  await modelsStatusCommand({
207
211
  json: Boolean(opts?.statusJson),
208
212
  plain: Boolean(opts?.statusPlain),
213
+ agent: opts?.agent,
209
214
  }, defaultRuntime);
210
215
  });
211
216
  });
212
217
  const auth = models.command("auth").description("Manage model auth profiles");
218
+ auth.option("--agent <id>", "Agent id for auth order get/set/clear");
219
+ auth.action(() => {
220
+ auth.help();
221
+ });
213
222
  auth
214
223
  .command("add")
215
224
  .description("Interactive auth helper (setup-token or paste token)")
@@ -281,11 +290,12 @@ export function registerModelsCli(program) {
281
290
  .requiredOption("--provider <name>", "Provider id (e.g. anthropic)")
282
291
  .option("--agent <id>", "Agent id (default: configured default agent)")
283
292
  .option("--json", "Output JSON", false)
284
- .action(async (opts) => {
293
+ .action(async (opts, command) => {
294
+ const agent = resolveOptionFromCommand(command, "agent") ?? opts.agent;
285
295
  await runModelsCommand(async () => {
286
296
  await modelsAuthOrderGetCommand({
287
297
  provider: opts.provider,
288
- agent: opts.agent,
298
+ agent,
289
299
  json: Boolean(opts.json),
290
300
  }, defaultRuntime);
291
301
  });
@@ -296,11 +306,12 @@ export function registerModelsCli(program) {
296
306
  .requiredOption("--provider <name>", "Provider id (e.g. anthropic)")
297
307
  .option("--agent <id>", "Agent id (default: configured default agent)")
298
308
  .argument("<profileIds...>", "Auth profile ids (e.g. anthropic:default)")
299
- .action(async (profileIds, opts) => {
309
+ .action(async (profileIds, opts, command) => {
310
+ const agent = resolveOptionFromCommand(command, "agent") ?? opts.agent;
300
311
  await runModelsCommand(async () => {
301
312
  await modelsAuthOrderSetCommand({
302
313
  provider: opts.provider,
303
- agent: opts.agent,
314
+ agent,
304
315
  order: profileIds,
305
316
  }, defaultRuntime);
306
317
  });
@@ -310,11 +321,12 @@ export function registerModelsCli(program) {
310
321
  .description("Clear per-agent auth order override (fall back to config/round-robin)")
311
322
  .requiredOption("--provider <name>", "Provider id (e.g. anthropic)")
312
323
  .option("--agent <id>", "Agent id (default: configured default agent)")
313
- .action(async (opts) => {
324
+ .action(async (opts, command) => {
325
+ const agent = resolveOptionFromCommand(command, "agent") ?? opts.agent;
314
326
  await runModelsCommand(async () => {
315
327
  await modelsAuthOrderClearCommand({
316
328
  provider: opts.provider,
317
- agent: opts.agent,
329
+ agent,
318
330
  }, defaultRuntime);
319
331
  });
320
332
  });
@@ -7,10 +7,10 @@ import { renderTable } from "../terminal/table.js";
7
7
  import { theme } from "../terminal/theme.js";
8
8
  import { shortenHomePath } from "../utils.js";
9
9
  import { formatCliCommand } from "./command-format.js";
10
- function appendClawdHubHint(output, json) {
10
+ function appendClawHubHint(output, json) {
11
11
  if (json)
12
12
  return output;
13
- return `${output}\n\nTip: use \`npx clawdhub\` to search, install, and sync skills.`;
13
+ return `${output}\n\nTip: use \`npx clawhub\` to search, install, and sync skills.`;
14
14
  }
15
15
  function formatSkillStatus(skill) {
16
16
  if (skill.eligible)
@@ -72,7 +72,7 @@ export function formatSkillsList(report, opts) {
72
72
  const message = opts.eligible
73
73
  ? `No eligible skills found. Run \`${formatCliCommand("openclaw skills list")}\` to see all skills.`
74
74
  : "No skills found.";
75
- return appendClawdHubHint(message, opts.json);
75
+ return appendClawHubHint(message, opts.json);
76
76
  }
77
77
  const eligible = skills.filter((s) => s.eligible);
78
78
  const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
@@ -102,7 +102,7 @@ export function formatSkillsList(report, opts) {
102
102
  columns,
103
103
  rows,
104
104
  }).trimEnd());
105
- return appendClawdHubHint(lines.join("\n"), opts.json);
105
+ return appendClawHubHint(lines.join("\n"), opts.json);
106
106
  }
107
107
  /**
108
108
  * Format detailed info for a single skill
@@ -113,7 +113,7 @@ export function formatSkillInfo(report, skillName, opts) {
113
113
  if (opts.json) {
114
114
  return JSON.stringify({ error: "not found", skill: skillName }, null, 2);
115
115
  }
116
- return appendClawdHubHint(`Skill "${skillName}" not found. Run \`${formatCliCommand("openclaw skills list")}\` to see available skills.`, opts.json);
116
+ return appendClawHubHint(`Skill "${skillName}" not found. Run \`${formatCliCommand("openclaw skills list")}\` to see available skills.`, opts.json);
117
117
  }
118
118
  if (opts.json) {
119
119
  return JSON.stringify(skill, null, 2);
@@ -195,7 +195,7 @@ export function formatSkillInfo(report, skillName, opts) {
195
195
  lines.push(` ${theme.warn("→")} ${inst.label}`);
196
196
  }
197
197
  }
198
- return appendClawdHubHint(lines.join("\n"), opts.json);
198
+ return appendClawHubHint(lines.join("\n"), opts.json);
199
199
  }
200
200
  /**
201
201
  * Format a check/summary of all skills status
@@ -264,7 +264,7 @@ export function formatSkillsCheck(report, opts) {
264
264
  lines.push(` ${emoji} ${skill.name} ${theme.muted(`(${missing.join("; ")})`)}`);
265
265
  }
266
266
  }
267
- return appendClawdHubHint(lines.join("\n"), opts.json);
267
+ return appendClawHubHint(lines.join("\n"), opts.json);
268
268
  }
269
269
  /**
270
270
  * Register the skills CLI commands
@@ -2,10 +2,10 @@ import { resolveAgentDir, resolveDefaultAgentId } from "../../agents/agent-scope
2
2
  import { ensureAuthProfileStore, setAuthProfileOrder, } from "../../agents/auth-profiles.js";
3
3
  import { normalizeProviderId } from "../../agents/model-selection.js";
4
4
  import { loadConfig } from "../../config/config.js";
5
- import { normalizeAgentId } from "../../routing/session-key.js";
6
5
  import { shortenHomePath } from "../../utils.js";
6
+ import { resolveKnownAgentId } from "./shared.js";
7
7
  function resolveTargetAgent(cfg, raw) {
8
- const agentId = raw?.trim() ? normalizeAgentId(raw.trim()) : resolveDefaultAgentId(cfg);
8
+ const agentId = resolveKnownAgentId({ cfg, rawAgentId: raw }) ?? resolveDefaultAgentId(cfg);
9
9
  const agentDir = resolveAgentDir(cfg, agentId);
10
10
  return { agentId, agentDir };
11
11
  }
@@ -1,9 +1,10 @@
1
1
  import path from "node:path";
2
2
  import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
3
+ import { resolveAgentDir, resolveAgentModelFallbacksOverride, resolveAgentModelPrimary, } from "../../agents/agent-scope.js";
3
4
  import { buildAuthHealthSummary, DEFAULT_OAUTH_WARN_MS, formatRemainingShort, } from "../../agents/auth-health.js";
4
5
  import { ensureAuthProfileStore, resolveAuthStorePathForDisplay, resolveProfileUnusableUntilForDisplay, } from "../../agents/auth-profiles.js";
5
6
  import { resolveEnvApiKey } from "../../agents/model-auth.js";
6
- import { buildModelAliasIndex, parseModelRef, resolveConfiguredModelRef, resolveModelRefFromString, } from "../../agents/model-selection.js";
7
+ import { buildModelAliasIndex, parseModelRef, resolveConfiguredModelRef, resolveDefaultModelForAgent, resolveModelRefFromString, } from "../../agents/model-selection.js";
7
8
  import { CONFIG_PATH, loadConfig } from "../../config/config.js";
8
9
  import { getShellEnvAppliedKeys, shouldEnableShellEnvFallback } from "../../infra/shell-env.js";
9
10
  import { withProgressTotals } from "../../cli/progress.js";
@@ -15,24 +16,34 @@ import { shortenHomePath } from "../../utils.js";
15
16
  import { resolveProviderAuthOverview } from "./list.auth-overview.js";
16
17
  import { isRich } from "./list.format.js";
17
18
  import { describeProbeSummary, formatProbeLatency, runAuthProbes, sortProbeResults, } from "./list.probe.js";
18
- import { DEFAULT_MODEL, DEFAULT_PROVIDER, ensureFlagCompatibility } from "./shared.js";
19
+ import { DEFAULT_MODEL, DEFAULT_PROVIDER, ensureFlagCompatibility, resolveKnownAgentId, } from "./shared.js";
19
20
  export async function modelsStatusCommand(opts, runtime) {
20
21
  ensureFlagCompatibility(opts);
21
22
  if (opts.plain && opts.probe) {
22
23
  throw new Error("--probe cannot be used with --plain output.");
23
24
  }
24
25
  const cfg = loadConfig();
25
- const resolved = resolveConfiguredModelRef({
26
- cfg,
27
- defaultProvider: DEFAULT_PROVIDER,
28
- defaultModel: DEFAULT_MODEL,
29
- });
26
+ const agentId = resolveKnownAgentId({ cfg, rawAgentId: opts.agent });
27
+ const agentDir = agentId ? resolveAgentDir(cfg, agentId) : resolveOpenClawAgentDir();
28
+ const agentModelPrimary = agentId ? resolveAgentModelPrimary(cfg, agentId) : undefined;
29
+ const agentFallbacksOverride = agentId
30
+ ? resolveAgentModelFallbacksOverride(cfg, agentId)
31
+ : undefined;
32
+ const resolved = agentId
33
+ ? resolveDefaultModelForAgent({ cfg, agentId })
34
+ : resolveConfiguredModelRef({
35
+ cfg,
36
+ defaultProvider: DEFAULT_PROVIDER,
37
+ defaultModel: DEFAULT_MODEL,
38
+ });
30
39
  const modelConfig = cfg.agents?.defaults?.model;
31
40
  const imageConfig = cfg.agents?.defaults?.imageModel;
32
- const rawModel = typeof modelConfig === "string" ? modelConfig.trim() : (modelConfig?.primary?.trim() ?? "");
41
+ const rawDefaultsModel = typeof modelConfig === "string" ? modelConfig.trim() : (modelConfig?.primary?.trim() ?? "");
42
+ const rawModel = agentModelPrimary ?? rawDefaultsModel;
33
43
  const resolvedLabel = `${resolved.provider}/${resolved.model}`;
34
44
  const defaultLabel = rawModel || resolvedLabel;
35
- const fallbacks = typeof modelConfig === "object" ? (modelConfig?.fallbacks ?? []) : [];
45
+ const defaultsFallbacks = typeof modelConfig === "object" ? (modelConfig?.fallbacks ?? []) : [];
46
+ const fallbacks = agentFallbacksOverride ?? defaultsFallbacks;
36
47
  const imageModel = typeof imageConfig === "string" ? imageConfig.trim() : (imageConfig?.primary?.trim() ?? "");
37
48
  const imageFallbacks = typeof imageConfig === "object" ? (imageConfig?.fallbacks ?? []) : [];
38
49
  const aliases = Object.entries(cfg.agents?.defaults?.models ?? {}).reduce((acc, [key, entry]) => {
@@ -42,8 +53,7 @@ export async function modelsStatusCommand(opts, runtime) {
42
53
  return acc;
43
54
  }, {});
44
55
  const allowed = Object.keys(cfg.agents?.defaults?.models ?? {});
45
- const agentDir = resolveOpenClawAgentDir();
46
- const store = ensureAuthProfileStore();
56
+ const store = ensureAuthProfileStore(agentDir);
47
57
  const modelsPath = path.join(agentDir, "models.json");
48
58
  const providersFromStore = new Set(Object.values(store.profiles)
49
59
  .map((profile) => profile.provider)
@@ -208,16 +218,25 @@ export async function modelsStatusCommand(opts, runtime) {
208
218
  if (opts.json) {
209
219
  runtime.log(JSON.stringify({
210
220
  configPath: CONFIG_PATH,
221
+ ...(agentId ? { agentId } : {}),
211
222
  agentDir,
212
223
  defaultModel: defaultLabel,
213
224
  resolvedDefault: resolvedLabel,
214
225
  fallbacks,
215
226
  imageModel: imageModel || null,
216
227
  imageFallbacks,
228
+ ...(agentId
229
+ ? {
230
+ modelConfig: {
231
+ defaultSource: agentModelPrimary ? "agent" : "defaults",
232
+ fallbacksSource: agentFallbacksOverride !== undefined ? "agent" : "defaults",
233
+ },
234
+ }
235
+ : {}),
217
236
  aliases,
218
237
  allowed,
219
238
  auth: {
220
- storePath: resolveAuthStorePathForDisplay(),
239
+ storePath: resolveAuthStorePathForDisplay(agentDir),
221
240
  shellEnvFallback: {
222
241
  enabled: shellFallbackEnabled,
223
242
  appliedKeys: applied,
@@ -246,13 +265,14 @@ export async function modelsStatusCommand(opts, runtime) {
246
265
  }
247
266
  const rich = isRich(opts);
248
267
  const label = (value) => colorize(rich, theme.accent, value.padEnd(14));
268
+ const labelWithSource = (value, source) => label(source ? `${value} (${source})` : value);
249
269
  const displayDefault = rawModel && rawModel !== resolvedLabel ? `${resolvedLabel} (from ${rawModel})` : resolvedLabel;
250
270
  runtime.log(`${label("Config")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(CONFIG_PATH))}`);
251
271
  runtime.log(`${label("Agent dir")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(agentDir))}`);
252
- runtime.log(`${label("Default")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.success, displayDefault)}`);
253
- runtime.log(`${label(`Fallbacks (${fallbacks.length || 0})`)}${colorize(rich, theme.muted, ":")} ${colorize(rich, fallbacks.length ? theme.warn : theme.muted, fallbacks.length ? fallbacks.join(", ") : "-")}`);
254
- runtime.log(`${label("Image model")}${colorize(rich, theme.muted, ":")} ${colorize(rich, imageModel ? theme.accentBright : theme.muted, imageModel || "-")}`);
255
- runtime.log(`${label(`Image fallbacks (${imageFallbacks.length || 0})`)}${colorize(rich, theme.muted, ":")} ${colorize(rich, imageFallbacks.length ? theme.accentBright : theme.muted, imageFallbacks.length ? imageFallbacks.join(", ") : "-")}`);
272
+ runtime.log(`${labelWithSource("Default", agentId ? (agentModelPrimary ? "agent" : "defaults") : undefined)}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.success, displayDefault)}`);
273
+ runtime.log(`${labelWithSource(`Fallbacks (${fallbacks.length || 0})`, agentId ? (agentFallbacksOverride !== undefined ? "agent" : "defaults") : undefined)}${colorize(rich, theme.muted, ":")} ${colorize(rich, fallbacks.length ? theme.warn : theme.muted, fallbacks.length ? fallbacks.join(", ") : "-")}`);
274
+ runtime.log(`${labelWithSource("Image model", agentId ? "defaults" : undefined)}${colorize(rich, theme.muted, ":")} ${colorize(rich, imageModel ? theme.accentBright : theme.muted, imageModel || "-")}`);
275
+ runtime.log(`${labelWithSource(`Image fallbacks (${imageFallbacks.length || 0})`, agentId ? "defaults" : undefined)}${colorize(rich, theme.muted, ":")} ${colorize(rich, imageFallbacks.length ? theme.accentBright : theme.muted, imageFallbacks.length ? imageFallbacks.join(", ") : "-")}`);
256
276
  runtime.log(`${label(`Aliases (${Object.keys(aliases).length || 0})`)}${colorize(rich, theme.muted, ":")} ${colorize(rich, Object.keys(aliases).length ? theme.accent : theme.muted, Object.keys(aliases).length
257
277
  ? Object.entries(aliases)
258
278
  .map(([alias, target]) => rich
@@ -263,7 +283,7 @@ export async function modelsStatusCommand(opts, runtime) {
263
283
  runtime.log(`${label(`Configured models (${allowed.length || 0})`)}${colorize(rich, theme.muted, ":")} ${colorize(rich, allowed.length ? theme.info : theme.muted, allowed.length ? allowed.join(", ") : "all")}`);
264
284
  runtime.log("");
265
285
  runtime.log(colorize(rich, theme.heading, "Auth overview"));
266
- runtime.log(`${label("Auth store")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(resolveAuthStorePathForDisplay()))}`);
286
+ runtime.log(`${label("Auth store")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(resolveAuthStorePathForDisplay(agentDir)))}`);
267
287
  runtime.log(`${label("Shell env")}${colorize(rich, theme.muted, ":")} ${colorize(rich, shellFallbackEnabled ? theme.success : theme.muted, shellFallbackEnabled ? "on" : "off")}${applied.length ? colorize(rich, theme.muted, ` (applied: ${applied.join(", ")})`) : ""}`);
268
288
  runtime.log(`${label(`Providers w/ OAuth/tokens (${providersWithOauth.length || 0})`)}${colorize(rich, theme.muted, ":")} ${colorize(rich, providersWithOauth.length ? theme.info : theme.muted, providersWithOauth.length ? providersWithOauth.join(", ") : "-")}`);
269
289
  const formatKey = (key) => colorize(rich, theme.warn, key);
@@ -1,6 +1,9 @@
1
1
  import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../../agents/defaults.js";
2
2
  import { buildModelAliasIndex, modelKey, parseModelRef, resolveModelRefFromString, } from "../../agents/model-selection.js";
3
+ import { listAgentIds } from "../../agents/agent-scope.js";
4
+ import { formatCliCommand } from "../../cli/command-format.js";
3
5
  import { readConfigFileSnapshot, writeConfigFile, } from "../../config/config.js";
6
+ import { normalizeAgentId } from "../../routing/session-key.js";
4
7
  export const ensureFlagCompatibility = (opts) => {
5
8
  if (opts.json && opts.plain) {
6
9
  throw new Error("Choose either --json or --plain, not both.");
@@ -67,6 +70,17 @@ export function normalizeAlias(alias) {
67
70
  }
68
71
  return trimmed;
69
72
  }
73
+ export function resolveKnownAgentId(params) {
74
+ const raw = params.rawAgentId?.trim();
75
+ if (!raw)
76
+ return undefined;
77
+ const agentId = normalizeAgentId(raw);
78
+ const knownAgents = listAgentIds(params.cfg);
79
+ if (!knownAgents.includes(agentId)) {
80
+ throw new Error(`Unknown agent id "${raw}". Use "${formatCliCommand("openclaw agents list")}" to see configured agents.`);
81
+ }
82
+ return agentId;
83
+ }
70
84
  export { modelKey };
71
85
  export { DEFAULT_MODEL, DEFAULT_PROVIDER };
72
86
  /**