Home / All Skills / Workflow & Core Tools / openclaw
Workflow & Core Tools · daymade/claude-code-skills

openclaw

Manage OpenClaw (龙虾) instance configurations. Use whenever the user wants to audit, diff, copy, add-model, list, or switch models in an openclaw.json file, or when they mention lobsters, 虾, 甲虾, 乙虾, DeepSeek patch, default model, model aliases, or OpenClaw config validation.

L4 High-Privilege · Graded auth & full auditV1 Commit-PinnedExecute CommandNetwork AccessWrite FileDual-pass Audit
Author daymadeGitHub daymade/claude-code-skills ↗Stars 1392License MIT(仓库根 LICENSE 文件;GitHub API spdx MIT;Copyright (c) 2025 daymade)Commit d5c4678cb5
Control levels describe skill capabilities and suggested control measures; they do not represent quality or safety certifications, nor do they dictate usability. Usage decisions rest entirely with users and administrators. Different agent hosts apply varying constraints; do not assume hosts provide automatic protection. Third-party skill copyrights belong to their original authors. Use at your own risk.

1How It Works & Mechanism

The unified entrypoint is a pure argparse forwarding layer: cli.py uses a SUBCOMMANDS dictionary to map audit/compare/diff/copy/add-model/list/switch to each submodule's main(), where `diff` is merely an alias for `compare` with no distinct business logic.

