基础工具与工作流 · 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.

风险提醒:蓝色 · 知晓即可AI 侦查报告
作者 daymadeGitHub daymade/claude-code-skills ↗Stars 1392许可 MIT(仓库根 LICENSE 文件;GitHub API spdx MIT;Copyright (c) 2025 daymade)commit d5c4678cb5
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

统一入口是个纯 argparse 转发层:cli.py 用 SUBCOMMANDS 字典把 audit/compare/diff/copy/add-model/list/switch 映射到各子模块的 main(),`diff` 只是 `compare` 的别名,没有任何自身业务逻辑。

openclaw/scripts/cli.py
SUBCOMMANDS = { "audit": audit, "compare": compare, "diff": compare, "copy": copy_provider,
注:这里在做什么:把「六个子命令」拆成六个可独立运行的脚本,再用一层薄转发把多命令体验装回来——SKILL.md 也提醒每个子命令可绕过 cli.py 直接跑(python3 scripts/audit.py ...),便于 agent 只读场景下按需调用。

配置定位是「显式路径 → 昵称注册表 → 三个默认位置」三级回退,默认位置顺序硬编码在 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", ]
注:这里在做什么:不假设单一安装位置,按「先私有工作区、再 Kimi 旧路径、再官方路径」优先取第一个存在的文件;全部不存在时抛 ConfigError 并把三个候选路径都打印出来提示用户。

多实例抽象靠 lobsters.json 昵称注册表:先用 Path 判断入参是不是真实文件,若不是再去注册表里查 nickname→path 映射。

openclaw/scripts/openclaw_config.py
registry = load_lobster_registry() if str(name_or_path) in registry: return Path(registry[str(name_or_path)])
注:这里在做什么:让 `--config 甲虾`、`--from 乙虾` 这种人类口语昵称直接可用;代价是注册表文件里的路径值被无校验地 Path() 采纳(见 security.injection_surface)。

所有写操作都自带备份,且备份有保留上限:写到 <配置目录>/config-backups/<stem>-<UTC 时间戳>.json,随后按 mtime 排序裁掉超出 20 份的旧备份。

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)
注:这里在做什么:把「改坏了怎么回滚」变成默认能力;用 UTC 时间戳避免时区歧义,用 shutil.copy2 连文件元数据一起复制。同文件下方 `for old in existing[:-max_backups]: old.unlink()` 负责裁剪,是防目录无限膨胀的唯一机制。

改默认模型时保留原有结构:agents.defaults.model 本来是对象就只改 primary,本来是字符串就写字符串——不会把用户原来的写法强行规范化。

openclaw/scripts/openclaw_config.py
if isinstance(current, dict): defaults["model"] = {**current, "primary": ref} else: defaults["model"] = ref
注:这里在做什么:OpenClaw 配置里 model 允许两种形态,直接下标 model["primary"] 会在字符串形态下抛 TypeError/KeyError;这里做形态自适应,是 openclaw 与 openclaw-model-switch 在健壮性上的关键差异。

变更类子命令默认做「改前体检 + 出 error 就中止 + 改后复检」,`--no-audit` 才跳过;这就是它所谓 auto-audit 护栏。

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
注:这里在做什么:把 audit.py 当软性事前门禁——只要配置里有结构性 error(缺 baseUrl/api、默认模型指向不存在的 provider…)就拒绝写入,避免在已经坏掉的配置上再叠一次修改。

copy 是「合并」而非「覆盖」:只同步 baseUrl/api 和同名 model 定义,目标端独有的模型不会被删掉。

openclaw/scripts/copy_provider.py
for key in ("baseUrl", "api"):
注:这里在做什么:跨实例搬运 provider 时,目标配置里自有的额外模型/别名必须幸存,否则一次 copy 就会静默丢配置;merge_provider 的 docstring 明确写「does not remove target-only models」。

重启网关用三级降级:先 `openclaw gateway restart`,失败再 `systemctl --user restart`,再退到系统级 `systemctl restart`,三档全失败只打警告不抛异常。

openclaw/scripts/openclaw_config.py
commands = [ ["openclaw", "gateway", "restart"], ["systemctl", "--user", "restart", "openclaw-gateway"], ["systemctl", "restart", "openclaw-gateway"], ]
注:这里在做什么:适配「CLI 在 PATH / 用户级 systemd / 系统级 systemd」三种安装形态;subprocess.run 传的是 argv 列表(无 shell=True),所以配置内容无法注入命令,但第三个候选意味着可能触发系统级服务重启。

把领域踩坑固化成可执行断言:audit 里有一条 DeepSeek 反模式启发式——provider 名以 deepseek 开头就告警,指向正确路径 gateway provider + deepseek-v4-pro。

openclaw/scripts/audit.py
if pname.lower().startswith("deepseek"):
注:这里在做什么:SKILL.md「Critical pitfalls」把这条经验写成人话,audit.py 把它写成代码检查,references/deepseek_patch_sop.md 写成长文 SOP,三者形成「文档→检查器→操作手册」的闭环。

2核心能力

01配置体检 audit:providers/baseUrl/api、model id 重复、模型条目类型、默认模型与别名能否解析、plugins 的 allow/entries/installs 一致性
02语义 diff 两个实例:providers/models/default model/aliases/plugins 分节报差异,cost 字段默认跳过(--include-cost 才比)
03跨实例复制 provider 并合并(可 --model 只搬指定模型、--alias 连别名一起搬)
04add-model:从源配置或 JSON 文件引入模型定义,必要时连 provider 一起拷过来,并自动补别名
05list:人读列表 / --json 给 jq,--validate 顺带校验默认模型与别名可解析
06switch:唯一改 agents.defaults.model 的子命令(改前校验 provider/model 存在)
07dry-run 预览:copy/add-model/switch 三个写命令都能只打印不落盘
08多实例昵称寻址:lobsters.json 里的中文昵称可当 --config/--from/--to 使用