openclaw/scripts/cli.py
SUBCOMMANDS = { "audit": audit, "compare": compare, "diff": compare, "copy": copy_provider,
What it is doing: Decoupling the "six subcommands" into six independently executable scripts, then reassembling the multi-command UX via a thin forwarder. SKILL.md also notes that each subcommand can bypass cli.py and run directly (python3 scripts/audit.py ...), facilitating on-demand calls by agents in read-only scenarios.

Configuration location employs a three-level fallback: "explicit path → nickname registry → three default paths", with the default path order hardcoded in DEFAULT_CONFIG_PATHS.

openclaw/scripts/openclaw_config.py
DEFAULT_CONFIG_PATHS = [ Path.home() / "workspace" / ".force" / "openclaw" / "openclaw.json", Path.home() / ".kimi_openclaw" / "openclaw.json", Path.home() / ".openclaw" / "openclaw.json", ]
What it is doing: Making no assumption of a single install location, it resolves the first existing file in priority order: "private workspace first, Kimi legacy path next, official path last". If none exist, it raises ConfigError and prints all three candidate paths to inform the user.

Multi-instance abstraction relies on the lobsters.json nickname registry: it first uses Path to test if the input argument is a real file, and if not, queries the registry for the nickname→path mapping.

openclaw/scripts/openclaw_config.py
registry = load_lobster_registry() if str(name_or_path) in registry: return Path(registry[str(name_or_path)])
What it is doing: Enabling natural colloquial nicknames like `--config 甲虾` or `--from 乙虾` out of the box; the trade-off is that path values inside the registry file are resolved via Path() without sanitization (see security.injection_surface).

All write operations perform an automatic backup with a retention limit: backups are written to <config_dir>/config-backups/<stem>-<UTC_timestamp>.json, and backups exceeding the 20-copy retention limit are pruned sorted by mtime.

openclaw/scripts/openclaw_config.py
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S") backup_path = backup_dir / f"{p.stem}-{ts}{p.suffix}" shutil.copy2(p, backup_path)
What it is doing: Making rollback on failure a default capability. It uses UTC timestamps to prevent timezone ambiguity and shutil.copy2 to preserve file metadata. Further down in the same file, `for old in existing[:-max_backups]: old.unlink()` handles pruning, serving as the sole mechanism against unbounded directory growth.

Modifying the default model preserves its original structure: if agents.defaults.model was originally an object, only primary is updated; if it was originally a string, it remains a string—avoiding forced normalization of the user's existing format.

openclaw/scripts/openclaw_config.py
if isinstance(current, dict): defaults["model"] = {**current, "primary": ref} else: defaults["model"] = ref
What it is doing: OpenClaw configurations permit two formats for model. Direct index access via model["primary"] throws TypeError/KeyError on string formats; this structure-adaptive behavior is a key distinction in robustness between openclaw and openclaw-model-switch.

Mutating subcommands enforce pre-change health check + abort on error + post-change recheck by default; skipped only via `--no-audit`. This constitutes its auto-audit guardrail.

openclaw/scripts/switch_model.py
if any(i["level"] == "error" for i in issues): print("Aborting due to audit errors. Use --no-audit to skip.", file=sys.stderr) return 2
What it is doing: Using audit.py as a soft pre-flight gate. As long as structural errors exist in the configuration (missing baseUrl/api, default model targeting a non-existent provider, etc.), it refuses to write, preventing cascading mutations atop an already broken configuration.

copy performs a "merge" rather than an "overwrite": it only syncs baseUrl/api and matching model definitions; target-exclusive models are not deleted.

openclaw/scripts/copy_provider.py
for key in ("baseUrl", "api"):
What it is doing: When porting a provider across instances, existing custom models and aliases on the target must survive; otherwise, a copy operation would silently discard configurations. The docstring for merge_provider explicitly states "does not remove target-only models".

Gateway restart uses a three-tier fallback: first `openclaw gateway restart`, falling back to `systemctl --user restart` on failure, and finally falling back to system-level `systemctl restart`. If all three fail, it issues a warning without raising an exception.

openclaw/scripts/openclaw_config.py
commands = [ ["openclaw", "gateway", "restart"], ["systemctl", "--user", "restart", "openclaw-gateway"], ["systemctl", "restart", "openclaw-gateway"], ]
What it is doing: Adapting across three deployment types: "CLI in PATH / user-level systemd / system-level systemd". subprocess.run is passed an argv list (no shell=True), preventing command injection via config content, though the third fallback implies the potential triggering of a system-level service restart.

Codifying hard-learned domain pitfalls into executable assertions: audit includes a DeepSeek anti-pattern heuristic that warns if a provider name starts with deepseek, directing users to the correct path: gateway provider + deepseek-v4-pro.

openclaw/scripts/audit.py
if pname.lower().startswith("deepseek"):
What it is doing: SKILL.md explains this pitfall in plain language under "Critical pitfalls", audit.py implements it as a programmatic check, and references/deepseek_patch_sop.md details it in an SOP document—forming a closed feedback loop of "documentation → validator → operation runbook".

2Core Capabilities

01Configuration audit: providers/baseUrl/api, duplicate model IDs, model entry types, default model and alias resolvability, plugins allow/entries/installs consistency
02Semantic diff between two instances: section-by-section diff of providers/models/default model/aliases/plugins; cost field skipped by default (compared only via --include-cost)
03Cross-instance provider copy and merge (supports copying specific models via --model, or porting aliases via --alias)
04add-model: import model definitions from a source config or JSON file, porting the provider along when necessary and automatically populating aliases
05list: human-readable listing / --json for jq parsing, with --validate to simultaneously verify that default models and aliases resolve properly
06switch: the sole subcommand for modifying agents.defaults.model (validates provider/model existence prior to update)
07dry-run preview: all three write commands (copy/add-model/switch) support printing changes without persisting to disk
08Multi-instance nickname resolution: Chinese nicknames defined in lobsters.json can be passed directly to --config/--from/--to

3External Dependencies

KindDependency / Endpoint
cliopenclaw CLI(gateway restart)
clisystemctl(用户级/系统级服务重启回退)
packagePython 3 标准库 only(json/os/shutil/subprocess/argparse/pathlib;无第三方依赖)
networkOpenClaw provider baseUrl(仅写在配置里被审计/搬运,skill 自身从不发请求)

4Recommended Governance & Evidence

Suggested Controls for Safe Operation
For Agent Runtime
Graded/per-use authorization, sandbox recommended
For Administrators
Approval workflow, rollback support, full audit
Evidence & Triggers (File Paths & Excerpts)
  • scripts/: Execute local scripts or commands: python3 scripts/cli.py <audit|diff|copy|add-model|list|switch> (or run individual sub-scripts directly)
  • 环境变量 / API Key: Read vendor service keys: models.providers.*.apiKey in openclaw.json: read into memory and written back alongside the entire config (the script never extracts this field explicitly); copy/
  • 本地工作目录: File read/write and artifact output: <config_dir>/config-backups/<stem>-<UTC_timestamp>.json (backed up prior to every write operation)
Audit Notes: Risk assessment: Blue, controlled local configuration utility write tier. Rationale: (1) Executes subprocesses (openclaw/systemctl to restart the gateway, with tier 3 targeting system-level services), (2) In-place overwrites user openclaw.json files and purges old backups exceeding the retention threshold, (3) Reads and ports models.providers.*.apiKey across files—yet features zero outbound network calls, no env/keychain credential harvesting, no third-party dependencies, and enforces pre-mutation backups and automated audit gates by default. Minor concerns include the `--config <arbitrary_path>` + `--no-audit` combination, apiKey being copied alongside the provider block to the target config (as noted in the SOP itself), and unhardened backup directory permissions.

5Second-Pass Verification

  • [ok] SKILL.md 声明「Backups: every write operation copies the config to config-backups/<stem>-<utc-timestamp>.json」是否与代码一致 — 三条写路径 copy_provider.py / add_model.py / switch_model.py 都在 save_config 之前调用 backup_config(config_path),且 openclaw_config.backup_config 用 datetime.now(timezone.utc) 生成时间戳、文件名格式恰为 f"{p.stem}-{ts}{p.suffix}";SKILL.md 关于「keeps the 20 most recent backups」也对得上 max_backups: int = 20 默认值与 existing[:-max_backups] 裁剪。
  • [ok] SKILL.md 声明「switch 是唯一改 agents.defaults.model 的子命令」 — grep set_default_model 的调用点只有 switch_model.py 一处;add_model.py 只写 agents.defaults.models(别名映射),copy_provider.py 只写 models.providers 与别名,compare/list/audit 纯只读,声明成立。
  • [ok] SKILL.md「Restart: write subcommands support --restart to restart the OpenClaw gateway after saving」 — 三个写脚本都定义了 --restart 并调用 restart_gateway();且未给 --restart 时会打印「NOTE: You must restart the OpenClaw gateway...」提示,行为与文档一致。副产物确认:restart_gateway 的第三档是系统级 systemctl(无 --user),文档未提及这一越权风险,已写进 verdict.risks。
  • [ok] external_deps 里是否漏掉了网络调用(有没有隐藏的 endpoint probe 或遥测) — 反向扫描 scripts/ 全部 8 文件:无 import urllib/requests/socket/httpx,无 curl/wget 字符串,无任何 URL 常量。openclaw 与 openclaw-model-switch 的关键差异(后者文档要求 curl 探针)在此得到对照确认。network 依赖项仅保留「配置里存在 baseUrl 字段」这一事实,并显式标注 skill 自身不请求。
  • [ok] 是否读 env 里的 API key / 密钥 — scripts/ 内 os.environ、getenv 零命中;openclaw_config.py 里 import os 的唯一用途是 os.path.getmtime 做备份排序。凭证面仅为「随配置整份读写的 apiKey 字段」与「copy/add-model 把 provider 块连同 apiKey 深拷贝到目标配置」,已在 security.credential_reads 如实登记而非留空。
  • [ok] 「copy 不删目标独有模型」是否为真(找反例:有没有静默覆盖整个 provider 的分支) — 反例检查通过:当目标已有该 provider 时走 merge_provider(只按 id 增补/更新、且注释明确 does not remove target-only models),不整块替换;唯一整体替换发生在「目标根本没有该 provider」时(copy.deepcopy(source_provider)),此时不存在目标独有模型可丢。--alias 分支只做 target_aliases[ref] = deepcopy(detail) 的增补,也不删。
  • [discrepancy] 备份保留逻辑会不会误删非备份文件 — 发现第一遍未记的边界:裁剪用 backup_dir.glob(f"{p.stem}-*{p.suffix}") 匹配,若用户在 config-backups/ 目录里放了同名模式的其它文件(例如手工备份 openclaw-手工.json,而 stem 恰为 openclaw),mtime 最旧的会被 unlink。属真实但低概率的删除面,已补进 verdict.risks。
  • [ok] 功能声明 vs 实际能力夸大检查(SKILL.md / README 有没有说到做不到的事) — SKILL.md 的六子命令、昵称注册表、三级默认路径、备份与 20 份上限、dry-run、restart、自动 audit 全部可在代码中一一落到实处,未发现夸大。唯一「文档比代码多说一句」的是 references/deepseek_patch_sop.md 的示例命令 `add-model gateway-provider references/deepseek_model.json`(相对路径需从 skill 根执行),属示例语境问题而非能力夸大。

6Verdict & Scenarios

  • Guardrails enabled by default on write paths: automatic pre- and post-mutation audits, immediate abort on error, pre-write backup capped at 20 copies, reducing recovery cost of a broken config to a single cp
  • Clean abstraction for multi-instance management: a single lobsters.json turns colloquial nicknames like "甲虾/乙虾" into addressable config paths, shared consistently across all six subcommands
  • Hard-won domain lessons encoded as executable assertions rather than prose: audit triggers warnings directly on "custom deepseek providers", while SKILL.md and SOP simultaneously provide the correct path (gateway provider + deepseek-v4-pro, no [1m] suffix)
  • Compact and transparent implementation: pure Python standard library, zero network access, zero third-party dependencies, and the only external process invocations pass argv lists (no shell=True), minimizing audit overhead
  • Safe preview for destructive actions: copy/add-model/switch all support --dry-run, and add-model's dry-run output even prints the subsequent switch command to run next
  • Best for: Ideal for users maintaining multiple "Lobsters" (multiple OpenClaw instances/wrappers) concurrently: needing to diff two openclaw.json files, sync a specific provider (such as DeepSeek under gateway-provider) to another instance, batch-import models and aliases into a new instance, or troubleshoot why "Lobster A works but Lobster B fails". Also well-suited for executing DeepSeek patch migrations—backed by the triad of SOP + model definition JSON + audit assertions, with dry-run previews at every step. For AI agents, the most seamless workflow is "audit → diff → copy/add-model --dry-run → execute → audit".
    Not for: Not intended for single-instance setups where the user only needs to change the default model once—openclaw-model-switch is more direct for such use cases (single command, no need to learn audit/diff/copy concepts). Not suitable for environments lacking local filesystem write permissions or where configs reside remotely/on read-only mounts (all mutations are applied in-place locally). Also not suitable when immediate proof of model execution is required: openclaw only manages config structure and optional service restarts without endpoint probing or end-to-end inference verification (which are handled by Step 2/Step 4 in openclaw-model-switch); never bypass audit gates via --no-audit to repair an already corrupted configuration.
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload openclaw.tar.gz
    sha256: c792eb95fa4dde39…
    Option B · Copy Guide for Agent
    install.json
    Agents automatically download and verify mirrors from this JSON guide.
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit d5c4678cb5.