3外部依赖

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

4风险提醒 风险提醒:蓝色 · 知晓即可

风险提醒:蓝色 · 知晓即可
  • apiKey 随 provider 块被跨配置搬运 — copy 与 add-model --from 用 copy.deepcopy 把源 provider 整块(含 apiKey)写进目标 openclaw.json,即密钥会落到第二个文件里;SOP 自己也提醒 'Do not write the API key into the target config unless it comes from a known-good source config via `copy` or `add-model --from`.'。skill 不管理密钥文件权限,也不提示目标文件应 chmod。
  • --config 任意路径 + --no-audit 组合可对任意合法 JSON 原地覆写 — resolve_config_path 对非昵称入参不做扩展名/存在性/结构白名单校验(直接 Path(path)),save_config 就地覆写。若 agent 被诱导把 --config 指向非 openclaw 的 JSON,写操作仍会执行(备份会先做,但备份也落在该文件的 config-backups/ 旁)。
  • 备份裁剪的 glob 可能误删同模式的非备份文件 — existing = sorted(backup_dir.glob(f"{p.stem}-*{p.suffix}"), key=os.path.getmtime),随后 existing[:-max_backups] 全部 unlink;只要目录里存在同前缀同后缀的文件(手工备份、其它工具产物),最旧的会被删掉。
  • 网关重启的第 3 档是系统级 systemctl — 重启降级链的最后一档为 ["systemctl", "restart", "openclaw-gateway"](无 --user),在部分环境可能影响整机服务或直接失败需要 root;SKILL.md 只笼统写 'restart the OpenClaw gateway',未提示这与用户级 systemd 的区别。
  • 昵称注册表是无校验的重定向表 — load_lobster_registry 把 lobsters.json 的 value 直接 Path() 使用,不校验是否存在、是否是 openclaw 配置;能写这个文件的人可让 --to 甲虾 指向任意路径。风险取决于该文件权限(skill 未检测)。
风险提醒:蓝色,本地配置工具的受控写入档。理由:①确实会执行子进程(openclaw/systemctl 重启网关,第 3 档是系统级服务),②确实会原地覆写用户的 openclaw.json 并删除超出保留上限的旧备份,③会读入并跨文件搬运 models.providers.*.apiKey——但全程无任何网络外发、无 env/keychain 凭证读取、无第三方依赖,且写操作默认有自动 audit 门禁 + 备份前置于修改。扣分项是 --config 任意路径 + --no-audit 组合、apiKey 随 provider 块被复制到目标配置(SOP 自己也提醒这一点)、备份目录权限未收紧。

5第二遍独立确认

  • [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 根执行),属示例语境问题而非能力夸大。

6结论

  • 写路径默认带护栏:变更前后自动 audit、error 即中止、写前备份且只保留 20 份,把「改坏配置」的恢复成本压到一次 cp
  • 多实例操作的抽象干净:一个 lobsters.json 就把「甲虾/乙虾」这类口语昵称变成可寻址的配置路径,六个子命令共用同一套解析
  • 把踩坑写成可执行断言而非散文:audit 里对「自建 deepseek provider」直接告警,SKILL.md 与 SOP 同步给出正确路径(gateway provider + deepseek-v4-pro、不得带 [1m])
  • 实现面小而透明:纯 Python 标准库、零网络、零第三方依赖,且唯一的外部进程调用传 argv 列表(无 shell=True),审计成本低
  • 破坏性操作可预览:copy/add-model/switch 均支持 --dry-run,且 add-model 的 dry-run 还会打印下一步该跑的 switch 命令
  • 适合:适合同时维护多只「龙虾」(多个 OpenClaw 实例/包装器)的用户:需要横向对比两份 openclaw.json 差在哪、把某个 provider(如 gateway-provider 的 DeepSeek)同步到另一台、给新实例批量加模型与别名、或排查「为什么甲虾能用乙虾不行」。也适合把 DeepSeek 补丁当作业来做的场景——有 SOP + 模型定义 JSON + audit 断言三件套兜底,且每一步都可 dry-run 预览。给 agent 用时最舒服的路径是「audit → diff → copy/add-model --dry-run → 正式执行 → audit」。
    不适合:不适合单实例、只改一次默认模型就走的场景——那种需求 openclaw-model-switch 更直接(一条命令、不需要理解 audit/diff/copy 的概念)。不适合没有本地文件系统权限、或配置存放在远端/只读挂载的环境(全部操作都是本地就地覆写)。也不适合需要「改完立刻证明模型真的能跑」的场景:openclaw 只管配置结构与可选重启,没有任何端点探针或端到端验证,那部分是 openclaw-model-switch 的 Step 2/Step 4 覆盖的;更不要用 --no-audit 跳过门禁去修一份已经坏掉的配置。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-15
    方式 A · 人下载镜像包下载 openclaw.tar.gz
    sha256: c792eb95fa4dde39…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit d5c4678cb5;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库daymade / daymade/claude-code-skills
    Stars1392
    最近推送2026-09-09
    本 skill commitd5c4678cb5
    许可MIT(仓库根 LICENSE 文件;GitHub API spdx MIT;Copyright (c) 2025 daymade)
    本站信息
    收录日期2026-09-06
    分类基础工具与工作流
    侦查报告AI 侦查 · 2 遍 · 2026-09-06
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。
    同分类邻近