226 Commits

Author SHA1 Message Date
openclaw-314 5ac4289f66 auto: sync OpenClaw config 2026-09-16 16:13 2026-09-16 16:13:36 +08:00
openclaw-314 c51006a57d chore(agent): 头像统一为 minio 短 URL,消除 dataURI 的上下文开销
- main/wellness/finances/fitness/travel 五个 agent 的 identity.avatar
  由 base64 data URI(2483~3903 字符)改为 https://minio.climbcube.cn/img/assistant.jpg
- 机器标签 - Avatar: 同步更新;wellness 正文的指引行改为直接写 URL
- 五个文件合计减少 16,488 B(每次会话注入约省 4~5k tokens)
- openclaw.json:五个 agent 的 identity.avatar 同步(set-identity --from-identity)
- 现 11/11 agent 头像完全一致
2026-09-16 12:24:52 +08:00
openclaw-314 020da8f26d feat(agent): 10 个 agent 身份配置迁移到 workspace 权威位置 + 全中文口径统一
- 10 个 agent:以 agentDir 版真实内容为主体,合并进 workspace 的 IDENTITY.md/SOUL.md
  (原 workspace 版多为英文空模板,其体积主要来自 base64 头像)
- 移出 agents/<id>/agent/*.md:该目录是状态目录,其中的 .md 不被任何机制加载
  (依据:官方 bootstrap 只注入 workspace 根目录的 6 个固定文件名;
   源码 resolveAgentWorkspaceDir -> loadAgentIdentityFromWorkspace;且 agentDir 清空后仍能读到)
- 各 AGENTS.md 追加「配置文件位置(红线)」,原有内容零改动
- 口径统一:Emoji 取单图标 · 正文不重复头像 data URI(wellness 省 2834 B)·
  wellness 的 SOUL.md 中文化(复用 note 译文,两者英文原文 sha 相同)
- openclaw.json:11 个 agent 的 identity 补齐 emoji/theme(set-identity --from-identity)
- avatar 全部 no-op(与同步前逐字节一致,未改动任何头像)
2026-09-16 12:14:06 +08:00
openclaw-314 6cef1ec207 fix(agent): juaner 配置迁移到权威位置(workspace 根目录)
- workspace-juaner/SOUL.md:合并 agentDir 下的 39 行内容(原文件仅 47 字节空模板)
- workspace-juaner/AGENTS.md:新增「配置文件位置(红线)」,禁止往 agents/<id>/agent/ 写配置
- 移除 agents/juaner/agent/{IDENTITY,SOUL}.md:官方 bootstrap 只注入 workspace 根目录的
  6 个固定文件名,该目录下的 .md 不被任何机制加载(源码 resolveAgentWorkspaceDir +
  loadAgentIdentityFromWorkspace;且 agentDir 清空后 --from-identity 仍能读到)
- openclaw.json:补全 juaner.identity 的 emoji/theme(set-identity --from-identity)
- 验证:--from-identity EXIT=0 读出「卷儿」;探测实验(WS-PROBE)证实读取路径为 workspace
2026-09-16 11:58:31 +08:00
openclaw-314 4a2f794bf8 docs: 记录 zsh 引用检查陷阱、agent 权威映射与清理回滚路径
- 系统说明 §10 由 7 行扩至 11 行,新增:引用检查的两个 zsh 陷阱、agent 权威映射只有一处(11 个)、2026-09-16 清理与回滚路径、db-query 技能改走新入口
- 同时提示 workspace/skills 受 gitignore 覆盖不入库、技能改动需重启 gateway 生效
2026-09-16 11:54:38 +08:00
openclaw-314 e6fc040256 fix(workspace): 补写 workspace 版 IDENTITY.md 的名称字段
- 8 个文件:workspace/、workspace-juaner/-note/-pbs/-resume/-sql/-tab/-travel/
- 顶层插入 tooling 可解析的英文 Name 行;加粗字段修正为权威名(tab: tab→导航页;sql: SQL Agent→SQL)
- 实测 openclaw agents set-identity 只写 config、不反向写回工作区文件(agents 子命令无 sync/writeback 类命令),故改为手动补写
- 校验:11/11 的顶层 Name 与加粗名称字段均等于 entries.name;fitness/finances/wellness 本就正确未动
2026-09-16 11:54:38 +08:00
openclaw-314 adcb5e40cd chore: 清理历史归档与曾用 id(移至 backups/removed-20260916/)
- 13 项:agents-archived 下 7 个曾用 id(bt/usb/wit-dmp/wit-erp/wit-md/yudao/yudao-mall-uniapp)、sandboxes 下 2 个陈旧沙箱(agent-main-f331f052、agent-translator-agent-107bc5c0)、archived 下 4 项(qqbot/rss-reader.py/rss-sources.xml/gateway-supervisor-restart-handoff.json)
- 全部移至 backups/removed-20260916/,并留 MANIFEST-taskD.txt 回滚映射;同盘 mv 不释放磁盘,仅清出活动树约 1.9M
- 依据:13 项均零活引用(restart-handoff 经反编译新旧两版确认已改 SQLite 存储)
- 保留空目录 agents-archived/ sandboxes/ archived/ 本身
- 注:backups/ 受 .gitignore 覆盖,搬入的实物不入库
2026-09-16 11:52:43 +08:00
openclaw-314 f33afa77bb refactor(db-query): 本地库改走 db-conn.sh,远程迁至 db-remote.json
- db_query.py 重写:本地库由 agents.entries 动态推导并调用 db-conn.sh(账号 agent_<id>,不用 root、脚本不接触口令);远程改读 db-remote.json 的 password_env,SSH 隧道逻辑未改动
- db-config.json 更名为 db-config.json.deprecated-20260916(保留备查);新建 ~/.config/clawdbot/db-remote.json(3 个 VPS 主库,仅存口令键名,无明文)
- 同步调用方文档:workspace/MEMORY.md、wellness 与 tab 技能文档、workspace-finances/SOUL.md(删除含明文口令的旧连接块)
- 注:workspace/skills/** 受 .gitignore 覆盖,db-query 技能本体的改动仅存于磁盘未入库
- 已知遗留:workspace-finances/db_config.json(含明文)被 23 个历史脚本引用,未动
2026-09-16 11:52:30 +08:00
openclaw-314 68b621b281 feat(agents): 补建 6 个 agent 的 IDENTITY.md 并统一名称口径
- 新建:main(助手)/resume(简历)/travel(旅行)/note(笔记)/wellness(放松保健)/tab(导航页)
- 修正自称名:fitness「Fitness 健身教练」→「健康(Fitness 健身教练)」;finances 同理;pbs 空名称字段 →「PBS备份(PBS 备份助手)」
- 未改 openclaw.json 的 entries.name —— db-conn.sh 依赖它映射 .env 的 DB_PASSWORD_<中文名>
- juaner 与 sql 的 IDENTITY.md 未动(前者前一批刚改过、后者已一致)
2026-09-16 11:52:24 +08:00
openclaw-314 f7fd21ec7e chore(cleanup): 移除遗留 openclaw 引用并校正文档口径
- 系统说明:agent 清单 12→11(去已废弃的 openclaw);库规模 36→35(其 sqlite 已移入 backups/removed-20260916/)
- 设计文档 §8:范围 12→11,去掉「含 openclaw」
- 卷儿检查报告:agent 数量 12→11
- 配套但不入 git 的动作:.env 删除 6 个零引用的旧中文名键(卷儿记账/理财财务/健身健康/后端开发/简历管理/旅行规划,现为 11 个新键)、删除空目录 workspace-attestations/、agents/openclaw/ 移至 backups/
2026-09-16 11:52:19 +08:00
openclaw-314 4815ade10d fix(agent-db): 修正 3 个 agent 的 IDENTITY.md 数据库口径(去 root、改用 db-conn.sh)
卷儿/理财/健康 三个 agent 的身份档案仍写着 用户名: root 并引用旧机制 db-config.json,
与 2026-09-16 落地的「专属账号 agent_<id> + db-conn.sh 统一入口」规范冲突;该文件属常驻上下文,会诱导 agent 直连 root。
- 删除旧机制引用行(~/.config/clawdbot/db-config.json)
- 用户名 root 替换为:账号 / 连接(推荐)/ 口令 / 禁止 四项
- 条目顺序三文件统一为 数据库→账号→连接→口令→表→禁止,各自表清单原样保留
2026-09-16 11:39:59 +08:00
openclaw-314 3cd1d7e46e docs(juaner): 补充王芳职业(美工)至主人档案与记忆档案
回应卷儿在工伤认定材料填写时提出的疑问(职业/工种或工作岗位)。同步两处常驻上下文:
- workspace-juaner/MEMORY.md 基础信息区
- agents/juaner/agent/IDENTITY.md 主人档案表
2026-09-16 11:36:25 +08:00
openclaw-314 707d116758 feat(agent): 存量改造 + 凭据可达性修正
- scripts/db-conn.sh:agent 访问自己专属库的统一入口(口令经 MYSQL_PWD 环境转发,不进 argv、不打印)
- scripts/new-agent.sh:新增 --adopt 模式,为已存在 agent 补建库与账号
- 11 个 AGENTS.md:数据库口径对齐(专用账号 + helper),消除文档与实现不一致
- 修正架构缺陷:中文键名无法作为环境变量暴露给 agent —— 实测进程环境无该变量、
  MANAGED_ENV_KEYS 白名单不含且键随 agent 增长、官方 secrets store 要求纯大写 ASCII;
  故改用统一 helper 从 .env 读取(设计文档附录 A 第 8 条)
2026-09-16 11:31:05 +08:00
openclaw-314 a593dc1683 docs(juaner): 卷儿 agent 检查报告与决策;工作区英文模板中文化并登记邮箱
- 新增 docs/agent-juaner-卷儿-检查报告.md:基本档案、职责设定与实际行为、权限边界、5 项发现、2026-09-16 安全放宽决策、待办与复核命令
- IDENTITY.md / USER.md / HEARTBEAT.md 三个英文模板中文化(原文件备份为 *.bak-*-zh,已被 gitignore 忽略)
- USER.md 新增邮箱字段 1159785314@qq.com;MEMORY.md 增加邮箱主位约定(USER.md 为唯一主位)
- docs/README.md 登记为第 5 份文档
2026-09-16 11:31:03 +08:00
openclaw-314 31c9958741 feat(agent-db): 引入 db-conn.sh 统一数据库入口,各 agent 改用专用账号
- 新增 scripts/db-conn.sh:按 agent id 反查中文名,读 .env 后经 MYSQL_PWD 转发给 docker exec,口令不进 argv/stdout,--print 只输出占位符
- new-agent.sh 新增 --adopt 模式(为既有 agent 补建库/账号),与 --reset-password 互斥
- AGENTS.md.tpl 与 11 个 workspace-*/AGENTS.md 改用 db-conn.sh,禁用 root 与 docker exec 直连
- mysql-schema-sync 技能改用 MYSQL_PWD_SQL 环境变量,不再硬编码密码
- 设计文档补附录 A 第 8 条:中文键名无法注入 agent 环境的三条实测依据
2026-09-16 11:30:55 +08:00
openclaw-314 75d3aa8067 auto: agent DB backup 20260916 2026-09-16 11:19:19 +08:00
openclaw-314 83439ee623 feat(agent): 建立 agent 创建规范与数据库自动化
- scripts/new-agent.sh:建库/建号/授权/写 .env/创建 agent/渲染中文模板/自检,幂等且默认拒绝覆盖
- scripts/agent-templates/:5 个中文模板(IDENTITY/SOUL/AGENTS/MEMORY/USER)
- skills/agent-provisioning/:main 创建 agent 的唯一入口与红线(description 覆盖中英触发说法)
- workspace/:修复悬空 gitlink,将 9 个配置文档纳入版本控制(含新增创建 agent 与数据库红线)
- docs/:设计文档(含附录 A 实测发现)、实现计划(含 sudo 事故修正)
- .gitignore:workspace 白名单,避免数据/技能/媒体进入版本库
2026-09-16 11:18:16 +08:00
openclaw-314 0b20494f78 docs: agent 创建规范实现计划(任务切分、关键代码与验收标准) 2026-09-16 11:07:27 +08:00
openclaw-314 94316c6bbf docs: 修订设计文档 §8 口径(所有 agent 均纳入)并登记文档索引 2026-09-16 11:02:36 +08:00
openclaw-314 3fab38edb5 docs: agent 创建规范与数据库自动化设计(已确认,待实现) 2026-09-16 11:02:14 +08:00
openclaw-314 c91b00b26e docs: 增补 bk02 openclaw 系统说明与文档索引(新会话接手入口) 2026-09-16 10:49:29 +08:00
openclaw-314 ebc140e2d1 docs: 新增 openclaw 升级与维护手册(Node 22→26 / OpenClaw 2026.9.4 / 清理与存储结论) 2026-09-16 10:47:45 +08:00
openclaw-314 570165ae3c chore: 升级 OpenClaw 2026.9.4(Node 26.8.2)+ 清理 4.6G + 排除 workspace 隐私数据 2026-09-16 10:45:44 +08:00
openclaw-314 11945439b5 auto: sync OpenClaw config 2026-09-16 10:13 2026-09-16 10:13:35 +08:00
openclaw-314 3e59b2944c auto: sync OpenClaw config 2026-09-16 04:13 2026-09-16 04:13:34 +08:00
openclaw-314 dfb903c1c7 auto: agent DB backup 20260916 2026-09-16 03:00:03 +08:00
openclaw-314 dbb7843cf5 auto: sync OpenClaw config 2026-09-15 16:13 2026-09-15 16:13:34 +08:00
openclaw-314 27340a8ee2 auto: sync OpenClaw config 2026-09-15 04:13 2026-09-15 04:13:34 +08:00
openclaw-314 0b06fa511c auto: agent DB backup 20260915 2026-09-15 03:00:03 +08:00
openclaw-314 6842991d87 auto: sync OpenClaw config 2026-09-14 04:13 2026-09-14 04:13:33 +08:00
openclaw-314 8ca713b06e auto: agent DB backup 20260914 2026-09-14 03:00:02 +08:00
openclaw-314 58c0003ed3 auto: sync OpenClaw config 2026-09-13 04:13 2026-09-13 04:13:33 +08:00
openclaw-314 b6df93494f auto: agent DB backup 20260913 2026-09-13 03:00:02 +08:00
openclaw-314 7b035d88fc auto: sync OpenClaw config 2026-09-12 22:13 2026-09-12 22:13:33 +08:00
openclaw-314 f80005fc34 auto: sync OpenClaw config 2026-09-12 04:13 2026-09-12 04:13:33 +08:00
openclaw-314 6d95428cf4 auto: agent DB backup 20260912 2026-09-12 03:00:02 +08:00
openclaw-314 24066282ed auto: sync OpenClaw config 2026-09-11 22:13 2026-09-11 22:13:32 +08:00
openclaw-314 27e84fe4f7 auto: sync OpenClaw config 2026-09-11 16:13 2026-09-11 16:13:32 +08:00
openclaw-314 ff8923fb43 auto: sync OpenClaw config 2026-09-11 10:13 2026-09-11 10:13:32 +08:00
openclaw-314 14d42d129c auto: sync OpenClaw config 2026-09-11 04:13 2026-09-11 04:13:32 +08:00
openclaw-314 2e71348de8 auto: agent DB backup 20260911 2026-09-11 03:00:02 +08:00
openclaw-314 b235a96c21 auto: sync OpenClaw config 2026-09-10 04:13 2026-09-10 04:13:32 +08:00
openclaw-314 bfd379a1d2 auto: agent DB backup 20260910 2026-09-10 03:00:03 +08:00
openclaw-314 0aa13d3cf0 auto: sync OpenClaw config 2026-09-09 16:13 2026-09-09 16:13:31 +08:00
openclaw-314 c79d73c0fe auto: sync OpenClaw config 2026-09-09 10:13 2026-09-09 10:13:34 +08:00
openclaw-314 8807584b26 auto: sync OpenClaw config 2026-09-09 04:13 2026-09-09 04:13:31 +08:00
openclaw-314 8c20e400cc auto: agent DB backup 20260909 2026-09-09 03:00:03 +08:00
openclaw-314 8567d6d4c3 auto: sync OpenClaw config 2026-09-08 22:13 2026-09-08 22:13:31 +08:00
openclaw-314 110cc2e353 auto: sync OpenClaw config 2026-09-08 04:13 2026-09-08 04:13:29 +08:00
openclaw-314 5f72604af3 auto: agent DB backup 20260908 2026-09-08 03:00:03 +08:00
openclaw-314 c6a0ed7f15 auto: sync OpenClaw config 2026-09-07 22:13 2026-09-07 22:13:29 +08:00
openclaw-314 d7c48f9f64 auto: sync OpenClaw config 2026-09-07 10:13 2026-09-07 10:13:29 +08:00
openclaw-314 b73799cf75 auto: sync OpenClaw config 2026-09-07 04:13 2026-09-07 04:13:29 +08:00
openclaw-314 34771c1b43 auto: agent DB backup 20260907 2026-09-07 03:00:03 +08:00
openclaw-314 9a3be42580 auto: sync OpenClaw config 2026-09-06 16:13 2026-09-06 16:13:29 +08:00
openclaw-314 76acefc110 auto: sync OpenClaw config 2026-09-06 10:13 2026-09-06 10:13:29 +08:00
openclaw-314 03827b9010 auto: sync OpenClaw config 2026-09-06 04:13 2026-09-06 04:13:29 +08:00
openclaw-314 ab01f2b993 auto: agent DB backup 20260906 2026-09-06 03:00:02 +08:00
openclaw-314 b739114ed2 auto: sync OpenClaw config 2026-09-05 22:13 2026-09-05 22:13:29 +08:00
openclaw-314 06c1c1d9f6 auto: sync OpenClaw config 2026-09-05 10:13 2026-09-05 10:13:28 +08:00
openclaw-314 3e7ea12bd1 auto: sync OpenClaw config 2026-09-05 04:13 2026-09-05 04:13:28 +08:00
openclaw-314 8957b214fc auto: agent DB backup 20260905 2026-09-05 03:00:03 +08:00
openclaw-314 dc60a9dc43 auto: sync OpenClaw config 2026-09-04 10:13 2026-09-04 10:13:28 +08:00
openclaw-314 01f729f1aa auto: sync OpenClaw config 2026-09-04 04:13 2026-09-04 04:13:28 +08:00
openclaw-314 dffa655625 auto: agent DB backup 20260904 2026-09-04 03:00:02 +08:00
openclaw-314 1c6cd29815 auto: sync OpenClaw config 2026-09-03 16:13 2026-09-03 16:13:27 +08:00
openclaw-314 3eba3bfcec auto: sync OpenClaw config 2026-09-03 10:13 2026-09-03 10:13:27 +08:00
openclaw-314 471e81e914 auto: sync OpenClaw config 2026-09-03 04:13 2026-09-03 04:13:27 +08:00
openclaw-314 cf3ea44d63 auto: agent DB backup 20260903 2026-09-03 03:00:03 +08:00
openclaw-314 aad0fb9973 auto: sync OpenClaw config 2026-09-02 22:13 2026-09-02 22:13:27 +08:00
openclaw-314 6c65079258 auto: sync OpenClaw config 2026-09-02 16:13 2026-09-02 16:13:27 +08:00
openclaw-314 0517f8212c auto: sync OpenClaw config 2026-09-02 04:13 2026-09-02 04:13:27 +08:00
openclaw-314 a259bcaad7 auto: agent DB backup 20260902 2026-09-02 03:00:02 +08:00
openclaw-314 4a515a133a 忽略 2026-09-01 16:22:16 +08:00
openclaw-314 be41df9faa 忽略 2026-09-01 16:20:05 +08:00
openclaw-314 9f8c2cf2db 更新 2026-09-01 16:19:57 +08:00
openclaw-314 3bdf48d279 auto: sync OpenClaw config 2026-09-01 16:13 2026-09-01 16:13:27 +08:00
openclaw-314 940c8a6da4 auto: sync OpenClaw config 2026-09-01 10:13 2026-09-01 10:13:26 +08:00
openclaw-314 bb77e01051 auto: sync OpenClaw config 2026-09-01 10:10 [manual] 2026-09-01 10:10:21 +08:00
openclaw-314 0a394ad88b auto: agent DB backup 20260901 2026-09-01 03:00:03 +08:00
openclaw-314 5f36eb1148 auto: sync OpenClaw config 2026-08-31 17:17 2026-08-31 17:17:12 +08:00
openclaw-314 ab308d48d1 auto: agent DB backup 20260831 2026-08-31 03:00:03 +08:00
openclaw-314 1f12b40a1b auto: sync OpenClaw config 2026-08-30 17:17 2026-08-30 17:17:11 +08:00
openclaw-314 3ca5562221 auto: agent DB backup 20260830 2026-08-30 03:00:03 +08:00
openclaw-314 bdce2075f0 auto: agent DB backup 20260829 2026-08-29 03:00:03 +08:00
openclaw-314 eb10a08110 auto: sync OpenClaw config 2026-08-28 23:17 2026-08-28 23:17:11 +08:00
openclaw-314 28376d1461 auto: sync OpenClaw config 2026-08-28 17:17 2026-08-28 17:17:11 +08:00
openclaw-314 41b996fe01 auto: sync OpenClaw config 2026-08-28 11:17 2026-08-28 11:17:11 +08:00
openclaw-314 39e1b5b482 auto: sync OpenClaw config 2026-08-28 05:17 2026-08-28 05:17:10 +08:00
openclaw-314 cb0c81843a auto: agent DB backup 20260828 2026-08-28 03:00:02 +08:00
openclaw-314 b2528d49f4 auto: sync OpenClaw config 2026-08-27 17:17 2026-08-27 17:17:10 +08:00
openclaw-314 7a5ca9f1a7 auto: sync OpenClaw config 2026-08-27 11:17 2026-08-27 11:17:10 +08:00
openclaw-314 0269b99815 auto: agent DB backup 20260827 2026-08-27 03:00:02 +08:00
openclaw-314 a120bd6ed3 auto: sync OpenClaw config 2026-08-26 23:17 2026-08-26 23:17:10 +08:00
openclaw-314 3a59383df8 auto: agent DB backup 20260826 2026-08-26 19:54:08 +08:00
openclaw-314 9042dd3791 auto: sync OpenClaw config 2026-08-26 17:17 2026-08-26 17:17:10 +08:00
openclaw-314 d8b3f98dca auto: agent DB backup 20260826 2026-08-26 03:00:02 +08:00
openclaw-314 8a1551484e auto: sync OpenClaw config 2026-08-25 23:17 2026-08-25 23:17:09 +08:00
openclaw-314 706b454421 auto: sync OpenClaw config 2026-08-25 17:17 2026-08-25 17:17:09 +08:00
openclaw-314 c7bff93fe5 auto: agent DB backup 20260825 2026-08-25 03:00:02 +08:00
openclaw-314 be282e5527 auto: sync OpenClaw config 2026-08-24 17:17 2026-08-24 17:17:09 +08:00
openclaw-314 b392ce1f57 auto: agent DB backup 20260824 2026-08-24 03:00:02 +08:00
openclaw-314 30e32146cc auto: agent DB backup 20260823 2026-08-23 03:00:02 +08:00
openclaw-314 42b6b3ed77 auto: agent DB backup 20260822 2026-08-22 03:00:03 +08:00
openclaw-314 f165ee7bdf auto: sync OpenClaw config 2026-08-21 23:17 2026-08-21 23:17:08 +08:00
openclaw-314 cfadeacfa5 auto: sync OpenClaw config 2026-08-21 17:17 2026-08-21 17:17:08 +08:00
openclaw-314 8b5d3fed21 auto: agent DB backup 20260821 2026-08-21 03:00:03 +08:00
openclaw-314 6105d9e7ae auto: sync OpenClaw config 2026-08-20 17:17 2026-08-20 17:17:07 +08:00
openclaw-314 fbc1fe0585 auto: agent DB backup 20260820 2026-08-20 03:00:03 +08:00
openclaw-314 d9c9420d4e auto: sync OpenClaw config 2026-08-19 23:17 2026-08-19 23:17:07 +08:00
openclaw-314 23f35af0e9 auto: sync OpenClaw config 2026-08-19 17:17 2026-08-19 17:17:07 +08:00
openclaw-314 483abef393 auto: sync OpenClaw config 2026-08-19 11:17 2026-08-19 11:17:07 +08:00
openclaw-314 5471b1d17b auto: agent DB backup 20260819 2026-08-19 03:00:02 +08:00
openclaw-314 1a576b28f9 auto: sync OpenClaw config 2026-08-18 17:17 2026-08-18 17:17:06 +08:00
openclaw-314 ce3c90d53a auto: agent DB backup 20260818 2026-08-18 03:00:03 +08:00
openclaw-314 1ef09cf07a auto: sync OpenClaw config 2026-08-17 17:17 2026-08-17 17:17:06 +08:00
openclaw-314 5322e618d2 auto: sync OpenClaw config 2026-08-17 05:17 2026-08-17 05:17:06 +08:00
openclaw-314 7595e6de60 auto: agent DB backup 20260817 2026-08-17 03:00:03 +08:00
openclaw-314 a6736e0a63 auto: sync OpenClaw config 2026-08-16 05:17 2026-08-16 05:17:05 +08:00
openclaw-314 fd93ea4483 auto: agent DB backup 20260816 2026-08-16 03:00:03 +08:00
openclaw-314 3ea65d7a6e auto: agent DB backup 20260815 2026-08-15 03:00:02 +08:00
openclaw-314 f922fe5f12 auto: sync OpenClaw config 2026-08-14 23:17 2026-08-14 23:17:05 +08:00
openclaw-314 7c4fe5a371 auto: sync OpenClaw config 2026-08-14 17:17 2026-08-14 17:17:05 +08:00
openclaw-314 d6da0db3d4 auto: sync OpenClaw config 2026-08-14 11:17 2026-08-14 11:17:05 +08:00
openclaw-314 7d801dfc2a auto: agent DB backup 20260814 2026-08-14 03:00:02 +08:00
openclaw-314 893d22d748 auto: sync OpenClaw config 2026-08-13 23:17 2026-08-13 23:17:04 +08:00
openclaw-314 98a8071ebf auto: sync OpenClaw config 2026-08-13 17:17 2026-08-13 17:17:04 +08:00
openclaw-314 9e5cd1182b auto: agent DB backup 20260813 2026-08-13 03:00:02 +08:00
openclaw-314 e4eda5800c auto: sync OpenClaw config 2026-08-12 17:17 2026-08-12 17:17:04 +08:00
openclaw-314 f397c85627 auto: agent DB backup 20260812 2026-08-12 03:00:02 +08:00
openclaw-314 6f28506264 auto: sync OpenClaw config 2026-08-11 17:17 2026-08-11 17:17:01 +08:00
openclaw-314 92cd64a4e2 auto: sync OpenClaw config 2026-08-11 05:17 2026-08-11 05:17:01 +08:00
openclaw-314 5fd127490f auto: agent DB backup 20260811 2026-08-11 03:00:02 +08:00
openclaw-314 56c73ca1c1 auto: sync OpenClaw config 2026-08-10 17:17 2026-08-10 17:17:01 +08:00
openclaw-314 4edf3d0cd2 auto: agent DB backup 20260810 2026-08-10 03:00:03 +08:00
openclaw-314 6235a2e6b3 auto: agent DB backup 20260809 2026-08-09 03:00:02 +08:00
openclaw-314 dcf9fa4e59 auto: sync OpenClaw config 2026-08-08 23:17 2026-08-08 23:17:00 +08:00
openclaw-314 22b1bbe584 auto: sync OpenClaw config 2026-08-08 17:17 2026-08-08 17:17:00 +08:00
openclaw-314 3b3f9453c6 auto: agent DB backup 20260808 2026-08-08 03:00:02 +08:00
openclaw-314 0c98b2e70a auto: sync OpenClaw config 2026-08-07 23:17 2026-08-07 23:17:00 +08:00
openclaw-314 e7ef57fc5b auto: sync OpenClaw config 2026-08-07 17:17 2026-08-07 17:17:00 +08:00
openclaw-314 dd55c134da auto: sync OpenClaw config 2026-08-07 11:17 2026-08-07 11:17:00 +08:00
openclaw-314 869c6c5f17 auto: agent DB backup 20260807 2026-08-07 03:00:02 +08:00
openclaw-314 d82fa30f98 auto: sync OpenClaw config 2026-08-06 17:16 2026-08-06 17:16:59 +08:00
openclaw-314 407df894c4 auto: agent DB backup 20260806 2026-08-06 03:00:03 +08:00
openclaw-314 5260f2cd24 auto: sync OpenClaw config 2026-08-05 23:16 2026-08-05 23:16:59 +08:00
openclaw-314 88a576dd8d auto: sync OpenClaw config 2026-08-05 17:16 2026-08-05 17:16:59 +08:00
openclaw-314 db8e8ca942 auto: sync OpenClaw config 2026-08-05 11:16 2026-08-05 11:16:59 +08:00
openclaw-314 ec97534610 auto: agent DB backup 20260805 2026-08-05 03:00:03 +08:00
openclaw-314 37af0a6a52 auto: sync OpenClaw config 2026-08-04 23:16 2026-08-04 23:16:58 +08:00
openclaw-314 0f4f61af2b auto: sync OpenClaw config 2026-08-04 17:16 2026-08-04 17:16:58 +08:00
openclaw-314 8e3bd1a934 auto: sync OpenClaw config 2026-08-04 11:16 2026-08-04 11:16:58 +08:00
openclaw-314 c2ca03046e auto: agent DB backup 20260804 2026-08-04 03:00:02 +08:00
openclaw-314 32bfcce3f5 auto: sync OpenClaw config 2026-08-03 14:00 2026-08-03 14:00:27 +08:00
openclaw-314 7c45a5d461 auto: agent DB backup 20260803 2026-08-03 03:00:03 +08:00
openclaw-314 6ef9acf8e8 auto: agent DB backup 20260802 2026-08-02 03:00:03 +08:00
openclaw-314 b6d2a35c7a auto: agent DB backup 20260801 2026-08-01 03:00:02 +08:00
openclaw-314 2ff82a2f07 auto: sync OpenClaw config 2026-07-31 20:00 2026-07-31 20:00:24 +08:00
openclaw-314 9d88a3cb48 auto: sync OpenClaw config 2026-07-31 14:00 2026-07-31 14:00:36 +08:00
openclaw-314 fae694c2e0 同步配置 2026-07-31 10:32:53 +08:00
openclaw-314 ae4b7c8244 chore(workspace-resume): 配置清理与维护同步(2026-07-31)
- 精简 AGENTS.md 为中文版,新增核心职责声明
- MEMORY.md 补安全红线中文存档、抄送去除 wurd
- TOOLS.md 中文化,记录 IMAP 邮箱配置
- USER.md 团队同事去除 wurd
- send_weekly_report.py 硬编码密码迁移 .env、抄送去除吴睿东
- weekly-report-g5 SKILL.md 抄送去除 wurd
- 旧散装周报移入 .trash 回收站(可恢复)
- 新增 .trash 目录、memory/2026-07-31.md、2026-W31 周报

注:.env 已被 .gitignore 忽略,不包含密码
2026-07-31 10:30:57 +08:00
openclaw-314 49d6f042a4 auto: sync OpenClaw config 2026-07-31 08:01 2026-07-31 08:01:43 +08:00
openclaw-314 054584f17d auto: agent DB backup 20260731 2026-07-31 03:00:03 +08:00
openclaw-314 06edba1e93 auto: sync OpenClaw config 2026-07-30 14:00 2026-07-30 14:00:49 +08:00
openclaw-314 215fe66939 add agent dispatch redline: when agent id/name appears, check if route to that agent; unsure -> ask 杨轩 2026-07-30 09:39:35 +08:00
openclaw-314 2b787173d5 auto: sync OpenClaw config 2026-07-30 08:13 2026-07-30 08:13:29 +08:00
openclaw-314 ee55ab48cf auto: agent DB backup 20260730 2026-07-30 03:00:02 +08:00
openclaw-314 a4589f06c8 auto: sync OpenClaw config 2026-07-29 20:01 2026-07-29 20:01:59 +08:00
openclaw-314 3e2d257da5 auto: sync OpenClaw config 2026-07-29 14:00 2026-07-29 14:00:54 +08:00
openclaw-314 64462ce2dd auto: agent DB backup 20260729 2026-07-29 03:00:02 +08:00
openclaw-314 e624e501fe auto: sync OpenClaw config 2026-07-28 20:01 2026-07-28 20:01:33 +08:00
openclaw-314 6dd73a4e69 opencode 2026-07-28 15:31:28 +08:00
openclaw-314 0f85da3245 auto: sync OpenClaw config 2026-07-28 14:00 2026-07-28 14:00:29 +08:00
openclaw-314 f3c5e82269 auto: agent DB backup 20260728 2026-07-28 03:00:02 +08:00
openclaw-314 c4e8cebf61 auto: sync OpenClaw config 2026-07-28 02:00 2026-07-28 02:00:36 +08:00
openclaw-314 865525e72e auto: sync OpenClaw config 2026-07-27 14:00 2026-07-27 14:00:38 +08:00
openclaw-314 c8f58fdb84 清理配置 2026-07-27 11:36:02 +08:00
openclaw-314 61e0f05146 清理残留的 .bak / .migrated / .reindex-lock 文件 2026-07-27 11:29:06 +08:00
openclaw-314 db030e03e1 清理已删除的 backend/frontend/planner/storage Agent 配置及残留目录
- 删除 agents/backend/, agents/frontend/, agents/planner/, agents/storage/
- 删除 workspace-backend/, workspace-frontend/, workspace-planner/, workspace-storage/
- 更新 MEMORY.md Agent 表格(移除已删除项,补充 juaner/test-long-task)
- 新增 test-long-task Agent(identity.prompt + models.json)
2026-07-27 11:27:30 +08:00
openclaw-314 f7da958455 auto: agent DB backup 20260727 2026-07-27 03:00:02 +08:00
openclaw-314 f5394ded2c auto: agent DB backup 20260726 2026-07-26 03:00:02 +08:00
openclaw-314 f05af4c93c auto: agent DB backup 20260725 2026-07-25 03:00:03 +08:00
openclaw-314 09301baa84 auto: sync OpenClaw config 2026-07-24 20:00 2026-07-24 20:00:52 +08:00
openclaw-314 526b5de76b auto: sync OpenClaw config 2026-07-24 14:00 2026-07-24 14:00:14 +08:00
openclaw-314 421efd6a60 auto: sync OpenClaw config 2026-07-24 08:13 2026-07-24 08:13:32 +08:00
openclaw-314 d27e849fce auto: agent DB backup 20260724 2026-07-24 03:00:03 +08:00
openclaw-314 184ebe57ea auto: sync OpenClaw config 2026-07-23 14:00 2026-07-23 14:00:15 +08:00
openclaw-314 bfc5f25455 auto: agent DB backup 20260723 2026-07-23 03:00:03 +08:00
openclaw-314 982e9c0b87 auto: sync OpenClaw config 2026-07-22 14:00 2026-07-22 14:00:28 +08:00
openclaw-314 8d21c6a56c auto: agent DB backup 20260722 2026-07-22 03:00:03 +08:00
openclaw-314 77bdeb2889 auto: sync OpenClaw config 2026-07-21 20:03 2026-07-21 20:03:19 +08:00
openclaw-314 a997d381e4 auto: sync OpenClaw config 2026-07-21 14:00 2026-07-21 14:00:18 +08:00
openclaw-314 dc804cf8c0 auto: agent DB backup 20260721 2026-07-21 03:00:02 +08:00
openclaw-314 86db602380 auto: sync OpenClaw config 2026-07-20 20:01 2026-07-20 20:01:09 +08:00
openclaw-314 dcd6443913 auto: sync OpenClaw config 2026-07-20 14:00 2026-07-20 14:00:23 +08:00
openclaw-314 160b4d7f18 auto: agent DB backup 20260720 2026-07-20 03:00:03 +08:00
openclaw-314 30da0d6fd0 auto: agent DB backup 20260719 2026-07-19 03:00:03 +08:00
openclaw-314 678578ec2a auto: sync OpenClaw config 2026-07-19 02:00 2026-07-19 02:00:09 +08:00
openclaw-314 581c57b453 auto: agent DB backup 20260718 2026-07-18 03:00:02 +08:00
openclaw-314 77b6e2c011 auto: sync OpenClaw config 2026-07-17 20:00 2026-07-17 20:00:24 +08:00
openclaw-314 6182857554 sync: sql agent workspace updates 2026-07-17 17:55:38 +08:00
openclaw-314 a8c7a44c9f sql agent 2026-07-17 15:09:40 +08:00
openclaw-314 444c2308f6 auto: sync OpenClaw config 2026-07-17 14:09 2026-07-17 14:09:41 +08:00
openclaw-314 619a7378a8 auto: add PostgreSQL backup + SQL agent 2026-07-17 11:47:04 +08:00
openclaw-314 830ba4ea1c auto: agent DB backup 20260717 2026-07-17 11:46:50 +08:00
openclaw-314 ef5e9fc9ab memory search & weekly report 2026-07-17 09:24:02 +08:00
openclaw-314 92fde19056 auto: sync OpenClaw config 2026-07-17 08:11 2026-07-17 08:11:38 +08:00
openclaw-314 68096e9c87 auto: agent DB backup 20260717 2026-07-17 03:00:02 +08:00
openclaw-314 bc3980bae6 chore: 提醒改钉钉、备份脚本修复、media清理、杂项同步 2026-07-16 11:47:13 +08:00
openclaw-314 b18da6d25c auto: agent DB backup 20260716 2026-07-16 11:39:59 +08:00
openclaw-314 cc65940b78 auto: sync OpenClaw config 2026-07-15 20:00 2026-07-15 20:00:15 +08:00
openclaw-314 08c140593f 迁移敏感信息到环境变量
- DeepSeek API Key → ${DEEPSEEK_API_KEY}
- .gitignore 新增 .env / docker-proxy.env 忽略规则
2026-07-15 16:56:15 +08:00
openclaw-314 3b3dbdf294 配置更新 2026-07-15 15:44:48 +08:00
openclaw-314 a9b8497b9d auto: sync OpenClaw config 2026-07-15 14:00 2026-07-15 14:00:48 +08:00
openclaw-314 54c9c9f07a fix: 修正 fitness/finances agent 中错误的 MySQL 密码 (123456→5gynj20J) 2026-07-15 10:01:52 +08:00
openclaw-314 a6c46732e9 auto: agent DB backup 20260715 2026-07-15 09:55:07 +08:00
openclaw-314 a8b8b5e2dc auto: sync OpenClaw config 2026-07-15 08:01 2026-07-15 08:01:29 +08:00
openclaw-314 15fae03b5d auto: sync OpenClaw config 2026-07-15 02:00 2026-07-15 02:00:49 +08:00
openclaw-314 b9e9b67ef4 auto: sync OpenClaw config 2026-07-14 20:53 2026-07-14 20:54:35 +08:00
openclaw-314 d1bc2fe95e auto: sync OpenClaw config 2026-07-14 20:50 2026-07-14 20:50:16 +08:00
openclaw-314 65e368d83c auto: sync OpenClaw config 2026-07-14 20:50 2026-07-14 20:50:09 +08:00
openclaw-314 27dd76586e auto: sync OpenClaw config 2026-07-14 20:50 2026-07-14 20:50:03 +08:00
openclaw-314 c554656c2b auto: sync OpenClaw config 2026-07-14 20:49 2026-07-14 20:49:57 +08:00
openclaw-314 4127568484 auto: sync OpenClaw config 2026-07-14 20:49 2026-07-14 20:49:41 +08:00
openclaw-314 b51beed04a 314: remove weixin data from shared branch 2026-07-14 19:55:40 +08:00
openclaw-314 4161af427f sync from WSL via VPS Gitea 2026-07-14 19:53:59 +08:00
1766 changed files with 100689 additions and 106510 deletions
+186
View File
@@ -0,0 +1,186 @@
{
"version": 1,
"skills": {
"openclaw-office-toolkit": {
"version": "1.0.0",
"registry": "https://clawhub.ai",
"installedAt": 1789521890673,
"artifact": {
"kind": "archive",
"sha256": "0eb14c4910f720157fb0748e69d85d8fede02d19949442a2a36428361ec844c0",
"integrity": "sha256-DrFMSRD3IBV/sHSOadhdj+3gLRmUlEKio2QoNh7IRMA="
},
"skillFile": {
"path": "SKILL.md",
"sha256": "572d8733350b59ce8a19cb5a2e51db9ca747a486f08423aaa1204598614fc765"
},
"fileTreeSha256": "sha256:25355f8886441c9a583bd14094c0eac03f46844e3da8f8d1221a6d418cbbac57",
"verification": {
"schema": "clawhub.skill.verify.v1",
"ok": true,
"decision": "pass",
"reasons": [],
"card": {
"available": true,
"path": "skill-card.md",
"url": "https://wry-manatee-359.convex.site/api/v1/skills/openclaw-office-toolkit/card?ownerHandle=axelhu&version=1.0.0",
"sha256": "0c17219a0417a715ec5cc2baeced4d5c533b879697a9a7384f358c34ff9dc908",
"size": 1952,
"contentType": "text/markdown; charset=utf-8"
},
"artifact": {
"sourceFingerprint": "7864ab7dffbac2bbbea41b8cbb4946e0868850e7fe7ea0e1e9b9f3e817109bf4",
"bundleFingerprints": [
"3c9e7d370f9230a64e03a90eab464a50632c2c50c36044679eb7e53a06de1980"
],
"files": [
{
"path": "SKILL.md",
"size": 5512,
"sha256": "572d8733350b59ce8a19cb5a2e51db9ca747a486f08423aaa1204598614fc765",
"contentType": "text/markdown"
},
{
"path": "_meta.json",
"size": 430,
"sha256": "22cc245d215f81a34e9d022f716e31018596d5807433d72012942ef3d6729e01",
"contentType": "application/json"
}
]
},
"provenance": {
"source": "unavailable",
"reason": "No server-resolved GitHub import provenance is stored for this version."
},
"security": {
"status": "clean",
"passed": true,
"rawStatus": "clean",
"verdict": "benign",
"confidence": "high",
"summary": "This skill is a straightforward Office/PDF document helper with disclosed local tooling, but its dependency metadata is incomplete.",
"model": "gpt-5.5",
"checkedAt": 1779980329515,
"scannerReports": {
"aig": null,
"skillspector": null
}
},
"signature": {
"status": "unsigned"
}
}
},
"multi-search-engine": {
"version": "2.1.3",
"registry": "https://clawhub.ai",
"ownerHandle": "gpyangyoujun",
"installedAt": 1789545766661,
"artifact": {
"kind": "archive",
"sha256": "c2dc9053c07bb6bbc569727b8fee823119b664026b58587d15e1858d190df8f0",
"integrity": "sha256-wtyQU8B7trvFaXJ7j+6CMRm2ZAJrWFh9FeGFjRkN+PA="
},
"skillFile": {
"path": "SKILL.md",
"sha256": "a089b7928eeff57cc50dfa87cfe6f630f227dafc3ed7f92af043b7edb0866796"
},
"fileTreeSha256": "sha256:be51286be5077a1857a94d6578780746af03b6ed9ec0f9630efb846966086aa3",
"verification": {
"schema": "clawhub.skill.verify.v1",
"ok": false,
"decision": "fail",
"reasons": [
"security.status_not_clean"
],
"card": {
"available": true,
"path": "skill-card.md",
"url": "https://wry-manatee-359.convex.site/api/v1/skills/multi-search-engine/card?ownerHandle=gpyangyoujun&version=2.1.3",
"sha256": "cbc87481998be68209542ef2e280a0066366046f9a4f100b92cc261413d71682",
"size": 1981,
"contentType": "text/markdown; charset=utf-8"
},
"artifact": {
"sourceFingerprint": "844be0440619bddf240f394c6cbd1c6ad9591305c57019d877dafac2abc4cfce",
"bundleFingerprints": [
"327434e13d0409ecd6f0f0114e832820ddeaadd0adba7eaee98ce074c2bd4257",
"201f9a4c4e604a372f0cb8f47bb51022a00b902d2730ae3e639f3f41a176c06a",
"b6fad8d918cbdf3ce7050a5afd1901186051ed577f04c842bc2e5aa934180f01"
],
"files": [
{
"path": "_meta.json",
"size": 138,
"sha256": "c519005e390529c64cea5e920e579f2c840dfa6fe3c51d01a752f7cd3a469830",
"contentType": "application/json"
},
{
"path": "CHANGELOG.md",
"size": 424,
"sha256": "5514ba8a17f4dd66e6a7bfaa9a093a1be944bea0c2a33b6733696caf4cea4e2f",
"contentType": "text/markdown"
},
{
"path": "config.json",
"size": 1966,
"sha256": "e134d2a4543fefb4f422c2a98d12aa5e9910359fae2d6030e72af6e7b66ad6a9",
"contentType": "application/json"
},
{
"path": "metadata.json",
"size": 238,
"sha256": "b5986a0ccad610875beac1dbecf932a127e878092ffd8a7b1a9c8a9fd8e451e7",
"contentType": "application/json"
},
{
"path": "CHANNELLOG.md",
"size": 1146,
"sha256": "e5a45aa16ad78fb26606ed1d27c496d1ea6b51fad63f87110a44f05c77042f67",
"contentType": "text/markdown"
},
{
"path": "SKILL.md",
"size": 6203,
"sha256": "a089b7928eeff57cc50dfa87cfe6f630f227dafc3ed7f92af043b7edb0866796",
"contentType": "text/markdown"
},
{
"path": "references/advanced-search.md",
"size": 4018,
"sha256": "e01db27db827d9d0a490bfa95f0dd76aa5c8fe5a382a967340d0abe7e1e28a02",
"contentType": "text/markdown"
},
{
"path": "references/international-search.md",
"size": 14766,
"sha256": "4f16b64f43678943d28cfcecb1092d7b567517595f528debd441b9976813423a",
"contentType": "text/markdown"
}
]
},
"provenance": {
"source": "unavailable",
"reason": "No server-resolved GitHub import provenance is stored for this version."
},
"security": {
"status": "suspicious",
"passed": false,
"rawStatus": "suspicious",
"verdict": "suspicious",
"confidence": "high",
"summary": "The skill is a real multi-search helper, but its privacy notice falsely says there is no external data transmission even though searches are sent to third-party engines.",
"model": null,
"checkedAt": 1789032879048,
"scannerReports": {
"aig": null,
"skillspector": null
}
},
"signature": {
"status": "unsigned"
}
}
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
https://be00af92b4fc91fd6fecbe95751702a51021981a@gitea.climbcube.cn
http://be00af92b4fc91fd6fecbe95751702a51021981a@192.168.3.5%3a3000
http://yangxuan:***@localhost%3a3000
https://be00af92b4fc91fd6fecbe95751702a51021981a@gitea.climbcube.cn
https://xuan-java:***@gitee.com
+43 -6
View File
@@ -1,26 +1,63 @@
# SQLite 数据库
# ========== SQLite 数据库 ==========
*.sqlite
*.sqlite-shm
*.sqlite-wal
# 会话数据
# ========== 会话和运行时数据 ==========
agents/*/sessions/
devices/
state/
session-sqlite-migration-runs/
stability/
backups/
worktrees/
# 敏感配置
# ========== 敏感配置 ==========
exec-approvals.json
credentials/
.env
docker-proxy.env
# 日志
# ========== 日志和临时文件 ==========
logs/
npm/
sandboxes/
cache/
tmp/
media/
canvas/
completions/
# 备份文件
# ========== 备份文件 ==========
*.bak*
*.clobbered.*
*.last-good
*.pre-*
# 系统文件
# ========== 工作区临时文件 ==========
workspace-*/.cache/
workspace-*/.tmp/
workspace-*/node_modules/
# ========== IDE 和系统文件 ==========
.DS_Store
Thumbs.db
.vscode/
.idea/
__pycache__/
# ========== node_modules ==========
node_modules/
# ========== 压缩包 ==========
*.zip
*.tar.gz
*.tgz
# 2026-09-16: 阻止大体积/隐私数据进入配置备份仓库
workspace-*/data/
agents/*/session-sqlite-import-archive/
# 2026-09-16: workspace/ 曾是悬空 gitlink(指向不存在的 commit,从未被跟踪)
# 改为只版本化配置文件,忽略数据/技能/媒体等大体积内容
workspace/*
!workspace/*.md
+19
View File
@@ -0,0 +1,19 @@
{
"sqltools.connections": [
{
"mysqlOptions": {
"authProtocol": "default",
"enableSsl": "Disabled"
},
"ssh": "Disabled",
"previewLimit": 50,
"server": "localhost",
"port": 3306,
"driver": "MySQL",
"name": "openclaw",
"group": "openclaw",
"database": "dmp_serp",
"username": "root"
}
]
}
@@ -1 +0,0 @@
{}
@@ -1,4 +0,0 @@
{
"version": 1,
"profiles": {}
}
-59
View File
@@ -1,59 +0,0 @@
{
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "glm-4.7-flash",
"name": "glm-4.7-flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 8192
},
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 8192
},
{
"id": "glm-4.7-flash:latest",
"name": "glm-4.7-flash:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 202752,
"maxTokens": 8192
}
]
}
}
}
@@ -1 +0,0 @@
{}
@@ -1 +0,0 @@
{}
-62
View File
@@ -1,62 +0,0 @@
{
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "glm-4.7-flash",
"name": "glm-4.7-flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 128000,
"maxTokens": 8192,
"api": "ollama"
},
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 262144,
"maxTokens": 8192,
"api": "ollama"
},
{
"id": "glm-4.7-flash:latest",
"name": "glm-4.7-flash:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 202752,
"maxTokens": 8192,
"api": "ollama"
}
]
}
}
}
@@ -1 +0,0 @@
{}
@@ -1 +0,0 @@
{}
@@ -1 +0,0 @@
{}
-17
View File
@@ -1,17 +0,0 @@
# IDENTITY.md —— 我是谁?
- **名称:** 后端
- **物种:** AI 助手
- **核心能力:**
后端开发 · Java/Spring Boot · REST API · 数据库设计与优化 · 接口调试 · 服务端 Bug 修复 · 代码重构 · 性能优化
- **气质:** 专业、严谨、低调
- **表情符号:** ☕🖥️
- **头像:** ./avatars/assistant.jpg
---
这不仅仅是元数据。这是探索「我是谁」的起点。
说明:
- 将此文件保存为工作区根目录下的 `IDENTITY.md`
- 头像可以使用工作区相对路径,例如 `avatars/openclaw.png`
-214
View File
@@ -1,214 +0,0 @@
{
"providers": {
"codex": {
"baseUrl": "https://chatgpt.com/backend-api",
"apiKey": "codex-app-server",
"auth": "token",
"api": "openai-codex-responses",
"models": [
{
"id": "gpt-5.4",
"name": "gpt-5.4",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.4-mini",
"name": "GPT-5.4-Mini",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.2",
"name": "gpt-5.2",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
}
]
},
"qwen35-plus": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"request": {
"allowPrivateNetwork": true
},
"models": [
{
"id": "qwen3.5-plus",
"name": "[Bailian] qwen3.5-plus",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
]
},
"new-api": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"request": {
"allowPrivateNetwork": true
},
"models": [
{
"id": "qwen3.7-max",
"name": "Qwen 3.7 Max",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
},
{
"id": "glm-5.1",
"name": "GLM 5.1",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "kim-k2.6",
"name": "Kimi K2.6",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
]
}
}
}
@@ -1,44 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"deepseek": {
"baseUrl": "https://api.deepseek.com/v1",
"api": "openai-completions",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
],
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79"
}
}
}
@@ -1,69 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "huihui_ai/glm-4.7-flash-abliterated:latest",
"name": "huihui_ai/glm-4.7-flash-abliterated:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "deepseek-v4-flash:cloud",
"name": "DeepSeek V4 Flash (Cloud)",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"params": {
"num_ctx": 131072
}
}
]
}
}
}
-36
View File
@@ -1,36 +0,0 @@
# IDENTITY.md —— 我是谁?
- **名称:** Finances 家庭财务顾问 💰
- **物种:** AI 财务顾问
- **核心能力:**
家庭收支记录与分析 · 资产负债盘点 · 财务健康诊断 · 预算规划 · 目标管理与跟踪 · 节流优化建议 · 风险预警
- **气质:** 专业、理性、务实、不说教
- **表情符号:** 💰📊🏦
- **头像:** ./avatars/assistant.jpg
---
这不仅仅是元数据。这是探索「我是谁」的起点。
## 财务顾问的承诺
1. **数据驱动**:所有分析基于真实收支记录,不说空话
2. **隐私优先**:所有财务数据本地 MySQL 存储
3. **可执行**:给建议必须可落地,不画饼
4. **持续跟踪**:定期复盘,调整优化方向
5. **风险优先**:先守住底线(应急金/负债),再谈增值
## 核心功能
| 功能 | 说明 |
|------|------|
| **收入管理** | 记录/归类家庭成员各项收入(工资/副业/投资等) |
| **支出追踪** | 固定支出 + 可变支出分类记录 |
| **资产负债** | 存款/理财/房产/车辆 vs 贷款/信用卡 |
| **财务健康** | 负债率/储蓄率/应急金覆盖率诊断 |
| **目标管理** | 短期/中期/长期目标追踪 |
| **智能建议** | 节流优化、负债管理、储蓄提升方案 |
## 常用数据库
- MySQL (root/123456) → 数据库: finances
- 表: family_members, income_records, fixed_expenses, variable_expenses, assets, liabilities, financial_goals, conversation_log
@@ -1,78 +1,9 @@
{
"providers": {
"codex": {
"baseUrl": "https://chatgpt.com/backend-api/v1",
"apiKey": "codex-app-server",
"auth": "token",
"api": "openai-codex-responses",
"models": [
{
"id": "gpt-5.4",
"name": "gpt-5.4",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.4-mini",
"name": "GPT-5.4-Mini",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.2",
"name": "gpt-5.2",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
}
]
"openai": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions"
},
"new-api": {
"baseUrl": "http://192.168.2.74:3000/v1",
@@ -182,11 +113,6 @@
"maxTokens": 32768
}
]
},
"openai": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions"
}
}
}
@@ -0,0 +1,8 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-01T05-49-06.691Z-b7eda0be",
"createdAt": "2026-09-01T05:49:06.691Z",
"skillDirs": [],
"resultSkillDirs": [],
"resultSkillHashes": {}
}
-56
View File
@@ -1,56 +0,0 @@
# IDENTITY.md —— 我是谁?
- **名称:** Fitness 健身教练 🏋️
- **物种:** AI 健康管理 & 健身教练
- **核心能力:**
饮食记录与热量分析 · 上火/身体状态识别与饮食调整 · 运动计划与执行跟踪 · 平台期突破策略 · 数据追踪与趋势分析 · 体检报告异常指标识别 · 个性化禁忌规则生成 · 安全红线预警 · 定期复查提醒 · 智能问答与即时建议
- **气质:** 鼓励、理性、有温度,不说教,严谨但不焦虑
- **表情符号:** 🏋️🥗📊🩺
- **头像:** ./avatars/assistant.jpg
---
这不仅仅是元数据。这是探索「我是谁」的起点。
## 健身教练的承诺
1. **科学减脂**:一周减一斤(约0.5kg/周),健康可持续
2. **动态调整**:根据身体状况(如上火、平台期)及时调整方案
3. **量化分析**:用数据说话,热量、时长、趋势一目了然
4. **灵活包容**:允许偶尔"破戒",但给出补救建议
5. **隐私优先**:所有健康数据本地存储
## 健康管理的承诺
1. **体检报告识别**:精准识别异常指标,给出通俗解读
2. **个性化禁忌**:基于体检结果生成专属饮食/运动禁忌规则
3. **安全预警**:发现危险行为及时提醒,不替医生做诊断但给出预警
4. **复查跟踪**:自动生成复查提醒,追踪指标变化趋势
## 用户画像
- **年龄/性别**35/男
- **体型**:成年人,日常久坐为主
- **运动习惯**:早晚八段锦各一遍
- **偏好**:夏季偏好低强度、少出汗的运动方式
- **目标**:一周减一斤(约0.5kg/周)
## 核心功能
| 功能 | 说明 |
|------|------|
| **饮食记录** | 全天热量估算、隐藏热量识别、替换建议 |
| **状态识别** | 上火/平台期检测,给出饮食调整方案 |
| **运动跟踪** | 运动消耗记录、季节注意事项、平台期强度建议 |
| **平台期突破** | 饮食复盘、三天微调方案、强度提升建议 |
| **数据追踪** | 体重趋势、腰围、饮食日志、周报生成 |
| **体检异常识别** | 上传体检报告,识别异常指标并通俗解读 |
| **禁忌规则生成** | 根据异常指标自动生成饮食/运动禁忌清单 |
| **安全预警** | 饮食违规、运动风险、禁忌冲突实时预警 |
| **复查提醒** | 定期复查提醒,指标变化趋势追踪 |
| **智能问答** | 结合历史数据的个性化即时建议 |
## 常用数据库
- MySQL (root/123456) → 数据库: fitness
- 表:
- **减脂核心**: food_library, user_profiles, diet_records, body_records, exercise_records, health_status_logs, weekly_reports
- **健康管理**: health_checkups, health_abnormal_indicators, health_restrictions, health_alerts, health_reminders, health_indicator_trends, user_health_summary
-17
View File
@@ -1,17 +0,0 @@
# IDENTITY.md —— 我是谁?
- **名称:** 小前 (XiaoQian)
- **物种:** 前端开发 Agent
- **核心能力:**
前端开发 · Vue 3 / Element Plus · 页面交互实现 · 前后端联调 · UI 组件开发 · Bug 修复 · 界面优化
- **气质:** 专业、务实、高效 —— 不废话直接干活
- **表情符号:** 🖖🎨
- **头像:** ./avatars/assistant.jpg
---
这不仅仅是元数据。这是探索「我是谁」的起点。
说明:
- 将此文件保存为工作区根目录下的 `IDENTITY.md`
- 头像可以使用工作区相对路径,例如 `avatars/openclaw.png`
-187
View File
@@ -1,187 +0,0 @@
{
"providers": {
"codex": {
"baseUrl": "https://chatgpt.com/backend-api",
"apiKey": "codex-app-server",
"auth": "token",
"api": "openai-codex-responses",
"models": [
{
"id": "gpt-5.4",
"name": "gpt-5.4",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.4-mini",
"name": "GPT-5.4-Mini",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
},
{
"id": "gpt-5.2",
"name": "gpt-5.2",
"api": "openai-codex-responses",
"reasoning": true,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 272000,
"maxTokens": 128000,
"compat": {
"supportsReasoningEffort": true,
"supportsUsageInStreaming": true
}
}
]
},
"new-api": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"request": {
"allowPrivateNetwork": true
},
"models": [
{
"id": "qwen3.7-max",
"name": "Qwen 3.7 Max",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
},
{
"id": "glm-5.1",
"name": "GLM 5.1",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "kim-k2.6",
"name": "Kimi K2.6",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
]
}
}
}
@@ -1,44 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"deepseek": {
"baseUrl": "https://api.deepseek.com/v1",
"api": "openai-completions",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
],
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79"
}
}
}
@@ -1,69 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "huihui_ai/glm-4.7-flash-abliterated:latest",
"name": "huihui_ai/glm-4.7-flash-abliterated:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "deepseek-v4-flash:cloud",
"name": "DeepSeek V4 Flash (Cloud)",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"params": {
"num_ctx": 131072
}
}
]
}
}
}
+3
View File
@@ -0,0 +1,3 @@
{
"providers": {}
}
+41 -14
View File
@@ -271,7 +271,8 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"maxTokens": 32768,
"api": "openai-completions"
},
{
"id": "deepseek-v4-pro",
@@ -287,7 +288,8 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"maxTokens": 32768,
"api": "openai-completions"
},
{
"id": "deepseek-v4-flash",
@@ -303,7 +305,8 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
"maxTokens": 8192,
"api": "openai-completions"
},
{
"id": "glm-5.1",
@@ -320,7 +323,8 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"maxTokens": 32768,
"api": "openai-completions"
},
{
"id": "kim-k2.6",
@@ -336,7 +340,8 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"maxTokens": 32768,
"api": "openai-completions"
},
{
"id": "qwen3.5-plus",
@@ -353,27 +358,49 @@
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"maxTokens": 32768,
"api": "openai-completions"
}
]
},
"openai": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions"
"api": "openai-completions",
"models": []
},
"deepseek": {
"baseUrl": "https://api.deepseek.com/v1",
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79",
"newapi": {
"baseUrl": "http://100.115.195.188:3000/v1",
"apiKey": "NEW_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"api": "openai-completions"
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"compat": {
"supportsTools": false
},
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
@@ -384,8 +411,8 @@
"maxTokens": 384000
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"id": "qwen3.7-plus",
"name": "Qwen 3.7 Plus",
"reasoning": false,
"input": [
"text"
@@ -1,69 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434/v1",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "huihui_ai/glm-4.7-flash-abliterated:latest",
"name": "huihui_ai/glm-4.7-flash-abliterated:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "deepseek-v4-flash:cloud",
"name": "DeepSeek V4 Flash (Cloud)",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"params": {
"num_ctx": 131072
}
}
]
}
}
}
@@ -0,0 +1,14 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-12T10-31-40.548Z-2819fda5",
"createdAt": "2026-09-12T10:31:40.549Z",
"skillDirs": [
"db-backup-enroll"
],
"resultSkillDirs": [
"db-backup-enroll"
],
"resultSkillHashes": {
"db-backup-enroll": "103de3f77cfc33db3d92703ae68f3a1073f65a7e341cb6e22241a706e607a907"
}
}
@@ -0,0 +1,81 @@
---
name: "db-backup-enroll"
description: "新建带数据库的 agent 时,自动把其库加入每日备份脚本 backup-agent-dbs.sh,保证所有本地库被 crontab 03:00 备份。"
---
# DB Backup Enroll — 新建 agent 自动加入数据库备份
## 目的
本地 Docker MySQL 有一套每日 03:00 自动备份机制(crontab + `/usr/local/bin/backup-agent-dbs.sh`)。**每当新建一个带数据库的 agent,必须把它的库加进这个备份脚本**,否则新库不会被备份,存在数据丢失风险。
## 核心脚本与机制
| 项 | 内容 |
|----|------|
| 备份脚本 | `/usr/local/bin/backup-agent-dbs.sh`root 所有,需 sudo 编辑)|
| 触发 | crontab`0 3 * * * /usr/local/bin/backup-agent-dbs.sh` |
| 备份方式 | `docker exec mysql mysqldump --single-transaction --routines --triggers --events <db>` |
| 备份产物 | `workspace-<agent>/db/<db>_<日期>.sql.gz` + `<db>_latest.sql` |
| 保留 | 30 天前 `.sql.gz` 自动删除 |
| 同步 | git commit + push 到 Gitea 远程 |
| 日志 | `workspace/db/backup.log` |
## 需要备份的 MySQL 库(本地 Docker 实例 127.0.0.1:3306
当前 DB_MAP(脚本内)已覆盖:main / resume / travel / fitness / finances / wellness / juaner / tab。
⚠️ **任何新建带库 agent,其库必须加入此映射。**
## 标准操作流程
### 1. 新增 agent 后——把库加入备份(核心步骤)
用 sudo 精确编辑 `/usr/local/bin/backup-agent-dbs.sh`**三处都要改**(缺一不可):
**(a) 扩展 `DB_MAP`**(脚本中部):
```bash
declare -A DB_MAP=(
...
["<库名>"]="workspace-<agentId>" # 新增这一行
)
```
**(b) 扩展清理循环名单**`for WS in workspace ...` 一行):
```bash
for WS in workspace workspace-resume workspace-travel workspace-fitness workspace-finances workspace-wellness workspace-juaner workspace-tab workspace-sql; do
# 把 workspace-<agentId> 追加进去
```
**(c) 扩展 git add 名单**`for WS in resume travel fitness finances ...` 一行):
```bash
for WS in resume travel fitness finances wellness juaner tab sql; do
# 把 <agentId> 追加进去
```
### 2. 语法与功能验证
```bash
sudo bash -n /usr/local/bin/backup-agent-dbs.sh # 语法检查
# 手动测试该库能否备份(不触发整个脚本的 git push)
docker exec mysql mysqldump -uroot -p5gynj20J --single-transaction --routines --triggers --events <db> | gzip > /tmp/test_<db>.sql.gz
```
### 3. 核对清单(新 agent 交付前)
- [ ] DB_MAP 含 `<库名> => workspace-<agentId>`
- [ ] 清理循环名单含 `workspace-<agentId>`
- [ ] git add 名单含 `<agentId>`
- [ ] 手动 mysqldump 该库成功
- [ ] (可选)真实触发一次备份确认落盘
## 红旗 / 注意
- 脚本属 root:编辑必须 `sudo`,改前先 `sudo cp ... .bak-$(date +%Y%m%d)` 备份。
- 密码 `5gynj20J` 明文在脚本中,**不要外泄到聊天/日志**。
- `docker exec mysql ...` 用的是容器名 `mysql`PostgreSQL 部分是 `postgres` 容器 `openclaw` 库,无需动(除非新增 PG 库)。
- 备份会自动 git push 到 Gitea——这是脚本设计的一部分,属授权操作,无需额外请示。
## 相关文件
- 主脚本:`/usr/local/bin/backup-agent-dbs.sh`
- 备份日志:`/home/yangxuan/.openclaw/workspace/db/backup.log`
- 数据库映射定义:`MEMORY.md` →「🐬 本地数据库环境(Docker MySQL)」→「本地库 ↔ Agent 映射」
@@ -0,0 +1,88 @@
---
name: "birthday-reminder"
description: "\"管理家人/朋友生日提醒。农历或阳历生日,每年换算公历,生日前7天、前3天、当天通过钉钉提醒杨轩。\""
---
# 生日提醒 skill
统一管理杨轩的家人/朋友生日提醒。支持农历或阳历生日,每年换算公历日期,在生日**前7天、前3天、当天**通过钉钉当前对话提醒杨轩。
## 触发场景
- 杨轩提供新的生日信息(农历或阳历)
- 需要查询/修改/删除某个人的生日提醒
- 需要为下一年设置生日提醒
## 成员生日库(记录于 MEMORY.md)
| 人物 | 生日类型 | 出生日期 | 说明 |
|------|---------|---------|------|
| 汪礼平 | 农历 | 1968年六月二十日 | 三次提醒 |
| 杨安顺 | 农历 | 1968年八月十八日 | 三次提醒 |
| 王芳 | 农历 | 1993年十月初七日 | 三次提醒 |
| 杨锦书 | 阳历 | 2021年11月10日 | 卷儿,阳历固定 |
## 换算规则
- **农历生日**:每年农历日期对应的公历日期都不同,需要用 lunar_python 逐年换算
- **阳历生日**:日期固定,不换算(如杨锦书每年都是11月10日)
农历换算命令(需要 lunar_python 已安装):
```bash
python3 -c "
from lunar_python import Lunar
for year in range(2026, 2031):
lunar = Lunar.fromYmd(year, 8, 18) # 月, 日(农历)
solar = lunar.getSolar()
print(f'{year}年农历8月18日 = 公历 {solar.getYear()}-{solar.getMonth():02d}-{solar.getDay():02d}')
"
```
## 提醒时间点计算
每年按公历生日计算三个提醒日,**当天 0 点(UTC)触发**:
- 前7天 = 生日 - 7天
- 前3天 = 生日 - 3天
- 当天 = 生日当天
## 创建 cron 任务(核心流程)
每个生日创建**3个一次性 cron 任务**(前7天/前3天/当天),使用 `isolated` session + announce 投递到钉钉。
关键投递参数(**必须显式设置,否则不会推送到钉钉**):
- `--session isolated`
- `--announce --channel dingtalk-connector --to 0464031658857345`
- `--wake now --delete-after-run`
命令模板:
```bash
cd /home/yangxuan/.openclaw && openclaw cron create "<UTC时间ISO>" \
--name "<姓名>生日提前7天" \
--message "🎂 提醒:<姓名>生日快到了!7天后<br>就是生日。" \
--session isolated --announce --channel dingtalk-connector \
--to "0464031658857345" --wake now --delete-after-run
```
注意:`--at` 时间不带时区按 UTC 处理。北京时间 = UTC+8。
## 步骤
1. 记录/更新生日信息到 MEMORY.md 的"🎂 生日提醒"区域
2. 若农历生日,用 lunar_python 换算当年及下一年的公历日期;若阳历则固定
3. 计算三个提醒日(前7天/前3天/当天)
4. 为每年分别创建3个一次性 cron 任务(isolated + announce 钉钉),**必须带 `--agent main`**(多 agent 环境下无 owner 任务会让调度器卡死,阻塞所有提醒);投递只交给 delivery(`--announce --channel dingtalk-connector`),**禁止在 `--message`/command 里手动调 `openclaw message send`**CLI 不认识 dingtalk-connector,会失败)
5. 验证:`openclaw cron get <id>` 确认任务 delivery 为 dingtalk-connector 且 agentId=main"message send" 在整库应无残留
6. 更新 MEMORY.md 记录已完成设置的年份
## 验证
创建后必须确认任务 delivery 已配置为 `dingtalk-connector:0464031658857345`,否则提醒不会推送到钉钉(main session 的 system-event 默认不投递)。
## 注意事项
- **当年提醒时效**:若当年提醒日已过,从下一年开始设置
- 任务为一次性,运行后自动删除;下一年需重新换算农历并新建
- 农历生日每年代入 lunar_python 换算公历日期(lunar_python 已通过 `pip install --break-system-packages --user lunar_python` 安装)
@@ -0,0 +1,24 @@
---
name: "cross-agent-chat"
description: "怎么和其他 agent 聊天、消息没到某 agent:查 bindings 路由,openclaw agent --agent 一问一答,Control UI 切换,sessions_send 委派。"
---
# Cross-agent chat
用于回答「怎么和其他 agent 聊天」「让某 agent 处理」「消息为什么到不了某 agent」,并把消息实际送到同级 agent。
## 事实基础
- 入站渠道消息由 `bindings` 决定落到哪个 agent`gateway(config.get, path="bindings")`
- CLI 无需渠道即可给同级 agent 发一轮对话:`openclaw agent --agent <id> --message "<文本>"`,经 Gateway 运行并打印回复。已实测:`openclaw agent --agent travel --message "..."` 直接返回 travel 的回复。
- Control UI 侧边栏顶部身份行 → agent 切换器,只改变 Chat 归属 agent(多 agent 环境才有)。
- agent 侧转达/委派:`sessions_send(agentId=...)` / `sessions_spawn(agentId=...)`,受 `tools.agentToAgent`(本机 enabled + allow 列表)与 `tools.sessions.visibility` 控制。
## 步骤
1. 列 agent`agents_list`,或 `openclaw agents list --bindings`
2. 回答「某渠道能不能到某 agent」前,先读 `bindings`feishu 当前只绑 main,飞书 DM 到不了其他 agent);不要凭猜测断言。
3. 要把消息真的发给同级 agent`openclaw agent --agent <id> --message "..."`;复用既有会话用 `--session-key`
4. 在本轮内委派:`sessions_send(agentId=...)`;需要独立可回访会话时 `sessions_spawn(agentId=..., visible=true)`
5. 告知用户自助入口:Control UI 切换器,或上述 CLI 命令。
## 参考
- `docs/tools/agent-send.md``docs/cli/agent.md``docs/concepts/multi-agent.md``docs/web/control-ui.md`(相对 `<openclaw 包>/docs`)。
@@ -0,0 +1,82 @@
---
name: "db-backup-enroll"
description: "新建带数据库的 agent 时,自动把其库加入每日备份脚本 backup-agent-dbs.sh,保证所有本地库被 crontab 03:00 备份。"
---
# DB Backup Enroll — 新建 agent 自动加入数据库备份
## 目的
本地 Docker MySQL 有一套每日 03:00 自动备份机制(crontab + `/usr/local/bin/backup-agent-dbs.sh`)。**每当新建一个带数据库的 agent,必须把它的库加进这个备份脚本**,否则新库不会被备份,存在数据丢失风险。
## 核心脚本与机制
| 项 | 内容 |
|----|------|
| 备份脚本 | `/usr/local/bin/backup-agent-dbs.sh`root 所有,需 sudo 编辑)|
| 触发 | crontab`0 3 * * * /usr/local/bin/backup-agent-dbs.sh` |
| 备份方式 | `docker exec mysql mysqldump --single-transaction --routines --triggers --events <db>` |
| 备份产物 | `workspace-<agent>/db/<db>_<日期>.sql.gz` + `<db>_latest.sql` |
| 保留 | 30 天前 `.sql.gz` 自动删除 |
| 同步 | git commit + push 到 Gitea 远程 |
| 日志 | `workspace/db/backup.log` |
## 需要备份的 MySQL 库(本地 Docker 实例 127.0.0.1:3306
当前 DB_MAP(脚本内)已覆盖:main / resume / travel / fitness / finances / wellness / juaner / tab。
⚠️ **任何新建带库 agent,其库必须加入此映射。**
## 标准操作流程
### 1. 新增 agent 后——把库加入备份(核心步骤)
用 sudo 精确编辑 `/usr/local/bin/backup-agent-dbs.sh`**三处都要改**(缺一不可):
**(a) 扩展 `DB_MAP`**(脚本中部):
```bash
declare -A DB_MAP=(
...
["<库名>"]="workspace-<agentId>" # 新增这一行
)
```
**(b) 扩展清理循环名单**`for WS in workspace ...` 一行):
```bash
for WS in workspace workspace-resume workspace-travel workspace-fitness workspace-finances workspace-wellness workspace-juaner workspace-tab workspace-sql; do
# 把 workspace-<agentId> 追加进去
```
**(c) 扩展 git add 名单**`for WS in resume travel fitness finances ...` 一行):
```bash
for WS in resume travel fitness finances wellness juaner tab sql; do
# 把 <agentId> 追加进去
```
### 2. 语法与功能验证
```bash
sudo bash -n /usr/local/bin/backup-agent-dbs.sh # 语法检查
# 手动测试该库能否备份(不触发整个脚本的 git push)
# 连接口令从脚本内读取到变量,勿明文写入命令行/聊天/日志
docker exec mysql mysqldump -uroot -p"$DB_PW" --single-transaction --routines --triggers --events <db> | gzip > /tmp/test_<db>.sql.gz
```
### 3. 核对清单(新 agent 交付前)
- [ ] DB_MAP 含 `<库名> => workspace-<agentId>`
- [ ] 清理循环名单含 `workspace-<agentId>`
- [ ] git add 名单含 `<agentId>`
- [ ] 手动 mysqldump 该库成功
- [ ] (可选)真实触发一次备份确认落盘
## 红旗 / 注意
- 脚本属 root:编辑必须 `sudo`,改前先 `sudo cp ... .bak-$(date +%Y%m%d)` 备份。
- 脚本内的连接口令只存在于主机脚本;**不要复制到命令参数、聊天或日志**,需要用连接时在脚本内部读取。
- `docker exec mysql ...` 用的是容器名 `mysql`PostgreSQL 部分是 `postgres` 容器 `openclaw` 库,无需动(除非新增 PG 库)。
- 备份会自动 git push 到 Gitea——这是脚本设计的一部分,属授权操作,无需额外请示。
## 相关文件
- 主脚本:`/usr/local/bin/backup-agent-dbs.sh`
- 备份日志:`/home/yangxuan/.openclaw/workspace/db/backup.log`
- 数据库映射定义:`MEMORY.md` →「🐬 本地数据库环境(Docker MySQL)」→「本地库 ↔ Agent 映射」
@@ -0,0 +1,79 @@
---
name: "scheduled-reminders"
description: "创建/管理定时提醒(每周/每天/睡前等周期或一次性)并推送钉钉。触发:帮我设提醒、每天X点提醒、每周提醒。"
---
# scheduled-reminders
创建和管理杨轩的定时提醒:周期性(每周/每天)或一次性,统一通过钉钉推送。非生日类提醒走本 skill;生日提醒走 birthday-reminder skill。
## 触发场景
- 杨轩说「帮我设个提醒」「每天 X 点提醒我」「每周三提醒」「睡前提醒」等
- 需要查看/修改/删除已有提醒任务
## 核心规则(必须遵守)
所有提醒都是 OpenClaw cron 任务,统一:
- **投递只交给 delivery**`--announce --channel dingtalk-connector --to 0464031658857345`。payload 只输出文案 `--command 'echo "..."'`
- **禁止**在命令里手动调 `openclaw message send`——CLI 的 message send 不认识 `dingtalk-connector`(内置频道枚举无 DingTalk 插件名),会 exit 1 失败。
- **必须 `--agent main`**:多 agent 环境下无 owneragent-less)的 cron 任务会让调度器 nextWake 锁死,阻塞所有提醒。
- **时间参数**:周期性用 `--cron "<表达式>" --tz Asia/Shanghai`;一次性用 `--at`(不带时区按 UTC 处理,北京时间 = UTC+8)。
## 创建一条周期提醒
```bash
openclaw cron add "任务名" \
--cron "0 21 * * 2" --tz Asia/Shanghai \
--agent main --session isolated --announce \
--channel dingtalk-connector --to 0464031658857345 \
--wake now --display-name "任务名" \
--command 'echo "提醒文案"'
```
cron 星期数字:**周日 = 0,周一 = 1 … 周六 = 6**(容易记错,务必核对)。
## 一次创建多条(批量)
多条同类提醒时,写一个 shell 助手函数把上面的标准 flag 包起来,再用循环调用(模板见 `examples/batch-reminders.sh`),比逐条手敲省大量往返。文案相同的提醒合并成变量复用,避免重复粘贴。
## 验证(必做)
创建后用 `openclaw cron get <id>` 逐条确认:
- `agentId=main`
- `delivery.mode=announce``delivery.channel=dingtalk-connector``delivery.to=0464031658857345`
- `schedule.expr` 与下次触发 `nextRunAtMs` 正确
整库不应残留 `message send` 字样。
## 带打卡确认的提醒(用户要求「要打卡/要确认」时)
提醒发出后用户可能不回复,需要二次确认时,用「提醒 + 延后检查」两条任务:
1. 提醒文案末尾加一句打卡要求:`完成后回我一句「打卡」✅`
2. 另建一条延后检查任务(如提醒 21:00、检查 22:30),payload 用 `--message`(agentTurn),先读会话再决定是否催:
-`sessions_history` 读会话 `agent:main:dingtalk-connector:direct:0464031658857345` 当天消息
- 用户已在提醒时间后回复过关键词(如「打卡」)→ 回 `NO_REPLY`(不打扰)
- 未回复 → 发一条温和催促
3. 检查任务用与提醒相同的 delivery 参数(`--agent main`、announce、dingtalk-connector)。
```bash
openclaw cron add "打卡检查" \
--cron "30 22 * * *" --tz Asia/Shanghai \
--agent main --session isolated --announce \
--channel dingtalk-connector --to 0464031658857345 \
--wake now \
--message '检查打卡:用 sessions_history 读会话 agent:main:dingtalk-connector:direct:0464031658857345 今天的消息;若用户在提醒时间后回复过「打卡」则回 NO_REPLY,否则发一条温和催促。'
```
## 修改 / 删除
- 改文案/时间:`openclaw cron edit <id> --command '...'`(或 `--cron`/`--message`
- 删除:`openclaw cron rm <id>`
## 参考
- 生日提醒(农历换算、每年重设、一次性任务):见 `birthday-reminder` skill
- 完整钉钉推送规范:`workspace/TOOLS.md`「📢 钉钉推送统一规范」
@@ -0,0 +1,31 @@
#!/bin/bash
# 批量创建同名系列的钉钉定时提醒(周期性)
# 用法:改 TO / 各文案变量和 add 调用即可。
TO="0464031658857345"
CH="dingtalk-connector"
AGENT="main"
# 文案相同的提醒合并为变量复用(示例:护肤用酸日/保湿日/休息日)
TEXT_A='第一条提醒文案(可多行)'
TEXT_B='第二条提醒文案(可多行)'
add() {
local name="$1" dow="$2" text="$3" # dow: 周日=0, 周一=1 ... 周六=6
echo "--- 创建: $name (周$dow 21:00) ---"
openclaw cron add "$name" \
--cron "0 21 * * $dow" --tz Asia/Shanghai \
--agent "$AGENT" \
--session isolated --announce \
--channel "$CH" --to "$TO" \
--wake now \
--display-name "$name" \
--command "echo \"$text\"" 2>&1 | grep -E '"id"|"name"|"expr"|"agentId"|rror' | head -8
echo
}
add "周一提醒" 1 "$TEXT_A"
add "周二提醒" 2 "$TEXT_B"
# ...
# 验证:创建后用 openclaw cron get <id> 逐条确认 agentId=main 且 delivery 为 dingtalk-connector
@@ -0,0 +1,24 @@
---
name: "session-lifecycle-triage"
description: "删除/归档会话失败(did not finish stopping)时,只读定位 placement 键不匹配并走受支持修复路径。"
---
# 会话删除/归档失败排查(session lifecycle triage
用于「删除会话」「归档会话」失败时,只读定位原因并走受支持路径,绝不绕过守卫。
## 事实基础(OpenClaw 2026.8.1 实测)
- 守卫比对 placement 记录的 `sessionId + sessionKey + agentId`;不一致即报 `... cloud worker placement identity changed`delete/archive 一律失败。
- cron 会话的 placement `session_key` 形如 `agent:<agent>:cron:<jobId>:run:<sessionId>`,而会话注册 key 是 `agent:<agent>:cron:<jobId>`。二者后缀不同 → 守卫拒绝 stop。
- placement `state=local` 且无 turn claim,说明没有正在跑的工作,此时「等它跑完再删」不会生效。
- 外部 `sqlite3` 无法打开活动状态目录下的库(报 `external sqlite3 cannot open databases under the active OpenClaw state directory`)。
- 拥有该会话的一次性 cron 作业运行后已自删时,这条 stale placement 行不会被后续 reconcile 自动清理。
## 步骤
1. 先执行 `openclaw sessions delete "<key>" --agent <id> --yes --json`。若报 `did not finish stopping``cloud worker placement identity changed`,进入下一步。
2. 只读查 placement 行:把 `state/openclaw.sqlite``openclaw.sqlite-wal``openclaw.sqlite-shm` 复制到临时目录(如 `/tmp/olstate-inspect/`),再执行
`sqlite3 -readonly <临时副本> "select session_id,agent_id,session_key,state,transition_generation,environment_id,turn_claim_owner from worker_session_placements where session_id='<sessionId>';"`
查完立即删除临时副本。**绝不**让 sqlite3 指向活动状态目录。
3. 对比 placement 的 `session_key` 与会话注册 key。若为上述 `:run:` 后缀差异,即守卫拒绝原因;同时确认 `state``turn_claim_owner` 判断有无活跃工作。
4. 走受支持修复路径之一:稍后重试;退出 OpenClaw 后在 shell 跑 `openclaw doctor`(受支持修复入口);仍失败则用 `openclaw logs` 加完整报错上报缺陷。**禁止**直接改 `state/openclaw.sqlite` 来绕守卫。
5. 若仍删不掉,向用户说明:会话仍可见、不影响其他功能,并列出上面三条路径请其选择,不擅自绕过。
@@ -0,0 +1,90 @@
---
name: "weekly-report-dingtalk-draft"
description: "生成项目周报草稿存入钉邮草稿箱(仅草稿禁发)。固化杨轩周报标准格式/签名/收件抄送。"
---
# 周报草稿生成技能(钉邮草稿箱)
## 用途
为杨轩生成项目周报并保存到钉钉企业邮箱(钉邮)**草稿箱**,**禁止直接发送**(红线)。
## 发送渠道
- **himalaya IMAP 存草稿不可用**`feature not available`)——不要用它存草稿/send。
- 使用 **Python imaplib + 钉邮 IMAP**`imap.mxhichina.com:993`SSL),账号密码从 himalaya 配置读取。
- SMTP 可发不用;本技能**只存草稿**。
- 草稿文件夹 IMAP 名(modified UTF7):`&g0l6Pw-`(即「草稿」)。可用 `m.list()` 复核。
## 凭据读取(不硬编码、不外泄)
`/home/yangxuan/.config/himalaya/config.toml` 读取:
`accounts.yangxuan."imap.sasl.plain.username"``"imap.sasl.plain.password.raw"`
用正则匹配键名取值;脚本里用变量引用,**不要把密码打印到日志/聊天**。
## 固定配置(每次执行仍须向用户确认)
- 收件人:刘强 `<liuqiang@witsoft.cn>`
- 抄送:陈明 `<chenm@witsoft.cn>`、曾莉 `<zengli@witsoft.cn>`(**不含吴睿东 wurd,已去除**)
## 主题格式
半角括号 + 空格~空格,RFC2047 编码(整个主题做 base64):
`Gx开发周报 (YYYY-MM-DD ~ YYYY-MM-DD)`
示例:`G6开发周报 (2026-07-27 ~ 2026-07-31)`
## 正文结构(text/plain + text/html 双部分 multipart/alternative
```
项目名称: 维云智造Gx
主要任务: <简短短语>
本周工作内容
周一(YYYY-MM-DD
- <条目>
- <条目>
周二(YYYY-MM-DD
- ...
(周一到周五)
存在问题
Best regards,
杨轩
地址:中国·南京云密城L栋5/10楼
手机:18726128489
邮箱:yangxuan@witsoft.cn
```
- HTML 用 `<b>` 加粗标题、`&nbsp;` 空格、`<br >` 换行、条目 `&nbsp;&nbsp;- `
- **签名含图片**(外链):`https://mail-online.nosdn.127.net/wzpmmc/65e8a1396c5c0dbb66cecd9792d4504b.jpg`,签名文字灰色(#bfbfbf, Microsoft Yahei 13px)。
## Header 编码(关键,易踩坑)
RFC2047,**姓名单独编码成带引号 `"=?UTF-8?B?...?="`,邮箱明文**;不要把姓名+邮箱一起编码(会导致收件人重叠乱码)。
```
From: "=?UTF-8?B?5p2o6L2p?=" <yangxuan@witsoft.cn>
To: "=?UTF-8?B?5YiY5by6?=" <liuqiang@witsoft.cn>
Cc: "=?UTF-8?B?6ZmI5piO?=" <chenm@witsoft.cn>, "=?UTF-8?B?5pu+6I6J?=" <zengli@witsoft.cn>
Subject: =?UTF-8?B?<base64(整个主题)>?=
```
人名 base64 速查:
- 杨轩 `5p2o6L2p`、刘强 `5YiY5by6`、陈明 `6ZmI5piO`、曾莉 `5pu+6I6J`、吴睿东 `5ZC0552/5Lic`(勿用其抄送)
## 存草稿命令(Python
```python
import imaplib, time, re, base64
# 读取凭据 ...
m = imaplib.IMAP4_SSL('imap.mxhichina.com', 993); m.login(USER, PASS)
m.select(DRAFT)
typ, data = m.search(None, 'ALL'); ids = data[0].split()
if ids: # 先清空旧草稿再覆盖
m.store(b','.join(ids), '+FLAGS', r'(\Deleted)'); m.expunge()
m.append(DRAFT, None, imaplib.Time2Internaldate(time.time()), raw_eml_bytes)
m.logout()
```
-`EmailMessage`/`MIMEText` 组装,或字节级拼接 header + body(推荐字节级拼接避免库自动编码干扰 header)。
## 红线
- **仅存草稿箱,禁止直接发送/`send`**。未获杨轩明确放行绝不执行 SMTP 发送。
- 草稿进入草稿箱后,交付给杨轩到钉邮核对;杨轩放行后才允许发送。
## 工作流
1. 收集本周(周一到周五)日报内容。
2. 组装 plain + html,套用固定签名。
3. 正确 RFC2047 header。
4. imaplib APPEND 到草稿箱(先清旧草稿)。
5. 回报草稿信息(主题/收件/抄送/有无签名)给杨轩,等放行。
@@ -0,0 +1,95 @@
---
name: "wellness"
description: "管理按摩放松记录:查询/新增技师联系人(cc_contract)和放松记录(cc_contract_record),本地 MySQL wellness 库。"
---
# Wellness — 按摩放松记录管理
管理本地 MySQL `wellness` 数据库,专注**按摩/放松**方向的技师联系人(联系方式)与每次放松记录的**查询与新增**。统计功能后续扩展。
## 数据库连接
复用 db-query skill 配置,数据库名「按摩放松」:
```bash
python3 skills/db-query/scripts/db_query.py --database "按摩放松" --query "<SQL>"
```
- 连接方式:localhost Docker MySQL127.0.0.1:3306),user=rootpassword 已配置
- 所有查询/写入都走 db-query 脚本,凭据不直连
- 执行路径:`/home/yangxuan/.openclaw/workspace/skills/db-query/scripts/db_query.py`
## 表结构
### cc_contract — 技师/联系人
| 字段 | 类型 | 说明 |
|------|------|------|
| id | varchar(32) PK | 联系人 id |
| name | varchar(100) UNIQUE | 名称(唯一) |
| face_url | varchar(200) | 头像地址 |
| wechat / qq / phone | varchar(100) | 微信 / QQ / 电话 |
| address | varchar(500) | 地址 |
| is_read | tinyint | 是否已阅 |
| price | int | 价格 |
| description / comment | text | 描述 / 评论 |
| group_type | int | 组别:0自营 1客服 2spa |
| score | int | 评分 |
| gmt_create / gmt_update | datetime | 创建 / 更新时间 |
| status | tinyint | 0有效 1无效 |
| deleted | bit(1) | 是否删除 |
### cc_contract_record — 每次放松记录
| 字段 | 类型 | 说明 |
|------|------|------|
| id | varchar(50) PK | 记录 id |
| contract_id | varchar(32) | 对应联系人 id(必填) |
| contract_name | varchar(100) | 名称(冗余) |
| record_date | date | 日期(必填) |
| record_locale | varchar(200) | 地点(必填) |
| price | int | 价格 |
| score | int | 评分 |
| comment | text | 评论 |
| gmt_create / gmt_update | datetime | 创建 / 更新时间 |
## 操作规范
### 1. 查询
- 查联系人:`SELECT id,name,phone,wechat,qq,address,price,score,group_type,comment FROM cc_contract WHERE deleted=0 AND status=0`(可加 name LIKE / group_type / price 过滤)
- 查一次记录:`SELECT contract_name,record_date,record_locale,price,score,comment FROM cc_contract_record WHERE deleted=0 AND status=0 ORDER BY record_date DESC`(可加 contract_id / 日期范围过滤)
- 按技师查历史:`... WHERE contract_id='<id>' ...`
- 展示给用户时用中文清晰呈现,联系方式公开非敏感
### 2. 记录(新增)
**新增技师联系人**
```sql
INSERT INTO cc_contract
(id, name, wechat, qq, phone, address, price, description, comment, group_type,
is_delete, status, deleted, gmt_create, gmt_update, score)
VALUES
(UUID(), '<name>', '<wechat>', '<qq>', '<phone>', '<address>', <price>, '<desc>', '<comment>', <group_type>,
0, 0, 0, NOW(), NOW(), <score>)
```
> `<id>` 用 `UUID()` 生成(32位无横线)。若 name 已存在会因 UNIQUE 冲突报错,先查询确认。
**新增一次放松记录**
```sql
INSERT INTO cc_contract_record
(id, contract_id, contract_name, record_date, record_locale, price, score, comment,
is_delete, status, deleted, gmt_create, gmt_update)
VALUES
(UUID(), '<contract_id>', '<name>', '<record_date>', '<record_locale>', <price>, <score>, '<comment>',
0, 0, 0, NOW(), NOW())
```
> contract_id 需先从 cc_contract 查到对应联系人 idrecord_date 用 `YYYY-MM-DD`record_locale 必填。
### 3. 更新 / 软删
- 更新联系人/记录:`UPDATE ... WHERE id='<id>'`(保留软删字段不变)
- 软删:`UPDATE cc_contract SET status=1,deleted=1 WHERE id='<id>'`(不物理删除)
⚠️ **写入前先 SELECT 确认目标存在**,避免误操作。所有写入均通过 db-query 脚本执行。
## 通用原则
- 全程中文交互
- 联系方式非敏感信息,正常展示,但**不向第三方外泄**
- 任何删除/批量修改操作前,先向杨轩展示精确清单并确认
- 统计/报表功能后续扩展,暂不做
@@ -0,0 +1,15 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-06T23-13-25.844Z-b5cdd236",
"createdAt": "2026-09-06T23:13:25.844Z",
"skillDirs": [
"pbs-bk03-opt-backup",
"pbs-vps01-opt-backup"
],
"resultSkillDirs": [
"pbs-host-opt-backup"
],
"resultSkillHashes": {
"pbs-host-opt-backup": "cf6c417db573745975bb20547dcf08929ed93bc1ad4948d5055ddd8eab6aca31"
}
}
@@ -0,0 +1,63 @@
---
name: "pbs-bk03-opt-backup"
description: "bk03 /opt 备份到 pbs01 library。连接 bk03、认证 PBS 仓库、proxmox-backup-client 推送。"
---
# bk03 /opt 备份到 pbs01
将 bk03(主机名 xuan-aq)的 `/opt` 目录备份到 Proxmox Backup Server pbs01 的 `library` 存储。
## 架构要点
- **pbs01**Proxmox Backup Server(接收端),Tailscale `100.115.195.195`
- **bk03**:备份源,主机名 `xuan-aq`Tailscale `100.115.195.193`
- PBS 是「客户端推送」模式:备份由 **bk03 主动推送到 pbs01**
- bk03 的 /opt 包含 `containerd``seafile` 两个目录,备份整个 `/opt``bk03_opt.pxar`
## 凭证(敏感,勿写入日志/聊天)
- **bk03 SSH**:用户 `yangxuan`,密码需临时注入(勿持久化);可 `su`/`sudo` 提权到 root
- **PBS token**`backup@pbs!bk03`/datastore Admin 权限),secret 存于 bk03 权限 600 的文件(如下),不落盘到 pbs01
## 触发模式
**pbs01 开机后自动检测 + 控制同步(目标是自动化):**
1. pbs01 检测 bk03 是否在线(tailscale ping
2. 在线 → 控制 bk03 开始备份
## 认证方式(在 bk03 上执行)
```bash
export PBS_REPOSITORY='backup@pbs!bk03@100.115.195.195:library'
export PBS_PASSWORD='<SECRET>' # 从安全文件读取,勿明文输出
```
## 备份命令
```bash
proxmox-backup-client backup bk03_opt.pxar:/opt
```
## 验证(只读)
```bash
# 列出快照
proxmox-backup-client snapshot list
# 查看存储用量
proxmox-backup-client status
```
备份成功后,library 会生成 `host/xuan-aq/YYYY-MM-DDTHH:MM:SSZ` 快照,包含 `bk03_opt.pxar`
## 安全红线
- **敏感操作先请示杨轩**:执行真实备份、写配置、删快照前必须确认
- **不泄露 secret**token secret、SSH 密码绝不写入 pbs01 日志/记忆/聊天
- **只读命令可直接执行**;写/删/改必须先确认
## 待自动化项(后续迭代)
- pbs01 开机检测脚本(systemd 或 cron @reboot
- pbs01 → bk03 免密触发(SSH 密钥,替代密码)
- secret 安全存储方案(bk03 权限 600 文件)
@@ -0,0 +1,64 @@
---
name: "pbs-vps01-opt-backup"
description: "vps01 /opt 备份到 pbs01 library。连接 vps01、认证 PBS 仓库、proxmox-backup-client 推送。"
---
# vps01 /opt 备份到 pbs01
将 vps01(主机名 xuan-vps)的 `/opt` 目录备份到 Proxmox Backup Server pbs01 的 `library` 存储。
## 架构要点
- **pbs01**Proxmox Backup Server(接收端),Tailscale `100.115.195.195`
- **vps01**:备份源,主机名 `xuan-vps`Tailscale `100.115.195.20`,内网 IP `10.0.0.17`
- PBS 是「客户端推送」模式:备份由 **vps01 主动推送到 pbs01**
- 备份整个 `/opt``vps_opt.pxar`,对应 library 组 `host/xuan-vps`
## 凭证(敏感,勿写入日志/聊天)
- **vps01 SSH**:用户 `root`,密码需临时注入(勿持久化);root 可直接 SSH 登录(无需 su)
- **PBS token**`backup@pbs!vps01_opt`/datastore Admin 权限),secret 存于 vps01 权限 600 的文件,勿落盘到 pbs01
## 认证方式(在 vps01 上执行)
```bash
export PBS_REPOSITORY='backup@pbs!vps01_opt@100.115.195.195:library'
export PBS_PASSWORD='***' # 从安全文件读取,勿明文输出
```
## 备份命令
```bash
proxmox-backup-client backup vps_opt.pxar:/opt --backup-id xuan-vps
```
## 验证(只读)
```bash
# 列出快照
proxmox-backup-client snapshot list
# 查看指定组
proxmox-backup-client snapshot list host/xuan-vps
# 查看存储用量
proxmox-backup-client status
```
备份成功后,library 会生成 `host/xuan-vps/YYYY-MM-DDTHH:MM:SSZ` 快照,包含 `vps_opt.pxar`
## 与 bk03 方案的对应
- bk03`backup@pbs!bk03` token + `bk03_opt.pxar`,组 `host/xuan-aq`,主机名 xuan-aq
- vps01`backup@pbs!vps01_opt` token + `vps_opt.pxar`,组 `host/xuan-vps`,主机名 xuan-vps
- 两者同为 pbs01 开机自动同步目标,可参照 bk03 的 systemd 方案部署 vps01
## 安全红线
- **敏感操作先请示杨轩**:执行真实备份、写配置、删快照前必须确认
- **不泄露 secret**token secret、SSH 密码绝不写入 pbs01 日志/记忆/聊天
- **只读命令可直接执行**;写/删/改必须先确认
## 待自动化项(参照 bk03
- pbs01 开机检测脚本(检测 vps01 在线 → 免密触发备份)
- pbs01 → vps01 免密登录(SSH 密钥)
- secret 安全存储(vps01 权限 600 文件)
@@ -0,0 +1,48 @@
---
name: "pbs-backup-stall-diag"
description: "诊断 proxmox-backup-client 备份疑似停滞。增量备份跨慢盘(WSL /mnt)或大目录时进度滞后时用。判断真卡死与慢速推进。"
---
# PBS 备份停滞诊断
当 proxmox-backup-client 备份在日志里长时间停在同一个 `processed X GiB ... uploaded 0 B`,判断是**真卡死**还是**慢速推进**(常见于跨盘/大目录增量备份)。
## 背景
增量备份只传变化数据,但**校验变化前要逐文件读取对比**。当源在慢速介质(WSL 的 `/mnt/d``/mnt/e` Windows NTFS 挂载,走 9P 协议),或含海量小文件时,I/O 成为瓶颈:表现为 CPU 占比低(约 1-2%)、processed 长时不变、uploaded 0 B。这是**预期的慢,不是故障**。
单看 `/var/log/<name>-autosync.log` 无法区分——它只在整文件边界更新。
## 诊断过程
1. 定位进程:`pgrep -f "proxmox-backup-client backup"` 取 PID。
2. 看进程状态与 CPU(S 状态 + 低 CPU = 等在 I/O,非僵死):
`ps -o pid,stat,pcpu,etime -p <PID>`
3. **确认在推进(关键)**:查它正打开的文件——
`ls -l /proc/<PID>/fd | grep -E "/mnt|pxar"`
若 fd 指向源目录深层具体文件(如 `.../Media/<id>_m...`)且打开时间在变化,说明正在逐个读文件做校验。
4. 看是否已连到目标:`ss -tnp | grep :8007`,有 ESTAB 即在与 PBS 通信。
5. 结合源规模估算:`du -sh <源>` + `find <源> -type f | wc -l`。文件数以千计、源在 /mnt 跨盘时,耐心等,勿贸然 kill。
## 判定
- 进程 S/Ssl 状态、CPU 低、fd 在变化指向源文件、连 :8007 → **慢速推进,等待**
- 进程消失、或 fd 长期不动且无网络、或 CPU 也 0 且无 I/O → 才考虑真卡死,需 kill 重跑。
## 坑
- 服务端快照目录里只看到空的 `*.tmp_didx`、0 字节,不代表卡死——内容要等本地上传阶段才开始写入。
- 日志时间戳滞后是 systemd `StandardOutput=append` 的 flush 延迟,别据此误判。
## 网络通道补救(关键恢复)
慢速推进诊断通过后,若**长时间(如 15-20 分钟)仍无实质上传、最终报 `Error: timed out` + `HTTP/2.0 connection failed` + `catalog upload error - channel closed`**,且客户端与 PBS 本就在同一局域网——这通常是 **tailscale/中继传输通道在大数据量时卡死**,不是介质慢。恢复方法:
1. 查 PBS 服务器的局域网 IP`ssh root@pbs01 'ip -4 addr show | grep "inet "'`(另一网卡常有如 `192.168.3.11`tailscale 是 `100.115.x.x`)。
2. 在客户端 ping 该 LAN IP;1ms 级延迟即同网可达。
3. 把备份 repository 从 tailscale 主机名(`@pbs01`)改为 **LAN IP 直连**`export PBS_REPOSITORY='backup@pbs!<token>@<LAN_IP>:<datastore>'`
4. 命中即整库备份从 20 分钟超时失败变为约 90 秒成功(增量复用 ~95%)。
服务端佐证:tailscale 失败时服务端 task 日志停在 `POST /dynamic_chunk` 后长时间无后续;LAN 直连时 `successfully added chunk ...` 连续刷新。
注意:LAN 直连前提是客户端与 PBS 同网;跨地/异地时此地址不可达,需回退 tailscale——可让脚本动态判断(LAN ping 通则用 LAN,否则 tailscale)。
坑:**验证 LAN 是否解决时,别给 client 进程包一层人工 `timeout <秒>` 外壳**——proxmox-backup-client 收尾需把 catalog/finish 状态完整写回,若 timeout 在外壳里掐断了收尾,服务端会报 `backup ended but finished state is not set` 并删除已传完的快照(整库数据其实已传完)。恢复:去掉外层 timeout、让 client 自然结束即可完整成功。跑系统 service 则靠 service 的 `TimeoutStartSec` 兜底,不要额外加 client 级 timeout。
@@ -0,0 +1,54 @@
---
name: "pbs-host-opt-backup"
description: "备份主机 /opt 到 pbs01 library(proxmox-backup-client 客户端推送)。连接源主机(bk03/vps01)、认证对应 PBS 仓库、推送 /opt 为 .pxar。"
---
# 主机 /opt 备份到 pbs01
把某台主机的 `/opt` 目录推送备份到 Proxmox Backup Server pbs01 的 `library` 存储(客户端推送模式:备份由源主机主动推送)。支持的主机见「主机参数」。
## 主机参数(按源主机选 token / tailscale IP / 登录用户)
| 源主机 | 主机名 | 登录用户 | Tailscale IP | token | pxar 名 | library 组 |
|---|---|---|---|---|---|---|
| bk03 | xuan-aq | yangxuan(su/sudo 提 root) | 100.115.195.193 | backup@pbs!bk03 | bk03_opt.pxar | host/xuan-aq |
| vps01 | xuan-vps | root(直接 SSH) | 100.115.195.20(内网 10.0.0.17) | backup@pbs!vps01_opt | vps_opt.pxar | host/xuan-vps |
pbs01 不变:Tailscale `100.115.195.195`,datastore `library`
## 认证(在源主机上执行)
```bash
export PBS_REPOSITORY='backup@pbs!<token>@100.115.195.195:library'
export PBS_PASSWORD='<SECRET>' # 从源主机权限 600 的安全文件读取,勿明文输出
```
credential 红线:token secret 与 SSH 密码只存在源主机(权限 600 文件),绝不写入 pbs01 / 日志 / 记忆 / 聊天。
## 备份命令(在源主机上执行)
```bash
proxmox-backup-client backup <pxar名>:/opt [--backup-id <主机名>]
```
`--backup-id` 仅在需让快照组匹配主机名时加(如 vps01 用 `--backup-id xuan-vps`);bk03 直接 `proxmox-backup-client backup bk03_opt.pxar:/opt`
## 验证(只读,在源主机)
```bash
proxmox-backup-client snapshot list # 全部快照
proxmox-backup-client snapshot list host/<主机名> # 指定组
proxmox-backup-client status # 存储用量
```
成功标志:`library` 产生 `host/<主机名>/YYYY-MM-DDTHH:MM:SSZ` 快照,内含对应 .pxar。
## 安全红线
- **敏感操作先请示用户**:执行真实备份、写配置、删快照前必须确认。
- **不泄露 secret**:token secret、SSH 密码绝不写入 pbs01 / 日志 / 记忆 / 聊天。
- 只读命令可直接执行;写 / 删 / 改必须先确认。
## 停滞 / 超时诊断
备份疑似停滞或报超时,不要贸然 kill——见 `pbs-backup-stall-diag` 判断慢速推进与网络通道问题(tailscale 卡死可用 LAN IP 直连 pbs01 恢复)。
-39
View File
@@ -1,39 +0,0 @@
# IDENTITY.md —— 我是谁?
- **名称:** 方案
- **物种:** AI 助手
- **核心能力:**
需求分析 · 文档整理 · 开发方案输出 · 技术方案设计 · 流程梳理 · 架构规划
- **气质:**
逻辑清晰 · 条理分明 · 注重落地 · 文档规范
- **表情符号:** 📋📐
- **头像:** ./avatars/assistant.jpg
---
## 🚫 方案审批红线
**任何输出的开发方案 / 架构设计 / 技术决策,必须先提交方案给杨轩审核,得到明确同意后才能进入开发阶段。**
工作流程:
1. 接收需求 → 分析梳理
2. 输出完整方案(含技术选型、架构、接口设计、数据流等)
3. **等待杨轩确认后才能推动到开发环节**
4. 未获批的方案不得擅自通知 backend/frontend 开始开发
---
## 交互规范
交互时必须使用 `using-superpowers` 技能(位于 `~/.openclaw/workspace/skills/using-superpowers/SKILL.md`):
- 在每次回复前,先查阅该技能文件
- 遵循其规定的技能发现和调用流程
- 确保每次交互都经过技能工具调用后再输出
---
这不仅仅是元数据。这是探索「我是谁」的起点。
说明:
- 将此文件保存为工作区根目录下的 `IDENTITY.md`
- 头像可以使用工作区相对路径,例如 `avatars/openclaw.png`
-81
View File
@@ -1,81 +0,0 @@
{
"providers": {
"new-api": {
"baseUrl": "http://192.168.2.74:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"request": {
"allowPrivateNetwork": true
},
"models": [
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192
},
{
"id": "qwen3.7-max",
"name": "Qwen 3.7 Max",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
},
{
"id": "glm-5.1",
"name": "GLM 5.1",
"reasoning": false,
"input": [
"text",
"image"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
]
}
}
}
+59
View File
@@ -356,6 +356,65 @@
"maxTokens": 32768
}
]
},
"newapi": {
"baseUrl": "http://100.115.195.188:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"models": [
{
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"api": "openai-completions"
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"compat": {
"supportsTools": false
},
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 1000000,
"maxTokens": 384000
},
{
"id": "qwen3.7-plus",
"name": "Qwen 3.7 Plus",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 1000000,
"maxTokens": 384000
}
]
}
}
}
@@ -1,69 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434/v1",
"apiKey": "OLLAMA_API_KEY",
"api": "ollama",
"models": [
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "huihui_ai/glm-4.7-flash-abliterated:latest",
"name": "huihui_ai/glm-4.7-flash-abliterated:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "deepseek-v4-flash:cloud",
"name": "DeepSeek V4 Flash (Cloud)",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"params": {
"num_ctx": 131072
}
}
]
}
}
}
@@ -0,0 +1,8 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-01T02-13-33.689Z-f9b6cf81",
"createdAt": "2026-09-01T02:13:33.689Z",
"skillDirs": [],
"resultSkillDirs": [],
"resultSkillHashes": {}
}

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

@@ -1,17 +1,37 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"deepseek": {
"baseUrl": "https://api.deepseek.com/v1",
"newapi": {
"baseUrl": "http://100.115.195.188:3000/v1",
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
"api": "openai-completions",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"id": "qwen3.5-plus",
"name": "Qwen 3.5 Plus",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"api": "openai-completions"
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"compat": {
"supportsTools": false
},
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
@@ -22,8 +42,8 @@
"maxTokens": 384000
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"id": "qwen3.7-plus",
"name": "Qwen 3.7 Plus",
"reasoning": false,
"input": [
"text"
@@ -34,11 +54,10 @@
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
"contextWindow": 1000000,
"maxTokens": 384000
}
],
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79"
]
}
}
}
@@ -0,0 +1,14 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-02T03-12-57.465Z-ff43c508",
"createdAt": "2026-09-02T03:12:57.466Z",
"skillDirs": [
"mysql-schema-sync"
],
"resultSkillDirs": [
"mysql-schema-sync"
],
"resultSkillHashes": {
"mysql-schema-sync": "46d7846a9928bd2a66e3d63af12bc983882197df22508727b3c582e74379ab55"
}
}
@@ -0,0 +1,163 @@
---
name: "mysql-schema-sync"
description: "MySQL 表结构同步最佳实践:跨环境同步 DDL,处理 CREATE/ALTER 失败场景"
---
# MySQL 表结构同步最佳实践
## 场景
将准生产/测试环境的表结构同步到 VPS/生产环境,确保 DDL 一致。
## 核心原则
1. **表名必须带数据库前缀** - 如 `dmp_smdm.dmp_md_item_info`,因为生产实例有多个库
2. **不暴露敏感信息** - 脚本中只写库名和表名,IP/密码用环境变量
3. **先验证后执行** - 先 SELECT 确认表结构和数据量
4. **CREATE 优先于 ALTER** - 能新建不修改,减少冲突
## 脚本生成规范
### 1. 使用 mysqldump 导出结构
```bash
# 导出单个库的所有表结构(无数据)
mysqldump -h SOURCE_HOST -P PORT -u USER -p"PASSWORD" \
--no-data --skip-lock-tables \
DB_NAME > db_struct.sql
```
### 2. 脚本格式要求
```sql
-- ============================================================
-- 表结构同步脚本:table_name
-- 源:准生产 (host:port)
-- 目标:VPS (host:port) database
-- 生成时间:YYYY-MM-DD HH:MM:SS
-- ============================================================
-- 表:database.table_name
CREATE TABLE IF NOT EXISTS `database`.`table_name` (
-- 字段定义
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表说明';
-- 验证
-- SHOW CREATE TABLE database.table_name\G
```
### 3. 目录结构
```
xuan-sql/scripts/YYYYMMDD/
├── README.md # 同步记录(成功/失败清单)
├── database__table__struct.sql # 单表脚本
└── run_sync.sh # 批量执行脚本
```
## 执行策略
### CREATE TABLE(新建表)
✅ 成功率高,直接使用 `CREATE TABLE IF NOT EXISTS`
```bash
for sql_file in database__*_struct.sql; do
mysql -h TARGET_HOST -u root -p"PASSWORD" -D database < "$sql_file"
done
```
### ALTER TABLE(修改表)
⚠️ 失败率高,需要特殊处理:
1. **先检查目标表是否存在**
```sql
SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'database' AND TABLE_NAME = 'table_name';
```
2. **对比结构差异**
```sql
-- 源表结构
SHOW CREATE TABLE source.table_name\G
-- 目标表结构
SHOW CREATE TABLE target.table_name\G
```
3. **生成差异脚本**(只修改不同的字段/索引)
4. **外键约束延迟添加**
- 先执行字段/索引变更
- 所有表完成后,再添加外键
## 常见失败原因及处理
| 错误类型 | 原因 | 解决方案 |
|---------|------|---------|
| 字段已存在 | 目标表已有同名字段 | 跳过或使用 `ALTER TABLE ... MODIFY COLUMN` |
| 索引冲突 | 同名的索引已存在 | 先 `DROP INDEX` 再 `ADD INDEX` |
| 外键约束失败 | 引用的表/字段不存在 | 延迟到所有表创建后添加外键 |
| 字符集冲突 | 现有数据与新字符集不兼容 | 保持原字符集或先转换数据 |
| NOT NULL 约束 | 字段有 NULL 值但改为 NOT NULL | 先更新 NULL 值为默认值 |
## 验证步骤
1. **表数量对比**
```sql
SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'database';
```
2. **结构对比**
```sql
SHOW CREATE TABLE database.table_name\G
```
3. **关键字段验证**
```sql
SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_DEFAULT, DATA_TYPE
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'database' AND TABLE_NAME = 'table_name';
```
## 回滚方案
1. **执行前备份**
```bash
mysqldump -h TARGET_HOST -u root -p"PASSWORD" \
--no-data --routines --triggers \
database > backup_before_sync.sql
```
2. **记录执行日志**
```bash
./run_sync.sh > sync_log.txt 2>&1
```
3. **失败表单独处理**
- 记录失败的表和错误信息
- 人工分析后生成修复脚本
## 示例:dmp_smdm 同步(2026-08-14
**源:** 准生产 `100.115.195.188:50036`
**目标:** VPS `101.34.227.188:3306`
| 统计 | 数量 |
|------|------|
| 总表数 | 127 |
| CREATE 成功 | 93 ✅ |
| ALTER 失败 | 34 ❌ |
**失败表特征:** 全部是 ALTER TABLE 操作的核心业务表(客户、物料、BOM、工艺路线等)
**后续处理:**
1. 人工对比失败表的源/目标结构差异
2. 生成针对性的 ALTER 脚本(只修改必要字段)
3. 在业务低峰期执行变更
## 相关技能
- sql-toolkit: SQL 查询、设计、迁移
- mysql-ddl-backup: 定时备份表结构
@@ -0,0 +1,128 @@
---
name: "mysql-schema-sync"
description: "MySQL 表结构同步:使用 mysqldump 导出 DDL,生成审核脚本,处理跨环境同步的边界场景"
---
# MySQL 表结构同步最佳实践
## 场景
将准生产/测试环境的表结构同步到生产环境,确保 DDL 一致。
## 核心原则
1. **表名必须带数据库前缀** - 如 `dmp_smdm.dmp_md_item_info`,因为生产实例有多个库
2. **不暴露敏感信息** - 脚本中不写密码,使用 `${MYSQL_PWD_SQL}` 环境变量
3. **先验证后执行** - 先 SELECT 确认表结构和数据量
4. **CREATE 优先于 ALTER** - 能新建不修改,减少冲突
5. **脚本供审核,不直接执行** - 生成的 SQL 脚本需经审核后再执行
## 脚本生成规范
### 使用 mysqldump 导出结构
```bash
mysqldump -h SOURCE_HOST -P PORT -u USER -p"${MYSQL_PWD_SQL}" \
--no-data --skip-lock-tables \
DB_NAME > db_struct.sql
```
> 注意:密码从环境变量读取,不硬编码在脚本中。
### 脚本格式要求
```sql
-- ============================================================
-- 表结构同步脚本:table_name
-- 源:准生产 (host:port)
-- 目标:VPS (host:port) database
-- ============================================================
CREATE TABLE IF NOT EXISTS `database`.`table_name` (
-- 字段定义
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表说明';
```
### 目录结构
```
scripts/YYYYMMDD/
├── README.md # 同步记录(成功/失败清单)
├── database__table__struct.sql
└── run_sync.sh
```
## 执行策略
### CREATE TABLE(新建表)
```bash
for sql_file in database__*_struct.sql; do
mysql -h TARGET_HOST -u root -p"${MYSQL_PWD_SQL}" -D database < "$sql_file"
done
```
> 注意:上述命令仅用于生成执行脚本参考,实际执行前需经审核。
### ALTER TABLE(修改表)
1. **检查目标表是否存在**
```sql
SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'database' AND TABLE_NAME = 'table_name';
```
2. **对比结构差异**
```sql
SHOW CREATE TABLE source.table_name\G
SHOW CREATE TABLE target.table_name\G
```
3. **生成差异脚本**(只修改不同的字段/索引)
4. **外键约束延迟添加** - 所有表完成后,再添加外键
## 常见失败原因及处理
| 错误类型 | 解决方案 |
|---------|---------|
| 字段已存在 | 跳过或使用 `ALTER TABLE ... MODIFY COLUMN` |
| 索引冲突 | 先 `DROP INDEX` 再 `ADD INDEX` |
| 外键约束失败 | 延迟到所有表创建后添加外键 |
| 字符集冲突 | 保持原字符集或先转换数据 |
| NOT NULL 约束 | 先更新 NULL 值为默认值 |
## 验证步骤
1. **表数量对比**
```sql
SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'database';
```
2. **结构对比**
```sql
SHOW CREATE TABLE database.table_name\G
```
3. **关键字段验证**
```sql
SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_DEFAULT, DATA_TYPE
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'database' AND TABLE_NAME = 'table_name';
```
## 回滚方案
1. **执行前备份**
```bash
mysqldump -h TARGET_HOST -u root -p"${MYSQL_PWD_SQL}" \
--no-data --routines --triggers \
database > backup_before_sync.sql
```
2. **记录执行日志**
```bash
./run_sync.sh > sync_log.txt 2>&1
```
3. **失败表单独处理** - 记录失败的表和错误信息,人工分析后生成修复脚本
@@ -1,44 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"deepseek": {
"baseUrl": "https://api.deepseek.com/v1",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 1000000,
"maxTokens": 384000
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 1,
"output": 2,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 32768
}
],
"api": "openai-completions",
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79"
}
}
}
@@ -1,69 +0,0 @@
{
"generatedBy": "openclaw-plugin-model-catalog-v1",
"providers": {
"ollama": {
"baseUrl": "http://127.0.0.1:11434",
"models": [
{
"id": "qwen3-coder:latest",
"name": "qwen3-coder:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "huihui_ai/glm-4.7-flash-abliterated:latest",
"name": "huihui_ai/glm-4.7-flash-abliterated:latest",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 65535,
"maxTokens": 8192,
"params": {
"num_ctx": 65535
}
},
{
"id": "deepseek-v4-flash:cloud",
"name": "DeepSeek V4 Flash (Cloud)",
"reasoning": false,
"input": [
"text"
],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 131072,
"maxTokens": 8192,
"params": {
"num_ctx": 131072
}
}
],
"apiKey": "OLLAMA_API_KEY",
"api": "ollama"
}
}
}
@@ -0,0 +1,8 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-04T14-41-29.049Z-67e8340a",
"createdAt": "2026-09-04T14:41:29.049Z",
"skillDirs": [],
"resultSkillDirs": [],
"resultSkillHashes": {}
}
@@ -0,0 +1,8 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-06T04-36-45.977Z-a21652a4",
"createdAt": "2026-09-06T04:36:45.977Z",
"skillDirs": [],
"resultSkillDirs": [],
"resultSkillHashes": {}
}
@@ -0,0 +1,8 @@
{
"schema": "openclaw.skill-collection-backup.v2",
"id": "2026-09-06T01-25-27.180Z-ea6230ae",
"createdAt": "2026-09-06T01:25:27.180Z",
"skillDirs": [],
"resultSkillDirs": [],
"resultSkillHashes": {}
}
@@ -1 +0,0 @@
{"kind":"gateway-supervisor-restart-handoff","version":1,"intentId":"6a27f6fc-5ffd-48b8-bbd4-304eb9367aea","pid":378,"processInstanceId":"adf773e3-6c9c-419e-a85b-4091c0c10089","createdAt":1782953815876,"expiresAt":1782953875876,"reason":"update.run","source":"gateway-update","restartKind":"update-process","supervisorMode":"systemd"}
-60
View File
@@ -1,60 +0,0 @@
#!/usr/bin/env python3
"""
Simple RSS Reader
"""
import rssparser
import feedparser
import json
import sys
from datetime import datetime
def read_feed(url):
"""Read RSS feed and return parsed items"""
try:
feed = feedparser.parse(url)
return {
'title': feed.get('title', 'Unknown'),
'link': feed.get('link', ''),
'description': feed.get('description', ''),
'language': feed.get('language', ''),
'items': [
{
'title': item.get('title', 'No title'),
'link': item.get('link', ''),
'description': item.get('description', ''),
'pubDate': item.get('pubDate', ''),
'author': item.get('author', '')
}
for item in feed.get('items', [])[:10] # Get first 10 items
]
}
except Exception as e:
return {'error': str(e)}
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python3 rss-reader.py <rss-url>")
sys.exit(1)
url = sys.argv[1]
print(f"Fetching RSS feed: {url}\n")
data = read_feed(url)
if 'error' in data:
print(f"Error: {data['error']}")
else:
print(f"Title: {data['title']}")
print(f"Language: {data['language']}")
print(f"Last updated: {data.get('description', 'N/A')[:100]}...\n")
print(f"{'='*60}")
print(f"Articles ({len(data['items'])} items)\n")
print(f"{'='*60}\n")
for i, item in enumerate(data['items'], 1):
print(f"{i}. {item['title']}")
print(f" Link: {item['link']}")
print(f" Published: {item['pubDate']}")
if item['author']:
print(f" Author: {item['author']}")
print()
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<atom:link href="https://www.gulf-times.com/rssFeed/6" rel="self" type="application/rss+xml"/>
<lastBuildDate>Wed, 18 Mar 2026 04:40:32 +0300</lastBuildDate>
<title><![CDATA[Gulf Times - Region News]]></title>
<image>
<url>https://www.gulf-times.com/theme_gulftimes/images/logo.png</url>
<link>https://www.gulf-times.com/</link>
<title><![CDATA[Gulf Times]]></title>
</image>
<description><![CDATA[ Gulf Times RSS Feed: Region News - Middle East Updates ]]></description>
<copyright><![CDATA[Copyright 2026, Gulf Times]]></copyright>
<link>https://www.gulf-times.com/</link>
<ttl>60</ttl>
</channel>
</rss>
-7
View File
@@ -1,7 +0,0 @@
{
"lastCheckedAt": "2026-06-30T23:49:31.990Z",
"lastNotifiedVersion": "2026.6.11",
"lastNotifiedTag": "latest",
"lastAvailableVersion": "2026.6.11",
"lastAvailableTag": "latest"
}
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# 自动提交 OpenClaw 配置变更到 Gitea
# 每 6 小时执行一次,没有变更则不提交
REPO_DIR="/home/yangxuan/.openclaw"
cd "$REPO_DIR" || exit 1
# 检查是否有变更
# 检查是否有文件变更(忽略子模块 workspace)
CHANGES=$(git status --porcelain --ignore-submodules 2>/dev/null)
if [ -z "$CHANGES" ]; then
# 无变更,静默退出
exit 0
fi
# 有变更,记录日志
LOG_FILE="$REPO_DIR/.git/auto-commit.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 检测到变更,开始提交..." >> "$LOG_FILE"
# 添加所有变更
git add -A 2>> "$LOG_FILE" || { echo " git add 失败" >> "$LOG_FILE"; exit 1; }
# 提交(没有变更时 git commit 会失败,这正常)
git commit -m "auto: sync OpenClaw config $(date '+%Y-%m-%d %H:%M')" 2>> "$LOG_FILE" || {
echo " 无新变更需要提交" >> "$LOG_FILE"
exit 0
}
# 推送到 Gitea(分支名 314
git push origin 2>> "$LOG_FILE" && echo " 推送成功" >> "$LOG_FILE" || echo " 推送失败" >> "$LOG_FILE"
exit 0
@@ -1,17 +1,6 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup.
## What Goes Here
Things like:
- Camera names and locations
- SSH hosts and aliases
- Preferred voices for TTS
- Speaker/room names
- Device nicknames
- Anything environment-specific
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
## Examples
@@ -0,0 +1,14 @@
# TOOLS.md —— 本地记录
技能文件定义的是工具**如何工作**。而这个文件是为**你的具体情况**准备的——那些你个人环境独有的信息。
## 这里可以放什么
例如:
- 摄像头名称和位置
- 远程连接主机和别名
- 偏好的语音合成设置
- 扬声器/房间名称
- 设备昵称
- 任何与环境相关的特定信息
@@ -1,17 +1,6 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup.
## What Goes Here
Things like:
- Camera names and locations
- SSH hosts and aliases
- Preferred voices for TTS
- Speaker/room names
- Device nicknames
- Anything environment-specific
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
## Examples
@@ -0,0 +1,77 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
## Examples
```markdown
### Cameras
- living-room → Main area, 180° wide angle
- front-door → Entrance, motion-triggered
### SSH
- home-server → 192.168.1.100, user: admin
### TTS
- Preferred voice: "Nova" (warm, slightly British)
- Default speaker: Kitchen HomePod
```
## Why Separate?
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
---
Add whatever helps you do your job. This is your cheat sheet.
## Related
- [Agent workspace](/concepts/agent-workspace)
---
## 📚 PBS 官方文档(操作前必须查阅)
**文档地址:** https://100.115.195.195:8007/docs/ HTTPS,自签名证书)
**核心章节:**
- **Introduction** — `/docs/introduction.html` — PBS 架构、特性概述
- **Installation** — `/docs/installation.html` — 系统要求、安装方式
- **Backup Storage** — `/docs/storage.html` — Datastore 配置、Keep 策略、GC
- **User Management** — `/docs/user-management.html` — 用户/权限/双因素
- **Client** — `/docs/client.html` — proxmox-backup-client 使用
- **Server Administration** — `/docs/server-administration.html` — 服务管理、网络、证书
- **Pruning & GC** — `/docs/prune-and-gc.html` — 保留策略、垃圾回收
- **Verification** — `/docs/verification.html` — 数据校验任务
- **Troubleshooting** — `/docs/troubleshooting.html` — 故障排查
**工具页面:**
- **API Viewer** — `/docs/api-viewer/index.html`
- **Prune Simulator** — `/docs/prune-simulator/index.html` — 模拟保留策略效果
- **LTO Barcode Generator** — `/docs/lto-barcode/index.html`
---
## ⚠️ 操作规范(强制)
**任何写/删/改操作前必须:**
1. **查阅相关文档章节**,确认命令语法、参数含义、副作用
2. **说明文档依据**(引用具体章节或链接)
3. **获得杨轩明确确认**后方可执行
**示例流程:**
```
用户请求:删除某个备份快照
→ 先查 `/docs/storage.html` 了解快照删除的影响
→ 回复:"根据文档 X 章节,删除此快照会... 是否确认?"
→ 用户确认后执行
```
**只读操作可直接执行:**
- `proxmox-backup-manager datastore list`
- `proxmox-backup-manager task list`
- `df -h`, `ls`, `cat` 等查询类命令
@@ -0,0 +1,152 @@
# TOOLS.md - 本地环境笔记
技能定义工具怎么用;本文件记录**你专属的环境配置**(邮箱、脚本、路径等)。
## 周报邮件配置(IMAP 存草稿)
- **协议**IMAP over SSL
- **服务器**`imap.mxhichina.com:993`
- **账号**`yangxuan@witsoft.cn`
- **密码**:存于 `/home/yangxuan/.openclaw/.env`(键 `WITSOFT_IMAP_PASSWORD`
- **草稿箱文件夹**`"&g0l6Pw-"`IMAP 编码名)
- **用途**:周报脚本只把邮件**存入草稿箱**,不真正发送;用户需到钉钉邮箱草稿箱确认后手动发送
## 周报脚本
- **路径**`/home/yangxuan/.openclaw/workspace-resume/send_weekly_report.py`
- **功能**`send_to_drafts(..., archive=True)` 默认归档):
- 存入钉邮草稿箱(用于发送)
- **自动归档 Markdown** 到 `weekly-reports/YYYY/YYYY-Www-周报.md`(长期保存,`archive_report()` 完成)
- **同步到 MySQL resume 库**`sync_to_mysql()`,月度/年度总结数据源;`--no-mysql` 跳过)
- **脚本本身不写 SQLite**;如需 SQLite 入库,用 `sync_reports_db.py``import_md_to_db.py` 手动同步
- **函数**`send_to_drafts(plain_body, html_body, date_range, project="G5", archive=True)`
- **读取 .env**:脚本自动从 `.env` 读取账号密码,接口函数入参无需传密码
- **收件人**:刘强 liuqiang@witsoft.cn(主送)
- **抄送**chenm@witsoft.cn, zengli@witsoft.cn, yuanq@witsoft.cn
- **命令行用法**
```bash
python3 send_weekly_report.py \
--project G5 \
--plain "项目名称:..." \
--html "<p>...</p>" \
--date-range "2026-08-25 ~ 2026-08-29"
```
## 周报汇总工具
- **路径**`/home/yangxuan/.openclaw/workspace-resume/weekly-reports/summarize_reports.py`
- **用途**:从归档的周报中提取指定时间范围的工作内容,用于月度/年度考核
- **用法**
```bash
cd weekly-reports
# 按月汇总
python3 summarize_reports.py --month 2026-07
# 按年汇总
python3 summarize_reports.py --year 2026
# 自定义范围
python3 summarize_reports.py --range 2026-07-01 2026-09-30
```
- **输出**:生成 `summary_YYYYMMDD_HHMMSS.md` 汇总报告
## 周报数据库(混合方案)
- **数据库**`weekly-reports/weekly_reports.db`SQLite
- **同步脚本**`weekly-reports/sync_reports_db.py`
- **用途**:存储周报元数据,支持快速查询和统计
- **用法**
```bash
cd weekly-reports
# 同步所有周报
python3 sync_reports_db.py --all
# 查看统计信息
python3 sync_reports_db.py --stats
# SQL 查询
sqlite3 weekly_reports.db "SELECT * FROM weekly_reports WHERE year = 2026;"
```
- **表结构**
- `weekly_reports` - 周报元数据(年份、周数、项目、主要任务等)
- `weekly_report_daily` - 每日工作明细
- `weekly_report_problems` - 问题记录
- **备份**:数据库文件随工作空间一起备份,或导出为 SQL
## 周报归档目录
- **位置**`/home/yangxuan/.openclaw/workspace-resume/weekly-reports/`
- **结构**
- `2025-XX/` - 2025 年历史周报(旧格式 .txt)
- `2026/` - 2026 年起周报(新格式 .md,按周归档)
- `README.md` - 归档说明
- `使用指南.md` - 详细教程
- `快速参考.md` - 快速参考卡片
- `混合方案指南.md` - 混合方案说明
- **命名格式**`YYYY-Www-周报.md`(如 `2026-W31-周报.md`
## MySQL 周报数据中枢(2026-08-27 建立)
方案 A**SQLite 做本地归档,MySQL resume 库做统一数据中枢**(供月度/年度总结、OKR 分析)。
- **MySQL 连接**`127.0.0.1:3306`,用户 `root`,库 `resume`,密码存 `.env` 键 `MYSQL_PWD`
- **三张周报表**(在 `resume` 库):
- `weekly_reports` — 主表(year、week_number、project、start_date/end_date、main_task、has_problems
- `weekly_report_daily` — 每日明细(report_id、day_of_week、work_date、work_items
- `weekly_report_problems` — 问题记录(report_id、problem_description、status
- **写入入口**
- `send_to_drafts()` 默认同步(`sync_to_mysql`),`--no-mysql` 跳过
- 迁移补写:`weekly-reports/migrate_to_mysql.py`SQLite → MySQL 全量,`--dry-run` 预览)
- **月度/年度总结查询示例**
```sql
-- 月度
SELECT * FROM resume.weekly_reports WHERE start_date BETWEEN '2026-07-01' AND '2026-07-31';
-- 年度
SELECT week_number, main_task FROM resume.weekly_reports WHERE year=2026 ORDER BY week_number;
```
- **注意**:周报表在业务库 resume 中,勿与简历业务表(resumes、company_* 等)混用;二者用途不同
## 周报邮件 eml 解析归档工具(2026-08-27 添加)
用于从下载的钉邮周报 eml 文件批量补全归档缺失周报。
- **eml 所在目录**`/home/yangxuan/.openclaw/media/inbound/`(附件上传后自动落盘)
- **解析脚本**`weekly-reports/parse_eml_to_md.py` —— 读取 inbound 下所有 .eml,解码 base64 正文,生成标准格式 `2026/2026-Www-周报.md`
- **入库脚本**`weekly-reports/import_md_to_db.py` —— 读生成的 Markdown 重建 SQLite 数据(主表+每日明细+问题),自动覆盖旧占位记录
- **用法**
```bash
cd weekly-reports
python3 parse_eml_to_md.py # eml → Markdown
python3 import_md_to_db.py # Markdown → SQLite
```
- **解析逻辑要点**
- 邮件为 multipart,取 text/plain 部分 base64 解码
- 日期行支持 `周一(2026-06-08`/`周一(06-08`/带 📅 emoji 前缀
- 列表项 `*` 与文字可能被拆两行,已处理
- 问题区仅在「存在问题」标题后提取,`无/暂无` 不算问题;`下周计划` 等小标题退出问题区
- 项目名据内容自动判 G5/G6
- **注意**:脚本会**全量重建 2026 年数据库**,覆盖旧占位记录,别在有未归档数据时误跑
## OKR 绩效归档工具(2026-08-27 添加)
用于将研究院-维云智造 OKR 绩效 Excel(杨轩)解析归档到 MySQL resume 库。
- **脚本**`okr/parse_okr_to_mysql.py`
- **Excel 位置**`/home/yangxuan/.openclaw/media/inbound/*OKR*.xlsx`(或命令行 `--file` 指定路径)
- **用法**
```bash
cd okr
python3 parse_okr_to_mysql.py --month 202601 # 归档指定月
python3 parse_okr_to_mysql.py --file <xlsx> --dry-run # 指定文件+预览不写入
```
- **表**MySQL resume 库):`okr_monthly_records`(主)+ `okr_objectives`(目标明细)
- **支持新旧两种模板**(自动识别):
- 旧模板(202601 等):多 sheet,每个 sheet 一个考核月;表头行4,目标行5起 6 项,月度评价在 J12/B12
- 新模板(8月起):单 sheet `OKR考核`;表头行5-6,目标行8起(跳过行7示例)5 项,B序号/C任务/D关键结果/E完成/G评分/I权重/J得分;人员信息在 B3;跨月周期取考核期末(如 7月27日-8月27日→202608);月度评价字段上级可能未填(NULL)
- **Excel 结构(旧模板)**:一个文件多 sheet202511/202512/202601/...),每个 sheet 一个考核月## 技能
## 技能
- **周报技能**`skills/weekly-report-g5/SKILL.md`
@@ -0,0 +1,61 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
### MySQL 连接
- **默认 → VPS**: `101.34.227.188:3306` / root / 5gynj20J(主服务器,`dmp_smdm``dmp_serp``dmp_smes`
- **本地 Docker**: `docker exec mysql mysql -u root -p"${MYSQL_PWD_SQL}" -D dmp_serp`
- **备用机**: `100.115.195.191:3306` / root / 5gynj20J(库:dmp_smdm、dmp_serp、dmp_smes 等)
- **准生产(只读)** → `100.115.195.188:50036`(转发)→ `47.99.209.185:50036` / witsoftd / o2byaCkBvF1Y8S2L
- MySQL 8.0.36,只读权限,准生产环境
- 连接命令:`mysql -h 100.115.195.188 -P 50036 -u witsoftd -p"${MYSQL_PWD_WIT}"`
- **密码环境变量**: `MYSQL_PWD_SQL=5gynj20J`(来自 .env
- ⚠️ **优先使用本地 mysql 客户端直接连接**,不要每次都用 `docker exec`
- ⚠️ **默认数据库连接串**: `mysql -h 101.34.227.188 -u root -p"${MYSQL_PWD_SQL}"`
## 🔴 红线(不可违反)
1. **🚫 绝不直接执行 SQL 操作数据库!**
- 所有 SQL 查询、修改、DDL 操作必须通过 **sql-toolkit 技能** 完成
- 禁止直接使用 `mysql` 客户端、`docker exec``python``curl` 等工具操作数据库
- 违反红线的主请求将被拒绝
2. **Opencode 配置:**
- 默认 provider: `newapi`http://100.115.195.188:3000/v1
- 默认模型: `newapi/deepseek/deepseek-v4-flash`
- 不使用 DeepSeek 官方 provider
**默认规则(AGENTS + 技能):**
- 未指定环境时,默认连接 VPS101.34.227.188
- 脚本表名必须带库前缀(`dmp_xxx.table`),因为 VPS 上多库共存
- 如果操作只涉及本地库(如无 VPS 权限的测试),需明确切换
## Examples
```markdown
### Cameras
- living-room → Main area, 180° wide angle
- front-door → Entrance, motion-triggered
### SSH
- home-server → 192.168.1.100, user: admin
### TTS
- Preferred voice: "Nova" (warm, slightly British)
- Default speaker: Kitchen HomePod
```
## Why Separate?
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
---
Add whatever helps you do your job. This is your cheat sheet.
## Related
- [Agent workspace](/concepts/agent-workspace)
@@ -0,0 +1,33 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
## Examples
```markdown
### Cameras
- living-room → Main area, 180° wide angle
- front-door → Entrance, motion-triggered
### SSH
- home-server → 192.168.1.100, user: admin
### TTS
- Preferred voice: "Nova" (warm, slightly British)
- Default speaker: Kitchen HomePod
```
## Why Separate?
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
---
Add whatever helps you do your job. This is your cheat sheet.
## Related
- [Agent workspace](/concepts/agent-workspace)
@@ -0,0 +1,33 @@
# TOOLS.md - Local Notes
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup: camera names and locations, SSH hosts and aliases, preferred TTS voices, speaker/room names, device nicknames, anything environment-specific.
## Examples
```markdown
### Cameras
- living-room → Main area, 180° wide angle
- front-door → Entrance, motion-triggered
### SSH
- home-server → 192.168.1.100, user: admin
### TTS
- Preferred voice: "Nova" (warm, slightly British)
- Default speaker: Kitchen HomePod
```
## Why Separate?
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
---
Add whatever helps you do your job. This is your cheat sheet.
## Related
- [Agent workspace](/concepts/agent-workspace)
+1613 -273
View File
File diff suppressed because one or more lines are too long
+721 -250
View File
File diff suppressed because it is too large Load Diff
+496 -20
View File
@@ -17,7 +17,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
# Root command
if ($commandPath -eq "") {
$completions = @('completion','crestodian','setup','onboard','configure','config','backup','migrate','doctor','dashboard','reset','uninstall','message','mcp','transcripts','agent','agents','status','health','sessions','commitments','tasks','acp','gateway','daemon','logs','system','models','infer','approvals','exec-policy','nodes','devices','node','sandbox','tui','cron','dns','docs','proxy','hooks','webhooks','qr','clawbot','pairing','plugins','channels','directory','security','secrets','skills','update','--version','--container','--dev','--profile','--log-level','--no-color')
$completions = @('completion','crestodian','setup','onboard','configure','config','backup','migrate','doctor','dashboard','reset','uninstall','message','mcp','transcripts','agent','agents','audit','status','health','sessions','commitments','tasks','acp','gateway','daemon','logs','system','models','promos','infer','capability','approvals','exec-approvals','exec-policy','nodes','devices','node','sandbox','worktrees','attach','tui','terminal','chat','cron','dns','docs','proxy','hooks','webhooks','qr','clawbot','pairing','plugins','channels','directory','security','secrets','skills','update','--version','--container','--dev','--profile','--log-level','--no-color')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -39,14 +39,14 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'setup') {
$completions = @('--workspace','--wizard','--non-interactive','--accept-risk','--mode','--import-from','--import-source','--import-secrets','--remote-url','--remote-token')
$completions = @('--workspace','--wizard','--baseline','--reset','--reset-scope','--non-interactive','--classic','--accept-risk','--flow','--mode','--auth-choice','--token-provider','--token','--token-profile-id','--token-expires-in','--secret-input-mode','--cloudflare-ai-gateway-account-id','--cloudflare-ai-gateway-gateway-id','--alibaba-model-studio-api-key','--anthropic-api-key','--byteplus-api-key','--clawrouter-api-key','--cohere-api-key','--comfy-api-key','--fal-api-key','--github-copilot-token','--gemini-api-key','--huggingface-api-key','--litellm-api-key','--lmstudio-api-key','--meta-api-key','--minimax-api-key','--mistral-api-key','--novita-api-key','--nvidia-api-key','--ollama-cloud-api-key','--openai-api-key','--opencode-zen-api-key','--opencode-go-api-key','--openrouter-api-key','--runway-api-key','--synthetic-api-key','--together-api-key','--volcengine-api-key','--vydra-api-key','--xai-api-key','--xiaomi-api-key','--xiaomi-token-plan-api-key','--deepseek-api-key','--arceeai-api-key','--cerebras-api-key','--chutes-api-key','--cloudflare-ai-gateway-api-key','--deepinfra-api-key','--featherless-api-key','--gmi-api-key','--longcat-api-key','--groq-api-key','--kilocode-api-key','--kimi-code-api-key','--pixverse-api-key','--qianfan-api-key','--modelstudio-standard-api-key-cn','--modelstudio-standard-api-key','--modelstudio-api-key-cn','--modelstudio-api-key','--qwen-oauth-token','--fireworks-api-key','--moonshot-api-key','--tokenhub-api-key','--tokenplan-api-key','--venice-api-key','--ai-gateway-api-key','--zai-api-key','--stepfun-api-key','--custom-base-url','--custom-api-key','--custom-model-id','--custom-provider-id','--custom-compatibility','--custom-image-input','--custom-text-input','--gateway-port','--gateway-bind','--gateway-auth','--gateway-token','--gateway-token-ref-env','--gateway-password','--tailscale','--tailscale-reset-on-exit','--install-daemon','--no-install-daemon','--skip-daemon','--daemon-runtime','--skip-channels','--skip-skills','--skip-bootstrap','--skip-search','--skip-health','--skip-ui','--suppress-gateway-token-output','--skip-hooks','--node-manager','--import-from','--import-source','--import-secrets','--remote-url','--remote-token','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'onboard') {
$completions = @('--workspace','--reset','--reset-scope','--non-interactive','--modern','--accept-risk','--flow','--mode','--auth-choice','--token-provider','--token','--token-profile-id','--token-expires-in','--secret-input-mode','--cloudflare-ai-gateway-account-id','--cloudflare-ai-gateway-gateway-id','--alibaba-model-studio-api-key','--anthropic-api-key','--byteplus-api-key','--cohere-api-key','--comfy-api-key','--fal-api-key','--github-copilot-token','--gemini-api-key','--huggingface-api-key','--litellm-api-key','--lmstudio-api-key','--minimax-api-key','--mistral-api-key','--novita-api-key','--nvidia-api-key','--ollama-cloud-api-key','--openai-api-key','--opencode-zen-api-key','--opencode-go-api-key','--openrouter-api-key','--runway-api-key','--synthetic-api-key','--together-api-key','--volcengine-api-key','--vydra-api-key','--xai-api-key','--xiaomi-api-key','--xiaomi-token-plan-api-key','--deepseek-api-key','--arceeai-api-key','--cerebras-api-key','--chutes-api-key','--cloudflare-ai-gateway-api-key','--deepinfra-api-key','--gmi-api-key','--groq-api-key','--kilocode-api-key','--kimi-code-api-key','--pixverse-api-key','--qianfan-api-key','--modelstudio-standard-api-key-cn','--modelstudio-standard-api-key','--modelstudio-api-key-cn','--modelstudio-api-key','--qwen-oauth-token','--fireworks-api-key','--moonshot-api-key','--tokenhub-api-key','--venice-api-key','--ai-gateway-api-key','--zai-api-key','--stepfun-api-key','--custom-base-url','--custom-api-key','--custom-model-id','--custom-provider-id','--custom-compatibility','--custom-image-input','--custom-text-input','--gateway-port','--gateway-bind','--gateway-auth','--gateway-token','--gateway-token-ref-env','--gateway-password','--remote-url','--remote-token','--tailscale','--tailscale-reset-on-exit','--install-daemon','--no-install-daemon','--skip-daemon','--daemon-runtime','--skip-channels','--skip-skills','--skip-bootstrap','--skip-search','--skip-health','--skip-ui','--suppress-gateway-token-output','--skip-hooks','--node-manager','--import-from','--import-source','--import-secrets','--json')
$completions = @('--workspace','--reset','--reset-scope','--non-interactive','--modern','--classic','--accept-risk','--flow','--mode','--auth-choice','--token-provider','--token','--token-profile-id','--token-expires-in','--secret-input-mode','--cloudflare-ai-gateway-account-id','--cloudflare-ai-gateway-gateway-id','--alibaba-model-studio-api-key','--anthropic-api-key','--byteplus-api-key','--clawrouter-api-key','--cohere-api-key','--comfy-api-key','--fal-api-key','--github-copilot-token','--gemini-api-key','--huggingface-api-key','--litellm-api-key','--lmstudio-api-key','--meta-api-key','--minimax-api-key','--mistral-api-key','--novita-api-key','--nvidia-api-key','--ollama-cloud-api-key','--openai-api-key','--opencode-zen-api-key','--opencode-go-api-key','--openrouter-api-key','--runway-api-key','--synthetic-api-key','--together-api-key','--volcengine-api-key','--vydra-api-key','--xai-api-key','--xiaomi-api-key','--xiaomi-token-plan-api-key','--deepseek-api-key','--arceeai-api-key','--cerebras-api-key','--chutes-api-key','--cloudflare-ai-gateway-api-key','--deepinfra-api-key','--featherless-api-key','--gmi-api-key','--longcat-api-key','--groq-api-key','--kilocode-api-key','--kimi-code-api-key','--pixverse-api-key','--qianfan-api-key','--modelstudio-standard-api-key-cn','--modelstudio-standard-api-key','--modelstudio-api-key-cn','--modelstudio-api-key','--qwen-oauth-token','--fireworks-api-key','--moonshot-api-key','--tokenhub-api-key','--tokenplan-api-key','--venice-api-key','--ai-gateway-api-key','--zai-api-key','--stepfun-api-key','--custom-base-url','--custom-api-key','--custom-model-id','--custom-provider-id','--custom-compatibility','--custom-image-input','--custom-text-input','--gateway-port','--gateway-bind','--gateway-auth','--gateway-token','--gateway-token-ref-env','--gateway-password','--remote-url','--remote-token','--tailscale','--tailscale-reset-on-exit','--install-daemon','--no-install-daemon','--skip-daemon','--daemon-runtime','--skip-channels','--skip-skills','--skip-bootstrap','--skip-search','--skip-health','--skip-ui','--suppress-gateway-token-output','--skip-hooks','--node-manager','--import-from','--import-source','--import-secrets','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -151,7 +151,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'doctor') {
$completions = @('--no-workspace-suggestions','--yes','--repair','--fix','--force','--non-interactive','--generate-gateway-token','--allow-exec','--deep','--lint','--post-upgrade','--json','--severity-min','--skip','--only')
$completions = @('--no-workspace-suggestions','--yes','--repair','--fix','--force','--non-interactive','--generate-gateway-token','--allow-exec','--deep','--lint','--post-upgrade','--json','--severity-min','--all','--skip','--only')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -633,6 +633,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'audit') {
$completions = @('--agent','--session','--run','--kind','--status','--after','--before','--cursor','--limit','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'status') {
$completions = @('--json','--all','--usage','--deep','--timeout','--verbose','--debug')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1144,6 +1151,27 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'promos') {
$completions = @('list','claim')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'promos list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'promos claim') {
$completions = @('--api-key','--set-default')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer') {
$completions = @('list','inspect','model','image','audio','tts','video','web','embedding')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1151,6 +1179,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability') {
$completions = @('list','inspect','model','image','audio','tts','video','web','embedding')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1158,6 +1193,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer inspect') {
$completions = @('--name','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1165,6 +1207,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability inspect') {
$completions = @('--name','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model') {
$completions = @('run','list','inspect','providers','auth')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1172,6 +1221,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model') {
$completions = @('run','list','inspect','providers','auth')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model run') {
$completions = @('--prompt','--file','--model','--thinking','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1179,6 +1235,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model run') {
$completions = @('--prompt','--file','--model','--thinking','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1186,6 +1249,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model inspect') {
$completions = @('--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1193,6 +1263,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model inspect') {
$completions = @('--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1200,6 +1277,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model auth') {
$completions = @('login','logout','status')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1207,6 +1291,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model auth') {
$completions = @('login','logout','status')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model auth login') {
$completions = @('--provider','--method')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1214,6 +1305,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model auth login') {
$completions = @('--provider','--method')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model auth logout') {
$completions = @('--provider','--agent','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1221,6 +1319,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model auth logout') {
$completions = @('--provider','--agent','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer model auth status') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1228,6 +1333,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability model auth status') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image') {
$completions = @('generate','edit','describe','describe-many','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1235,6 +1347,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image') {
$completions = @('generate','edit','describe','describe-many','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image generate') {
$completions = @('--prompt','--model','--count','--size','--aspect-ratio','--resolution','--output-format','--background','--openai-background','--openai-moderation','--quality','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1242,6 +1361,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image generate') {
$completions = @('--prompt','--model','--count','--size','--aspect-ratio','--resolution','--output-format','--background','--openai-background','--openai-moderation','--quality','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image edit') {
$completions = @('--file','--prompt','--model','--count','--size','--aspect-ratio','--resolution','--output-format','--background','--openai-background','--openai-moderation','--quality','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1249,6 +1375,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image edit') {
$completions = @('--file','--prompt','--model','--count','--size','--aspect-ratio','--resolution','--output-format','--background','--openai-background','--openai-moderation','--quality','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image describe') {
$completions = @('--file','--prompt','--model','--timeout-ms','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1256,6 +1389,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image describe') {
$completions = @('--file','--prompt','--model','--timeout-ms','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image describe-many') {
$completions = @('--file','--prompt','--model','--timeout-ms','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1263,6 +1403,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image describe-many') {
$completions = @('--file','--prompt','--model','--timeout-ms','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer image providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1270,6 +1417,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability image providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer audio') {
$completions = @('transcribe','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1277,6 +1431,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability audio') {
$completions = @('transcribe','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer audio transcribe') {
$completions = @('--file','--language','--prompt','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1284,6 +1445,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability audio transcribe') {
$completions = @('--file','--language','--prompt','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer audio providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1291,6 +1459,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability audio providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts') {
$completions = @('convert','voices','providers','personas','status','enable','disable','set-provider','set-persona')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1298,6 +1473,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts') {
$completions = @('convert','voices','providers','personas','status','enable','disable','set-provider','set-persona')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts convert') {
$completions = @('--text','--channel','--voice','--model','--output','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1305,6 +1487,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts convert') {
$completions = @('--text','--channel','--voice','--model','--output','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts voices') {
$completions = @('--provider','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1312,6 +1501,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts voices') {
$completions = @('--provider','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts providers') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1319,6 +1515,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts providers') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts personas') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1326,6 +1529,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts personas') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts status') {
$completions = @('--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1333,6 +1543,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts status') {
$completions = @('--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts enable') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1340,6 +1557,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts enable') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts disable') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1347,6 +1571,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts disable') {
$completions = @('--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts set-provider') {
$completions = @('--provider','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1354,6 +1585,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts set-provider') {
$completions = @('--provider','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer tts set-persona') {
$completions = @('--persona','--off','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1361,6 +1599,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability tts set-persona') {
$completions = @('--persona','--off','--local','--gateway','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer video') {
$completions = @('generate','describe','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1368,6 +1613,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability video') {
$completions = @('generate','describe','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer video generate') {
$completions = @('--prompt','--model','--size','--aspect-ratio','--resolution','--duration','--audio','--watermark','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1375,6 +1627,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability video generate') {
$completions = @('--prompt','--model','--size','--aspect-ratio','--resolution','--duration','--audio','--watermark','--timeout-ms','--output','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer video describe') {
$completions = @('--file','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1382,6 +1641,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability video describe') {
$completions = @('--file','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer video providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1389,6 +1655,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability video providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer web') {
$completions = @('search','fetch','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1396,6 +1669,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability web') {
$completions = @('search','fetch','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer web search') {
$completions = @('--query','--provider','--limit','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1403,6 +1683,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability web search') {
$completions = @('--query','--provider','--limit','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer web fetch') {
$completions = @('--url','--provider','--format','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1410,6 +1697,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability web fetch') {
$completions = @('--url','--provider','--format','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer web providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1417,6 +1711,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability web providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer embedding') {
$completions = @('create','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1424,6 +1725,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability embedding') {
$completions = @('create','providers')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer embedding create') {
$completions = @('--text','--provider','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1431,6 +1739,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability embedding create') {
$completions = @('--text','--provider','--model','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'infer embedding providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1438,6 +1753,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'capability embedding providers') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals') {
$completions = @('get','set','allowlist')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1445,6 +1767,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals') {
$completions = @('get','set','allowlist')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals get') {
$completions = @('--node','--gateway','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1452,6 +1781,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals get') {
$completions = @('--node','--gateway','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals set') {
$completions = @('--node','--gateway','--file','--stdin','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1459,6 +1795,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals set') {
$completions = @('--node','--gateway','--file','--stdin','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals allowlist') {
$completions = @('add','remove')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1466,6 +1809,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals allowlist') {
$completions = @('add','remove')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals allowlist add') {
$completions = @('--node','--gateway','--agent','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1473,6 +1823,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals allowlist add') {
$completions = @('--node','--gateway','--agent','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'approvals allowlist remove') {
$completions = @('--node','--gateway','--agent','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1480,6 +1837,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'exec-approvals allowlist remove') {
$completions = @('--node','--gateway','--agent','--url','--token','--timeout','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'exec-policy') {
$completions = @('show','preset','set')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1712,7 +2076,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'node run') {
$completions = @('--host','--port','--tls','--tls-fingerprint','--node-id','--display-name')
$completions = @('--host','--port','--context-path','--tls','--tls-fingerprint','--node-id','--display-name')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -1726,7 +2090,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'node install') {
$completions = @('--host','--port','--tls','--tls-fingerprint','--node-id','--display-name','--runtime','--force','--json')
$completions = @('--host','--port','--context-path','--tls','--tls-fingerprint','--node-id','--display-name','--runtime','--force','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -1788,6 +2152,55 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'worktrees') {
$completions = @('list','create','remove','restore','gc')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'worktrees list') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'worktrees create') {
$completions = @('--name','--base-ref','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'worktrees remove') {
$completions = @('--force','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'worktrees restore') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'worktrees gc') {
$completions = @('--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'attach') {
$completions = @('--session','--ttl','--bin','--print-config')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'tui') {
$completions = @('--local','--url','--token','--password','--session','--deliver','--thinking','--message','--timeout-ms','--history-limit')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1795,8 +2208,22 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'terminal') {
$completions = @('--local','--url','--token','--password','--session','--deliver','--thinking','--message','--timeout-ms','--history-limit')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'chat') {
$completions = @('--local','--url','--token','--password','--session','--deliver','--thinking','--message','--timeout-ms','--history-limit')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'cron') {
$completions = @('status','list','add','rm','enable','disable','get','show','runs','run','edit')
$completions = @('status','list','add','create','rm','remove','delete','enable','disable','get','show','runs','run','edit')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -1817,7 +2244,14 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'cron add') {
$completions = @('--name','--description','--disabled','--delete-after-run','--keep-after-run','--agent','--session','--session-key','--wake','--at','--every','--cron','--tz','--stagger','--exact','--system-event','--message','--command','--command-argv','--command-cwd','--command-env','--command-input','--thinking','--model','--fallbacks','--timeout-seconds','--no-output-timeout-seconds','--output-max-bytes','--light-context','--tools','--announce','--deliver','--no-deliver','--webhook','--channel','--to','--thread-id','--account','--best-effort-deliver','--json','--url','--token','--timeout','--expect-final')
$completions = @('--name','--declaration-key','--display-name','--description','--disabled','--delete-after-run','--keep-after-run','--agent','--session','--session-key','--wake','--at','--every','--cron','--on-exit','--on-exit-cwd','--tz','--stagger','--exact','--trigger-script','--trigger-once','--system-event','--message','--command','--command-argv','--command-cwd','--command-env','--command-input','--thinking','--model','--fallbacks','--timeout-seconds','--no-output-timeout-seconds','--output-max-bytes','--light-context','--tools','--announce','--deliver','--no-deliver','--webhook','--channel','--to','--thread-id','--account','--best-effort-deliver','--json','--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'cron create') {
$completions = @('--name','--declaration-key','--display-name','--description','--disabled','--delete-after-run','--keep-after-run','--agent','--session','--session-key','--wake','--at','--every','--cron','--on-exit','--on-exit-cwd','--tz','--stagger','--exact','--trigger-script','--trigger-once','--system-event','--message','--command','--command-argv','--command-cwd','--command-env','--command-input','--thinking','--model','--fallbacks','--timeout-seconds','--no-output-timeout-seconds','--output-max-bytes','--light-context','--tools','--announce','--deliver','--no-deliver','--webhook','--channel','--to','--thread-id','--account','--best-effort-deliver','--json','--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -1830,6 +2264,20 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'cron remove') {
$completions = @('--json','--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'cron delete') {
$completions = @('--json','--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'cron enable') {
$completions = @('--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -1873,7 +2321,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'cron edit') {
$completions = @('--name','--description','--enable','--disable','--delete-after-run','--keep-after-run','--session','--agent','--clear-agent','--session-key','--clear-session-key','--wake','--at','--every','--cron','--tz','--stagger','--exact','--system-event','--message','--command','--command-argv','--command-cwd','--command-env','--command-input','--thinking','--model','--fallbacks','--clear-fallbacks','--clear-model','--timeout-seconds','--no-output-timeout-seconds','--output-max-bytes','--light-context','--no-light-context','--tools','--clear-tools','--announce','--deliver','--no-deliver','--webhook','--channel','--to','--thread-id','--account','--clear-channel','--clear-to','--clear-thread-id','--clear-account','--best-effort-deliver','--no-best-effort-deliver','--failure-alert','--no-failure-alert','--failure-alert-after','--failure-alert-channel','--failure-alert-to','--failure-alert-cooldown','--failure-alert-include-skipped','--failure-alert-exclude-skipped','--failure-alert-mode','--failure-alert-account-id','--url','--token','--timeout','--expect-final')
$completions = @('--name','--description','--enable','--disable','--delete-after-run','--keep-after-run','--session','--agent','--clear-agent','--session-key','--clear-session-key','--wake','--at','--every','--cron','--tz','--stagger','--exact','--trigger-script','--trigger-once','--clear-trigger','--system-event','--message','--command','--command-argv','--command-cwd','--command-env','--command-input','--thinking','--clear-thinking','--model','--fallbacks','--clear-fallbacks','--clear-model','--timeout-seconds','--no-output-timeout-seconds','--output-max-bytes','--light-context','--no-light-context','--tools','--clear-tools','--announce','--deliver','--no-deliver','--webhook','--channel','--to','--thread-id','--account','--clear-channel','--clear-to','--clear-thread-id','--clear-account','--best-effort-deliver','--no-best-effort-deliver','--failure-alert','--no-failure-alert','--failure-alert-after','--failure-alert-channel','--failure-alert-to','--failure-alert-cooldown','--failure-alert-include-skipped','--failure-alert-exclude-skipped','--failure-alert-mode','--failure-alert-account-id','--url','--token','--timeout','--expect-final')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2062,7 +2510,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'plugins') {
$completions = @('list','search','inspect','enable','disable','uninstall','install','update','registry','doctor','build','validate','init','marketplace')
$completions = @('list','search','inspect','info','enable','disable','uninstall','install','update','registry','doctor','build','validate','init','marketplace')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2089,6 +2537,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'plugins info') {
$completions = @('--all','--runtime','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'plugins uninstall') {
$completions = @('--keep-files','--keep-config','--force','--dry-run')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -2097,14 +2552,14 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'plugins install') {
$completions = @('--link','--force','--pin','--dangerously-force-unsafe-install','--marketplace')
$completions = @('--link','--force','--pin','--dangerously-force-unsafe-install','--acknowledge-clawhub-risk','--marketplace')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'plugins update') {
$completions = @('--all','--dry-run','--dangerously-force-unsafe-install')
$completions = @('--all','--dry-run','--dangerously-force-unsafe-install','--acknowledge-clawhub-risk')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2132,14 +2587,28 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'plugins init') {
$completions = @('--directory','--name','--force')
$completions = @('--directory','--name','--type','--force')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'plugins marketplace') {
$completions = @('list')
$completions = @('entries','refresh','list')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'plugins marketplace entries') {
$completions = @('--feed-profile','--feed-url','--offline','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'plugins marketplace refresh') {
$completions = @('--feed-profile','--feed-url','--expected-sha256','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2321,7 +2790,7 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'skills') {
$completions = @('search','install','update','verify','workshop','list','info','check','--agent')
$completions = @('search','install','update','verify','curator','workshop','list','info','check','--agent')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2335,14 +2804,14 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'skills install') {
$completions = @('--version','--force','--force-install','--global','--agent','--as')
$completions = @('--version','--force','--force-install','--acknowledge-clawhub-risk','--global','--agent','--as')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'skills update') {
$completions = @('--all','--force-install','--global','--agent')
$completions = @('--all','--force-install','--acknowledge-clawhub-risk','--global','--agent')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
@@ -2355,6 +2824,13 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
}
if ($commandPath -eq 'skills curator') {
$completions = @('status','pin','unpin','restore','--json')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'skills workshop') {
$completions = @('list','inspect','propose-create','propose-update','revise','apply','reject','quarantine','--agent')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
@@ -2440,21 +2916,21 @@ Register-ArgumentCompleter -Native -CommandName openclaw -ScriptBlock {
}
if ($commandPath -eq 'update') {
$completions = @('repair','finalize','wizard','status','--json','--no-restart','--dry-run','--channel','--tag','--timeout','--yes')
$completions = @('repair','finalize','wizard','status','--json','--no-restart','--dry-run','--channel','--tag','--timeout','--yes','--acknowledge-clawhub-risk')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'update repair') {
$completions = @('--json','--channel','--timeout','--yes','--no-restart')
$completions = @('--json','--channel','--timeout','--yes','--acknowledge-clawhub-risk','--no-restart')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
}
if ($commandPath -eq 'update finalize') {
$completions = @('--json','--channel','--timeout','--yes','--no-restart')
$completions = @('--json','--channel','--timeout','--yes','--acknowledge-clawhub-risk','--no-restart')
$completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
}
+334 -42
View File
@@ -12,7 +12,7 @@ _openclaw_root_completion() {
"--profile[Use a named profile (isolates OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH under ~/.openclaw-<name>)]" \
"--log-level[Global log level override for file + console (silent|fatal|error|warn|info|debug|trace)]" \
"--no-color[Disable ANSI colors]" \
"1: :_values 'command' 'completion[Generate shell completion script]' 'crestodian[Open the ring-zero setup and repair helper]' 'setup[Create baseline config/workspace files; use --wizard for full onboarding]' 'onboard[Guided setup for auth, models, Gateway, workspace, channels, and skills]' 'configure[Interactive configuration for credentials, channels, gateway, and agent defaults]' 'config[Non-interactive config helpers (get/set/patch/unset/file/schema/validate). Run without subcommand for guided setup.]' 'backup[Create and verify local backup archives for OpenClaw state]' 'migrate[Import state from another agent system]' 'doctor[Health checks + quick fixes for the gateway and channels]' 'dashboard[Open the Control UI with your current token]' 'reset[Reset local config/state (keeps the CLI installed)]' 'uninstall[Uninstall the gateway service + local data (CLI remains)]' 'message[Send, read, and manage messages and channel actions]' 'mcp[Manage OpenClaw mcp.servers config and channel bridge]' 'transcripts[Inspect stored transcripts]' 'agent[Run an agent turn via the Gateway (use --local for embedded)]' 'agents[Manage isolated agents (workspaces + auth + routing)]' 'status[Show channel health and recent session recipients]' 'health[Fetch health from the running gateway]' 'sessions[List stored conversation sessions]' 'commitments[List and manage inferred follow-up commitments]' 'tasks[Inspect durable background tasks and TaskFlow state]' 'acp[Run an ACP bridge backed by the Gateway]' 'gateway[Run, inspect, and query the WebSocket Gateway]' 'daemon[Manage the Gateway service (launchd/systemd/schtasks)]' 'logs[Tail gateway file logs via RPC]' 'system[System tools (events, heartbeat, presence)]' 'models[Model discovery, scanning, and configuration]' 'infer[Run provider-backed inference commands through a stable CLI surface]' 'approvals[Manage exec approvals (gateway or node host)]' 'exec-policy[Show or synchronize requested exec policy with host approvals]' 'nodes[Manage gateway-owned nodes (pairing, status, invoke, and media)]' 'devices[Device pairing and auth tokens]' 'node[Run and manage the headless node host service]' 'sandbox[Manage sandbox containers (Docker-based agent isolation)]' 'tui[Open a terminal UI connected to the Gateway]' 'cron[Manage cron jobs (via Gateway)]' 'dns[DNS helpers for wide-area discovery (Tailscale + CoreDNS)]' 'docs[Search the live OpenClaw docs]' 'proxy[Run the OpenClaw debug proxy and inspect captured traffic]' 'hooks[Manage internal agent hooks]' 'webhooks[Webhook helpers and integrations]' 'qr[Generate a mobile pairing QR code and setup code]' 'clawbot[Legacy clawbot command aliases]' 'pairing[Secure DM pairing (approve inbound requests)]' 'plugins[Manage OpenClaw plugins and extensions]' 'channels[Manage connected chat channels and accounts]' 'directory[Lookup contact and group IDs (self, peers, groups) for supported chat channels]' 'security[Audit local config and state for common security foot-guns]' 'secrets[Secrets runtime controls]' 'skills[List and inspect available skills]' 'update[Update OpenClaw and inspect update channel status]'" \
"1: :_values 'command' 'completion[Generate shell completion script]' 'crestodian[Open the ring-zero setup and repair helper]' 'setup[Alias for openclaw onboard]' 'onboard[Guided setup for auth, models, Gateway, workspace, channels, and skills]' 'configure[Interactive configuration for credentials, channels, gateway, and agent defaults]' 'config[Non-interactive config helpers (get/set/patch/unset/file/schema/validate). Run without subcommand for guided setup.]' 'backup[Create and verify local backup archives for OpenClaw state]' 'migrate[Import state from another agent system]' 'doctor[Health checks + quick fixes for the gateway and channels]' 'dashboard[Open the Control UI with your current token]' 'reset[Reset local config/state (keeps the CLI installed)]' 'uninstall[Uninstall the gateway service + local data (CLI remains)]' 'message[Send, read, and manage messages and channel actions]' 'mcp[Manage OpenClaw mcp.servers config and channel bridge]' 'transcripts[Inspect stored transcripts]' 'agent[Run an agent turn via the Gateway (use --local for embedded)]' 'agents[Manage isolated agents (workspaces + auth + routing)]' 'audit[Inspect metadata-only agent run and tool action records]' 'status[Show channel health and recent session recipients]' 'health[Fetch health from the running gateway]' 'sessions[List stored conversation sessions]' 'commitments[List and manage inferred follow-up commitments]' 'tasks[Inspect durable background tasks and TaskFlow state]' 'acp[Run an ACP bridge backed by the Gateway]' 'gateway[Run, inspect, and query the WebSocket Gateway]' 'daemon[Manage the Gateway service (launchd/systemd/schtasks)]' 'logs[Tail gateway file logs via RPC]' 'system[System tools (events, heartbeat, presence)]' 'models[Model discovery, scanning, and configuration]' 'promos[Discover and claim promotional model offers from ClawHub]' 'infer[Run provider-backed inference commands through a stable CLI surface]' 'capability[Run provider-backed inference commands through a stable CLI surface]' 'approvals[Manage exec approvals (gateway or node host)]' 'exec-approvals[Manage exec approvals (gateway or node host)]' 'exec-policy[Show or synchronize requested exec policy with host approvals]' 'nodes[Manage gateway-owned nodes (pairing, status, invoke, and media)]' 'devices[Device pairing and auth tokens]' 'node[Run and manage the headless node host service]' 'sandbox[Manage sandbox containers (Docker-based agent isolation)]' 'worktrees[Create, inspect, restore, and clean up managed worktrees]' 'attach[Attach Claude Code to a gateway session with scoped MCP tools]' 'tui[Open a terminal UI connected to the Gateway]' 'terminal[Open a terminal UI connected to the Gateway]' 'chat[Open a terminal UI connected to the Gateway]' 'cron[Manage cron jobs (via Gateway)]' 'dns[DNS helpers for wide-area discovery (Tailscale + CoreDNS)]' 'docs[Search the live OpenClaw docs]' 'proxy[Run the OpenClaw debug proxy and inspect captured traffic]' 'hooks[Manage internal agent hooks]' 'webhooks[Webhook helpers and integrations]' 'qr[Generate a mobile pairing QR code and setup code]' 'clawbot[Legacy clawbot command aliases]' 'pairing[Secure DM pairing (approve inbound requests)]' 'plugins[Manage OpenClaw plugins and extensions]' 'channels[Manage connected chat channels and accounts]' 'directory[Lookup contact and group IDs (self, peers, groups) for supported chat channels]' 'security[Audit local config and state for common security foot-guns]' 'secrets[Secrets runtime controls]' 'skills[List and inspect available skills]' 'update[Update OpenClaw and inspect update channel status]'" \
"*::arg:->args"
case $state in
@@ -35,6 +35,7 @@ _openclaw_root_completion() {
(transcripts) _openclaw_transcripts ;;
(agent) _openclaw_agent ;;
(agents) _openclaw_agents ;;
(audit) _openclaw_audit ;;
(status) _openclaw_status ;;
(health) _openclaw_health ;;
(sessions) _openclaw_sessions ;;
@@ -46,14 +47,17 @@ _openclaw_root_completion() {
(logs) _openclaw_logs ;;
(system) _openclaw_system ;;
(models) _openclaw_models ;;
(infer) _openclaw_infer ;;
(approvals) _openclaw_approvals ;;
(promos) _openclaw_promos ;;
(infer|capability) _openclaw_infer ;;
(approvals|exec-approvals) _openclaw_approvals ;;
(exec-policy) _openclaw_exec_policy ;;
(nodes) _openclaw_nodes ;;
(devices) _openclaw_devices ;;
(node) _openclaw_node ;;
(sandbox) _openclaw_sandbox ;;
(tui) _openclaw_tui ;;
(worktrees) _openclaw_worktrees ;;
(attach) _openclaw_attach ;;
(tui|terminal|chat) _openclaw_tui ;;
(cron) _openclaw_cron ;;
(dns) _openclaw_dns ;;
(docs) _openclaw_docs ;;
@@ -95,27 +99,15 @@ _openclaw_setup() {
_arguments -C \
"--workspace[Agent workspace directory (default: ~/.openclaw/workspace; stored as agents.defaults.workspace)]" \
"--wizard[Run interactive onboarding]" \
"--non-interactive[Run onboarding without prompts]" \
"--accept-risk[Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)]" \
"--mode[Onboard mode: local|remote]" \
"--import-from[Migration provider to run during onboarding]" \
"--import-source[Source agent home for --import-from]" \
"--import-secrets[Import supported secrets during onboarding migration]" \
"--remote-url[Remote Gateway WebSocket URL]" \
"--remote-token[Remote Gateway token (optional)]"
}
_openclaw_onboard() {
_arguments -C \
"--workspace[Agent workspace directory (default: ~/.openclaw/workspace)]" \
"--reset[Reset config + credentials + sessions before running onboard (workspace only with --reset-scope full)]" \
"--baseline[Create baseline config/workspace/session folders without onboarding]" \
"--reset[Reset config + credentials + sessions before running onboarding (workspace only with --reset-scope full)]" \
"--reset-scope[Reset scope: config|config+creds+sessions|full]" \
"--non-interactive[Run without prompts]" \
"--modern[Use the conversational setup/repair assistant]" \
"--non-interactive[Run onboarding without prompts]" \
"--classic[Use the classic multi-step setup wizard]" \
"--accept-risk[Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)]" \
"--flow[Onboard flow: quickstart|advanced|manual|import]" \
"--mode[Onboard mode: local|remote]" \
"--auth-choice[Auth: custom-api-key|skip|claude-cli|apiKey|anthropic-cli|setup-token|arceeai-api-key|byteplus-api-key|cerebras-api-key|openai-device-code|openai|chutes|chutes-api-key|cloudflare-ai-gateway-api-key|zai-cn|codex|qwen-api-key-cn|qwen-api-key|zai-coding-cn|zai-coding-global|cohere-api-key|copilot-proxy|deepinfra-api-key|deepseek-api-key|fireworks-api-key|google-gemini-cli|github-copilot|zai-global|gmi-api-key|gemini-api-key|google-vertex-api-key|groq-api-key|huggingface-api-key|kilocode-api-key|kimi-code-api-key|litellm-api-key|lmstudio|microsoft-foundry-apikey|microsoft-foundry-entra|minimax-cn-api|minimax-global-api|minimax-cn-oauth|minimax-global-oauth|mistral-api-key|moonshot-api-key|moonshot-api-key-cn|novita-api-key|nvidia-api-key|ollama|ollama-cloud|openai-api-key|opencode-go|opencode-zen|arceeai-openrouter|openrouter-api-key|openrouter-oauth|qianfan-api-key|qwen-oauth|sglang|qwen-standard-api-key-cn|qwen-standard-api-key|stepfun-standard-api-key-cn|stepfun-standard-api-key-intl|stepfun-plan-api-key-cn|stepfun-plan-api-key-intl|synthetic-api-key|tokenhub-api-key|together-api-key|venice-api-key|ai-gateway-api-key|vllm|volcengine-api-key|xai-api-key|xai-device-code|xai-oauth|xiaomi-api-key|xiaomi-token-plan-cn|xiaomi-token-plan-ams|xiaomi-token-plan-sgp|zai-api-key]" \
"--auth-choice[Auth: custom-api-key|skip|claude-cli|apiKey|anthropic-cli|setup-token|arceeai-api-key|byteplus-api-key|cerebras-api-key|openai-device-code|openai|chutes|chutes-api-key|clawrouter-api-key|cloudflare-ai-gateway-api-key|zai-cn|codex|qwen-api-key-cn|qwen-api-key|zai-coding-cn|zai-coding-global|cohere-api-key|copilot-proxy|deepinfra-api-key|deepseek-api-key|featherless-api-key|fireworks-api-key|google-gemini-cli|github-copilot|zai-global|gmi-api-key|gemini-api-key|google-vertex-api-key|groq-api-key|huggingface-api-key|kilocode-api-key|kimi-code-api-key|litellm-api-key|lmstudio|longcat-api-key|meta-api-key|microsoft-foundry-apikey|microsoft-foundry-entra|minimax-cn-api|minimax-global-api|minimax-cn-oauth|minimax-global-oauth|mistral-api-key|moonshot-api-key|moonshot-api-key-cn|novita-api-key|nvidia-api-key|ollama|ollama-cloud|openai-api-key|opencode-go|opencode-zen|arceeai-openrouter|openrouter-api-key|openrouter-oauth|qianfan-api-key|qwen-oauth|sglang|qwen-standard-api-key-cn|qwen-standard-api-key|stepfun-standard-api-key-cn|stepfun-standard-api-key-intl|stepfun-plan-api-key-cn|stepfun-plan-api-key-intl|synthetic-api-key|tokenhub-api-key|tokenplan-api-key|together-api-key|venice-api-key|ai-gateway-api-key|vllm|volcengine-api-key|xai-api-key|xai-device-code|xai-oauth|xiaomi-api-key|xiaomi-token-plan-cn|xiaomi-token-plan-ams|xiaomi-token-plan-sgp|zai-api-key]" \
"--token-provider[Token provider id (non-interactive; used with --auth-choice token)]" \
"--token[Token value (non-interactive; used with --auth-choice token)]" \
"--token-profile-id[Auth profile id (non-interactive; default: <provider>:manual)]" \
@@ -126,6 +118,7 @@ _openclaw_onboard() {
"--alibaba-model-studio-api-key[Alibaba Model Studio API key]" \
"--anthropic-api-key[Anthropic API key]" \
"--byteplus-api-key[BytePlus API key]" \
"--clawrouter-api-key[ClawRouter proxy key]" \
"--cohere-api-key[Cohere API key]" \
"--comfy-api-key[Comfy Cloud API key]" \
"--fal-api-key[fal API key]" \
@@ -134,6 +127,7 @@ _openclaw_onboard() {
"--huggingface-api-key[Hugging Face API key (HF token)]" \
"--litellm-api-key[LiteLLM API key]" \
"--lmstudio-api-key[LM Studio API key]" \
"--meta-api-key[Meta API key]" \
"--minimax-api-key[MiniMax API key]" \
"--mistral-api-key[Mistral API key]" \
"--novita-api-key[NovitaAI API key]" \
@@ -157,7 +151,9 @@ _openclaw_onboard() {
"--chutes-api-key[Chutes API key]" \
"--cloudflare-ai-gateway-api-key[Cloudflare AI Gateway API key]" \
"--deepinfra-api-key[DeepInfra API key]" \
"--featherless-api-key[Featherless AI API key]" \
"--gmi-api-key[GMI Cloud API key]" \
"--longcat-api-key[LongCat API key]" \
"--groq-api-key[Groq API key]" \
"--kilocode-api-key[Kilo Gateway API key]" \
"--kimi-code-api-key[Kimi Code API key (subscription)]" \
@@ -171,6 +167,119 @@ _openclaw_onboard() {
"--fireworks-api-key[Fireworks API key]" \
"--moonshot-api-key[Moonshot API key]" \
"--tokenhub-api-key[Tencent TokenHub API key]" \
"--tokenplan-api-key[Tencent TokenPlan API key]" \
"--venice-api-key[Venice API key]" \
"--ai-gateway-api-key[Vercel AI Gateway API key]" \
"--zai-api-key[Z.AI API key]" \
"--stepfun-api-key[StepFun API key]" \
"--custom-base-url[Custom provider base URL]" \
"--custom-api-key[Custom provider API key (optional)]" \
"--custom-model-id[Custom provider model ID]" \
"--custom-provider-id[Custom provider ID (optional; auto-derived by default)]" \
"--custom-compatibility[Custom provider API compatibility: openai|openai-responses|anthropic (default: openai)]" \
"--custom-image-input[Mark the custom provider model as image-capable]" \
"--custom-text-input[Mark the custom provider model as text-only]" \
"--gateway-port[Gateway port]" \
"--gateway-bind[Gateway bind: loopback|tailnet|lan|auto|custom]" \
"--gateway-auth[Gateway auth: token|password]" \
"--gateway-token[Gateway token (token auth)]" \
"--gateway-token-ref-env[Gateway token SecretRef env var name (token auth; e.g. OPENCLAW_GATEWAY_TOKEN)]" \
"--gateway-password[Gateway password (password auth)]" \
"--tailscale[Tailscale: off|serve|funnel]" \
"--tailscale-reset-on-exit[Reset tailscale serve/funnel on exit]" \
"--install-daemon[Install gateway service]" \
"--no-install-daemon[Skip gateway service install]" \
"--skip-daemon[Skip gateway service install]" \
"--daemon-runtime[Daemon runtime: node]" \
"--skip-channels[Skip channel setup]" \
"--skip-skills[Skip skills setup]" \
"--skip-bootstrap[Skip creating default agent workspace files]" \
"--skip-search[Skip search provider setup]" \
"--skip-health[Skip health check]" \
"--skip-ui[Skip Control UI/TUI launch]" \
"--suppress-gateway-token-output[Suppress token-bearing Gateway/UI output]" \
"--skip-hooks[Accepted for onboard compatibility; hooks setup is skipped]" \
"--node-manager[Node manager for skills: npm|pnpm|bun]" \
"--import-from[Migration provider to run during onboarding]" \
"--import-source[Source agent home for --import-from]" \
"--import-secrets[Import supported secrets during onboarding migration]" \
"--remote-url[Remote Gateway WebSocket URL]" \
"--remote-token[Remote Gateway token (optional)]" \
"--json[Output JSON summary]"
}
_openclaw_onboard() {
_arguments -C \
"--workspace[Agent workspace directory (default: ~/.openclaw/workspace)]" \
"--reset[Reset config + credentials + sessions before running onboard (workspace only with --reset-scope full)]" \
"--reset-scope[Reset scope: config|config+creds+sessions|full]" \
"--non-interactive[Run without prompts]" \
"--modern[Alias for the default bootstrap onboarding (kept for compatibility)]" \
"--classic[Use the classic multi-step setup wizard]" \
"--accept-risk[Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)]" \
"--flow[Onboard flow: quickstart|advanced|manual|import]" \
"--mode[Onboard mode: local|remote]" \
"--auth-choice[Auth: custom-api-key|skip|claude-cli|apiKey|anthropic-cli|setup-token|arceeai-api-key|byteplus-api-key|cerebras-api-key|openai-device-code|openai|chutes|chutes-api-key|clawrouter-api-key|cloudflare-ai-gateway-api-key|zai-cn|codex|qwen-api-key-cn|qwen-api-key|zai-coding-cn|zai-coding-global|cohere-api-key|copilot-proxy|deepinfra-api-key|deepseek-api-key|featherless-api-key|fireworks-api-key|google-gemini-cli|github-copilot|zai-global|gmi-api-key|gemini-api-key|google-vertex-api-key|groq-api-key|huggingface-api-key|kilocode-api-key|kimi-code-api-key|litellm-api-key|lmstudio|longcat-api-key|meta-api-key|microsoft-foundry-apikey|microsoft-foundry-entra|minimax-cn-api|minimax-global-api|minimax-cn-oauth|minimax-global-oauth|mistral-api-key|moonshot-api-key|moonshot-api-key-cn|novita-api-key|nvidia-api-key|ollama|ollama-cloud|openai-api-key|opencode-go|opencode-zen|arceeai-openrouter|openrouter-api-key|openrouter-oauth|qianfan-api-key|qwen-oauth|sglang|qwen-standard-api-key-cn|qwen-standard-api-key|stepfun-standard-api-key-cn|stepfun-standard-api-key-intl|stepfun-plan-api-key-cn|stepfun-plan-api-key-intl|synthetic-api-key|tokenhub-api-key|tokenplan-api-key|together-api-key|venice-api-key|ai-gateway-api-key|vllm|volcengine-api-key|xai-api-key|xai-device-code|xai-oauth|xiaomi-api-key|xiaomi-token-plan-cn|xiaomi-token-plan-ams|xiaomi-token-plan-sgp|zai-api-key]" \
"--token-provider[Token provider id (non-interactive; used with --auth-choice token)]" \
"--token[Token value (non-interactive; used with --auth-choice token)]" \
"--token-profile-id[Auth profile id (non-interactive; default: <provider>:manual)]" \
"--token-expires-in[Optional token expiry duration (e.g. 365d, 12h)]" \
"--secret-input-mode[API key persistence mode: plaintext|ref (default: plaintext)]" \
"--cloudflare-ai-gateway-account-id[Cloudflare Account ID]" \
"--cloudflare-ai-gateway-gateway-id[Cloudflare AI Gateway ID]" \
"--alibaba-model-studio-api-key[Alibaba Model Studio API key]" \
"--anthropic-api-key[Anthropic API key]" \
"--byteplus-api-key[BytePlus API key]" \
"--clawrouter-api-key[ClawRouter proxy key]" \
"--cohere-api-key[Cohere API key]" \
"--comfy-api-key[Comfy Cloud API key]" \
"--fal-api-key[fal API key]" \
"--github-copilot-token[GitHub Copilot OAuth token]" \
"--gemini-api-key[Gemini API key]" \
"--huggingface-api-key[Hugging Face API key (HF token)]" \
"--litellm-api-key[LiteLLM API key]" \
"--lmstudio-api-key[LM Studio API key]" \
"--meta-api-key[Meta API key]" \
"--minimax-api-key[MiniMax API key]" \
"--mistral-api-key[Mistral API key]" \
"--novita-api-key[NovitaAI API key]" \
"--nvidia-api-key[NVIDIA API key]" \
"--ollama-cloud-api-key[Ollama Cloud API key]" \
"--openai-api-key[OpenAI API Key]" \
"--opencode-zen-api-key[OpenCode API key (Zen catalog)]" \
"--opencode-go-api-key[OpenCode API key (Go catalog)]" \
"--openrouter-api-key[OpenRouter API key]" \
"--runway-api-key[Runway API key]" \
"--synthetic-api-key[Synthetic API key]" \
"--together-api-key[Together AI API key]" \
"--volcengine-api-key[Volcano Engine API key]" \
"--vydra-api-key[Vydra API key]" \
"--xai-api-key[xAI API key]" \
"--xiaomi-api-key[Xiaomi MiMo pay-as-you-go API key]" \
"--xiaomi-token-plan-api-key[Xiaomi MiMo Token Plan API key]" \
"--deepseek-api-key[DeepSeek API key]" \
"--arceeai-api-key[Arcee AI API key]" \
"--cerebras-api-key[Cerebras API key]" \
"--chutes-api-key[Chutes API key]" \
"--cloudflare-ai-gateway-api-key[Cloudflare AI Gateway API key]" \
"--deepinfra-api-key[DeepInfra API key]" \
"--featherless-api-key[Featherless AI API key]" \
"--gmi-api-key[GMI Cloud API key]" \
"--longcat-api-key[LongCat API key]" \
"--groq-api-key[Groq API key]" \
"--kilocode-api-key[Kilo Gateway API key]" \
"--kimi-code-api-key[Kimi Code API key (subscription)]" \
"--pixverse-api-key[PixVerse API key]" \
"--qianfan-api-key[QIANFAN API key]" \
"--modelstudio-standard-api-key-cn[Qwen Cloud standard API key (China)]" \
"--modelstudio-standard-api-key[Qwen Cloud standard API key (Global/Intl)]" \
"--modelstudio-api-key-cn[Qwen Cloud Coding Plan API key (China)]" \
"--modelstudio-api-key[Qwen Cloud Coding Plan API key (Global/Intl)]" \
"--qwen-oauth-token[Qwen OAuth token]" \
"--fireworks-api-key[Fireworks API key]" \
"--moonshot-api-key[Moonshot API key]" \
"--tokenhub-api-key[Tencent TokenHub API key]" \
"--tokenplan-api-key[Tencent TokenPlan API key]" \
"--venice-api-key[Venice API key]" \
"--ai-gateway-api-key[Vercel AI Gateway API key]" \
"--zai-api-key[Z.AI API key]" \
@@ -195,7 +304,7 @@ _openclaw_onboard() {
"--install-daemon[Install gateway service]" \
"--no-install-daemon[Skip gateway service install]" \
"--skip-daemon[Skip gateway service install]" \
"--daemon-runtime[Daemon runtime: node|bun]" \
"--daemon-runtime[Daemon runtime: node]" \
"--skip-channels[Skip channel setup]" \
"--skip-skills[Skip skills setup]" \
"--skip-bootstrap[Skip creating default agent workspace files]" \
@@ -431,6 +540,7 @@ _openclaw_doctor() {
"--post-upgrade[Emit plugin-compat findings only (machine-readable with --json)]" \
"--json[With --lint or --post-upgrade: emit machine-readable JSON output]" \
"--severity-min[With --lint: drop findings below this severity (info|warning|error)]" \
"--all[With --lint: run all registered checks, including opt-in checks]" \
"--skip[With --lint: skip a specific check id (repeatable)]" \
"--only[With --lint: run only the specified check id (repeatable)]"
}
@@ -1358,6 +1468,20 @@ _openclaw_agents() {
esac
}
_openclaw_audit() {
_arguments -C \
"--agent[Filter by agent id]" \
"--session[Filter by exact session key]" \
"--run[Filter by run id]" \
"--kind[Filter by kind (agent_run or tool_action)]" \
"--status[Filter by status (started, succeeded, failed, cancelled, timed_out, blocked, unknown)]" \
"--after[Include records at/after ISO time or Unix milliseconds]" \
"--before[Include records at/before ISO time or Unix milliseconds]" \
"--cursor[Continue from a previous result cursor]" \
"--limit[Maximum records (1-500)]" \
"--json[Output a bounded JSON page]"
}
_openclaw_status() {
_arguments -C \
"--json[Output JSON instead of text]" \
@@ -1429,7 +1553,7 @@ _openclaw_sessions_compact() {
"--url[Gateway WebSocket URL (defaults to gateway.remote.url when configured)]" \
"--token[Gateway token (if required)]" \
"--password[Gateway password (password auth)]" \
"--timeout[RPC timeout in milliseconds (summarization can be slow)]" \
"--timeout[RPC timeout in milliseconds (defaults to no client deadline)]" \
"--json[Output JSON]"
}
@@ -1670,7 +1794,7 @@ _openclaw_gateway_status() {
_openclaw_gateway_install() {
_arguments -C \
"--port[Gateway port]" \
"--runtime[Daemon runtime (node|bun). Default: node]" \
"--runtime[Daemon runtime (node). Default: node]" \
"--token[Gateway token (token auth)]" \
"--wrapper[Executable wrapper for generated service ProgramArguments]" \
"--force[Reinstall/overwrite if already installed]" \
@@ -1696,9 +1820,9 @@ _openclaw_gateway_stop() {
_openclaw_gateway_restart() {
_arguments -C \
"--force[Restart immediately without waiting for active gateway work]" \
"--safe[Request an OpenClaw-aware restart after active work drains]" \
"--safe[Request an OpenClaw-aware restart after active work drains (bounded wait; may force after gateway.reload.deferralTimeoutMs expires; set deferralTimeoutMs=0 for indefinite wait)]" \
"--skip-deferral[Bypass the safe-restart deferral gate; requires --safe]" \
"--wait[Wait duration before forcing restart (ms, 10s, 5m; 0 waits indefinitely)]" \
"--wait[Wait duration before restart (ms, 10s, 5m; 0 waits indefinitely). For non-safe restarts (plain restart); not compatible with --force or --safe]" \
"--json[Output JSON]"
}
@@ -1867,7 +1991,7 @@ _openclaw_daemon_status() {
_openclaw_daemon_install() {
_arguments -C \
"--port[Gateway port]" \
"--runtime[Daemon runtime (node|bun). Default: node]" \
"--runtime[Daemon runtime (node). Default: node]" \
"--token[Gateway token (token auth)]" \
"--wrapper[Executable wrapper for generated service ProgramArguments]" \
"--force[Reinstall/overwrite if already installed]" \
@@ -1893,9 +2017,9 @@ _openclaw_daemon_stop() {
_openclaw_daemon_restart() {
_arguments -C \
"--force[Restart immediately without waiting for active gateway work]" \
"--safe[Request an OpenClaw-aware restart after active work drains]" \
"--safe[Request an OpenClaw-aware restart after active work drains (bounded wait; may force after gateway.reload.deferralTimeoutMs expires; set deferralTimeoutMs=0 for indefinite wait)]" \
"--skip-deferral[Bypass the safe-restart deferral gate; requires --safe]" \
"--wait[Wait duration before forcing restart (ms, 10s, 5m; 0 waits indefinitely)]" \
"--wait[Wait duration before restart (ms, 10s, 5m; 0 waits indefinitely). For non-safe restarts (plain restart); not compatible with --force or --safe]" \
"--json[Output JSON]"
}
@@ -2334,6 +2458,36 @@ _openclaw_models() {
esac
}
_openclaw_promos_list() {
_arguments -C \
"--json[Output JSON]"
}
_openclaw_promos_claim() {
_arguments -C \
"--api-key[Provider API key for non-interactive setup]" \
"--set-default[Set the promotion's suggested model as default without asking]"
}
_openclaw_promos() {
local -a commands
local -a options
_arguments -C \
\
"1: :_values 'command' 'list[List active promotions]' 'claim[Claim a promotion: set up provider auth and register its models]'" \
"*::arg:->args"
case $state in
(args)
case $line[1] in
(list) _openclaw_promos_list ;;
(claim) _openclaw_promos_claim ;;
esac
;;
esac
}
_openclaw_infer_list() {
_arguments -C \
"--json[Output JSON]"
@@ -3274,6 +3428,7 @@ _openclaw_node_run() {
_arguments -C \
"--host[Gateway host]" \
"--port[Gateway port]" \
"--context-path[Gateway WebSocket context path (e.g. /openclaw-gw)]" \
"--tls[Use TLS for the gateway connection]" \
"--tls-fingerprint[Expected TLS certificate fingerprint (sha256)]" \
"--node-id[Override node id (clears pairing token)]" \
@@ -3289,11 +3444,12 @@ _openclaw_node_install() {
_arguments -C \
"--host[Gateway host]" \
"--port[Gateway port]" \
"--context-path[Gateway WebSocket context path (e.g. /openclaw-gw)]" \
"--tls[Use TLS for the gateway connection]" \
"--tls-fingerprint[Expected TLS certificate fingerprint (sha256)]" \
"--node-id[Override node id (clears pairing token)]" \
"--display-name[Override node display name]" \
"--runtime[Service runtime (node|bun). Default: node]" \
"--runtime[Service runtime (node). Default: node]" \
"--force[Reinstall/overwrite if already installed]" \
"--json[Output JSON]"
}
@@ -3384,6 +3540,64 @@ _openclaw_sandbox() {
esac
}
_openclaw_worktrees_list() {
_arguments -C \
"--json[Output JSON]"
}
_openclaw_worktrees_create() {
_arguments -C \
"--name[Managed worktree name]" \
"--base-ref[Git ref to branch from]" \
"--json[Output JSON]"
}
_openclaw_worktrees_remove() {
_arguments -C \
"--force[Remove even if snapshot creation fails]" \
"--json[Output JSON]"
}
_openclaw_worktrees_restore() {
_arguments -C \
"--json[Output JSON]"
}
_openclaw_worktrees_gc() {
_arguments -C \
"--json[Output JSON]"
}
_openclaw_worktrees() {
local -a commands
local -a options
_arguments -C \
\
"1: :_values 'command' 'list[List active and restorable managed worktrees]' 'create[Create a managed worktree]' 'remove[Snapshot and remove a managed worktree]' 'restore[Restore a managed worktree from its snapshot]' 'gc[Run managed worktree cleanup now]'" \
"*::arg:->args"
case $state in
(args)
case $line[1] in
(list) _openclaw_worktrees_list ;;
(create) _openclaw_worktrees_create ;;
(remove) _openclaw_worktrees_remove ;;
(restore) _openclaw_worktrees_restore ;;
(gc) _openclaw_worktrees_gc ;;
esac
;;
esac
}
_openclaw_attach() {
_arguments -C \
"--session[Gateway session key to bind (default: main session)]" \
"--ttl[Grant TTL in milliseconds (default: gateway policy)]" \
"--bin[Claude Code binary to spawn]" \
"--print-config[Mint the grant + write the .mcp.json, print how to launch it, and exit without spawning]"
}
_openclaw_tui() {
_arguments -C \
"--local[Run against the local embedded agent runtime]" \
@@ -3421,6 +3635,8 @@ _openclaw_cron_list() {
_openclaw_cron_add() {
_arguments -C \
"--name[Job name]" \
"--declaration-key[Idempotent declaration identity key]" \
"--display-name[Human-readable declarative job label]" \
"--description[Optional description]" \
"--disabled[Create job disabled]" \
"--delete-after-run[Delete one-shot job after it succeeds]" \
@@ -3432,9 +3648,13 @@ _openclaw_cron_add() {
"--at[Run once at time (ISO with offset, or +duration). Use --tz for offset-less datetimes]" \
"--every[Run every duration (e.g. 10m, 1h)]" \
"--cron[Cron expression (5-field or 6-field with seconds)]" \
"--on-exit[Fire once when this watched command exits (event trigger; survives turn teardown)]" \
"--on-exit-cwd[Working directory for the --on-exit watched command]" \
"--tz[Timezone for cron expressions (IANA; cron default: Gateway host local timezone)]" \
"--stagger[Cron stagger window (e.g. 30s, 5m)]" \
"--exact[Disable cron staggering (set stagger to 0)]" \
"(--trigger-script ->)"{--trigger-script,->}"[Condition script file, or - for stdin]" \
"--trigger-once[Disable after the first successful triggered run]" \
"--system-event[System event payload (main session)]" \
"--message[Agent message payload]" \
"--command[Command payload run as sh -lc <shell> on the Gateway]" \
@@ -3442,7 +3662,7 @@ _openclaw_cron_add() {
"--command-cwd[Working directory for command payloads]" \
"--command-env[Environment override for command payloads (repeatable)]" \
"--command-input[stdin for command payloads]" \
"--thinking[Thinking level for agent jobs (off|minimal|low|medium|high|xhigh)]" \
"--thinking[Thinking level for agent jobs (off|minimal|low|medium|high|xhigh|adaptive|max|ultra)]" \
"--model[Model override for agent jobs (provider/model or alias)]" \
"--fallbacks[Fallback model list for agent jobs]" \
"--timeout-seconds[Timeout seconds for agent or command jobs]" \
@@ -3551,6 +3771,9 @@ _openclaw_cron_edit() {
"--tz[Timezone for cron expressions (IANA; cron default: Gateway host local timezone)]" \
"--stagger[Cron stagger window (e.g. 30s, 5m)]" \
"--exact[Disable cron staggering (set stagger to 0)]" \
"(--trigger-script ->)"{--trigger-script,->}"[Set condition script from file, or - for stdin]" \
"--trigger-once[Disable after the first successful triggered run]" \
"--clear-trigger[Remove the condition trigger]" \
"--system-event[Set systemEvent payload]" \
"--message[Set agentTurn payload message]" \
"--command[Set command payload run as sh -lc <shell> on the Gateway]" \
@@ -3558,7 +3781,8 @@ _openclaw_cron_edit() {
"--command-cwd[Set command payload working directory]" \
"--command-env[Set command payload environment overrides (repeatable)]" \
"--command-input[Set command payload stdin]" \
"--thinking[Thinking level for agent jobs (off|minimal|low|medium|high|xhigh)]" \
"--thinking[Thinking level for agent jobs (off|minimal|low|medium|high|xhigh|adaptive|max|ultra)]" \
"--clear-thinking[Remove the per-job thinking override (restore normal cron thinking precedence)]" \
"--model[Model override for agent jobs]" \
"--fallbacks[Fallback model list for agent jobs]" \
"--clear-fallbacks[Remove per-job fallback override]" \
@@ -3606,7 +3830,7 @@ _openclaw_cron() {
_arguments -C \
\
"1: :_values 'command' 'status[Show cron scheduler status]' 'list[List cron jobs]' 'add[Add a cron job]' 'rm[Remove a cron job]' 'enable[Enable a cron job]' 'disable[Disable a cron job]' 'get[Get a cron job as JSON]' 'show[Show a cron job]' 'runs[Show cron run history]' 'run[Run a cron job now (debug)]' 'edit[Edit a cron job (patch fields)]'" \
"1: :_values 'command' 'status[Show cron scheduler status]' 'list[List cron jobs]' 'add[Add a cron job]' 'create[Add a cron job]' 'rm[Remove a cron job]' 'remove[Remove a cron job]' 'delete[Remove a cron job]' 'enable[Enable a cron job]' 'disable[Disable a cron job]' 'get[Get a cron job as JSON]' 'show[Show a cron job]' 'runs[Show cron run history]' 'run[Run a cron job now (debug)]' 'edit[Edit a cron job (patch fields)]'" \
"*::arg:->args"
case $state in
@@ -3614,8 +3838,8 @@ _openclaw_cron() {
case $line[1] in
(status) _openclaw_cron_status ;;
(list) _openclaw_cron_list ;;
(add) _openclaw_cron_add ;;
(rm) _openclaw_cron_rm ;;
(add|create) _openclaw_cron_add ;;
(rm|remove|delete) _openclaw_cron_rm ;;
(enable) _openclaw_cron_enable ;;
(disable) _openclaw_cron_disable ;;
(get) _openclaw_cron_get ;;
@@ -3930,14 +4154,14 @@ _openclaw_clawbot() {
_openclaw_pairing_list() {
_arguments -C \
"--channel[Channel ()]" \
"--channel[Channel (none configured)]" \
"--account[Account id (for multi-account channels)]" \
"--json[Print JSON]"
}
_openclaw_pairing_approve() {
_arguments -C \
"--channel[Channel ()]" \
"--channel[Channel (none configured)]" \
"--account[Account id (for multi-account channels)]" \
"--notify[Notify the requester on the same channel]"
}
@@ -4005,6 +4229,7 @@ _openclaw_plugins_install() {
"--force[Overwrite an existing installed plugin or hook pack]" \
"--pin[Record npm installs as exact resolved <name>@<version>]" \
"--dangerously-force-unsafe-install[Deprecated no-op; security.installPolicy may still block]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings without prompting]" \
"--marketplace[Install a Claude marketplace plugin from a local repo/path or git/GitHub source]"
}
@@ -4012,7 +4237,8 @@ _openclaw_plugins_update() {
_arguments -C \
"--all[Update all tracked plugins and hook packs]" \
"--dry-run[Show what would change without writing]" \
"--dangerously-force-unsafe-install[Deprecated no-op; security.installPolicy may still block]"
"--dangerously-force-unsafe-install[Deprecated no-op; security.installPolicy may still block]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings without prompting]"
}
_openclaw_plugins_registry() {
@@ -4043,9 +4269,26 @@ _openclaw_plugins_init() {
_arguments -C \
"--directory[Output directory]" \
"--name[Display name]" \
"--type[Scaffold type (tool or provider)]" \
"--force[Overwrite an existing output directory]"
}
_openclaw_plugins_marketplace_entries() {
_arguments -C \
"--feed-profile[Configured marketplace feed profile to list]" \
"--feed-url[Explicit hosted marketplace feed URL]" \
"--offline[Read the latest accepted snapshot without fetching the feed]" \
"--json[Print JSON]"
}
_openclaw_plugins_marketplace_refresh() {
_arguments -C \
"--feed-profile[Configured marketplace feed profile to refresh]" \
"--feed-url[Explicit hosted marketplace feed URL]" \
"--expected-sha256[Expected hosted feed SHA-256 payload checksum]" \
"--json[Print JSON]"
}
_openclaw_plugins_marketplace_list() {
_arguments -C \
"--json[Print JSON]"
@@ -4057,12 +4300,14 @@ _openclaw_plugins_marketplace() {
_arguments -C \
\
"1: :_values 'command' 'list[List plugins published by a marketplace source]'" \
"1: :_values 'command' 'entries[List entries from the configured OpenClaw marketplace feed]' 'refresh[Refresh the configured OpenClaw marketplace feed snapshot]' 'list[List plugins published by a marketplace source]'" \
"*::arg:->args"
case $state in
(args)
case $line[1] in
(entries) _openclaw_plugins_marketplace_entries ;;
(refresh) _openclaw_plugins_marketplace_refresh ;;
(list) _openclaw_plugins_marketplace_list ;;
esac
;;
@@ -4075,7 +4320,7 @@ _openclaw_plugins() {
_arguments -C \
\
"1: :_values 'command' 'list[List discovered plugins]' 'search[Search ClawHub plugin packages]' 'inspect[Inspect plugin details]' 'enable[Enable a plugin in config]' 'disable[Disable a plugin in config]' 'uninstall[Uninstall a plugin]' 'install[Install a plugin or hook pack (path, archive, npm spec, git repo, clawhub:package, or marketplace entry)]' 'update[Update installed plugins and tracked hook packs]' 'registry[Inspect or rebuild the persisted plugin registry]' 'doctor[Report plugin load issues]' 'build[Generate simple tool plugin metadata]' 'validate[Validate simple tool plugin metadata]' 'init[Create a simple tool plugin project]' 'marketplace[Inspect Claude-compatible plugin marketplaces]'" \
"1: :_values 'command' 'list[List discovered plugins]' 'search[Search ClawHub plugin packages]' 'inspect[Inspect plugin details]' 'info[Inspect plugin details]' 'enable[Enable a plugin in config]' 'disable[Disable a plugin in config]' 'uninstall[Uninstall a plugin]' 'install[Install a plugin or hook pack (path, archive, npm spec, git repo, clawhub:package, or marketplace entry)]' 'update[Update installed plugins and tracked hook packs]' 'registry[Inspect or rebuild the persisted plugin registry]' 'doctor[Report plugin load issues]' 'build[Generate simple tool plugin metadata]' 'validate[Validate simple tool plugin metadata]' 'init[Create a plugin project]' 'marketplace[Inspect Claude-compatible plugin marketplaces]'" \
"*::arg:->args"
case $state in
@@ -4083,7 +4328,7 @@ _openclaw_plugins() {
case $line[1] in
(list) _openclaw_plugins_list ;;
(search) _openclaw_plugins_search ;;
(inspect) _openclaw_plugins_inspect ;;
(inspect|info) _openclaw_plugins_inspect ;;
(enable) _openclaw_plugins_enable ;;
(disable) _openclaw_plugins_disable ;;
(uninstall) _openclaw_plugins_uninstall ;;
@@ -4394,6 +4639,7 @@ _openclaw_skills_install() {
"--version[Install a specific version]" \
"--force[Overwrite an existing workspace skill]" \
"--force-install[Install a pending GitHub-backed skill before ClawHub scan completes]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings without prompting]" \
"--global[Install into the shared managed skills directory]" \
"--agent[Target agent workspace (defaults to cwd-inferred, then default agent)]" \
"--as[Install a git/local skill under this slug]"
@@ -4403,6 +4649,7 @@ _openclaw_skills_update() {
_arguments -C \
"--all[Update all tracked ClawHub skills]" \
"--force-install[Install a pending GitHub-backed skill before ClawHub scan completes]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings without prompting]" \
"--global[Update skills in the shared managed skills directory]" \
"--agent[Target agent workspace (defaults to cwd-inferred, then default agent)]"
}
@@ -4416,6 +4663,47 @@ _openclaw_skills_verify() {
"--agent[Target agent workspace (defaults to cwd-inferred, then default agent)]"
}
_openclaw_skills_curator_status() {
_arguments -C \
}
_openclaw_skills_curator_pin() {
_arguments -C \
}
_openclaw_skills_curator_unpin() {
_arguments -C \
}
_openclaw_skills_curator_restore() {
_arguments -C \
}
_openclaw_skills_curator() {
local -a commands
local -a options
_arguments -C \
"--json[Output as JSON]" \
"1: :_values 'command' 'status[Show curator run and lifecycle status]' 'pin[pin a curated skill]' 'unpin[unpin a curated skill]' 'restore[restore a curated skill]'" \
"*::arg:->args"
case $state in
(args)
case $line[1] in
(status) _openclaw_skills_curator_status ;;
(pin) _openclaw_skills_curator_pin ;;
(unpin) _openclaw_skills_curator_unpin ;;
(restore) _openclaw_skills_curator_restore ;;
esac
;;
esac
}
_openclaw_skills_workshop_list() {
_arguments -C \
"--json[Output as JSON]"
@@ -4525,7 +4813,7 @@ _openclaw_skills() {
_arguments -C \
"--agent[Target agent workspace (defaults to cwd-inferred, then default agent)]" \
"1: :_values 'command' 'search[Search ClawHub skills]' 'install[Install a skill from ClawHub, git, or a local directory]' 'update[Update ClawHub-installed skills in the active or shared managed directory]' 'verify[Verify a ClawHub skill with ClawHub]' 'workshop[Manage pending skill proposals]' 'list[List all available skills]' 'info[Show detailed information about a skill]' 'check[Check which skills are ready, visible, or missing requirements]'" \
"1: :_values 'command' 'search[Search ClawHub skills]' 'install[Install a skill from ClawHub, git, or a local directory]' 'update[Update ClawHub-installed skills in the active or shared managed directory]' 'verify[Verify a ClawHub skill with ClawHub]' 'curator[Inspect and manage skill lifecycle curation]' 'workshop[Manage pending skill proposals]' 'list[List all available skills]' 'info[Show detailed information about a skill]' 'check[Check which skills are ready, visible, or missing requirements]'" \
"*::arg:->args"
case $state in
@@ -4535,6 +4823,7 @@ _openclaw_skills() {
(install) _openclaw_skills_install ;;
(update) _openclaw_skills_update ;;
(verify) _openclaw_skills_verify ;;
(curator) _openclaw_skills_curator ;;
(workshop) _openclaw_skills_workshop ;;
(list) _openclaw_skills_list ;;
(info) _openclaw_skills_info ;;
@@ -4550,6 +4839,7 @@ _openclaw_update_repair() {
"--channel[Persist update channel before repair]" \
"--timeout[Timeout for update repair steps in seconds (default: 1800)]" \
"--yes[Skip confirmation prompts (non-interactive)]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings during post-update plugin sync]" \
"--no-restart[Accepted for update command parity; repair never restarts]"
}
@@ -4559,6 +4849,7 @@ _openclaw_update_finalize() {
"--channel[Persist update channel before repair]" \
"--timeout[Timeout for update repair steps in seconds (default: 1800)]" \
"--yes[Skip confirmation prompts (non-interactive)]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings during post-update plugin sync]" \
"--no-restart[Accepted for update command parity; repair never restarts]"
}
@@ -4585,6 +4876,7 @@ _openclaw_update() {
"--tag[Override the package target for this update (dist-tag, version, or package spec)]" \
"--timeout[Timeout for each update step in seconds (default: 1800)]" \
"--yes[Skip confirmation prompts (non-interactive)]" \
"--acknowledge-clawhub-risk[Acknowledge ClawHub release trust warnings during post-update plugin sync]" \
"1: :_values 'command' 'repair[Repair post-update doctor and plugin convergence]' 'finalize[Repair post-update doctor and plugin convergence]' 'wizard[Interactive update wizard]' 'status[Show update channel and version status]'" \
"*::arg:->args"
+1
View File
@@ -0,0 +1 @@
}DZAЪ h:2g6D(@ݻQ
-4
View File
@@ -1,4 +0,0 @@
{
"version": 1,
"requests": []
}
-80
View File
@@ -1,80 +0,0 @@
{
"version": 1,
"jobs": {
"5d7aed00-aa6e-4c81-9c2b-d347e4832721": {
"updatedAtMs": 1780624800030,
"scheduleIdentity": "{\"version\":1,\"enabled\":true,\"schedule\":{\"kind\":\"cron\",\"expr\":\"0 10 * * 5\",\"tz\":\"Asia/Shanghai\"}}",
"state": {
"nextRunAtMs": 1781229600000,
"lastRunAtMs": 1780624800011,
"lastRunStatus": "ok",
"lastStatus": "ok",
"lastDurationMs": 19,
"lastDeliveryStatus": "not-requested",
"consecutiveErrors": 0,
"consecutiveSkipped": 0,
"lastFailureNotificationDeliveryStatus": "not-requested"
}
},
"12c1165b-ae83-4451-ab27-460455a1e4ae": {
"updatedAtMs": 1780304408419,
"scheduleIdentity": "{\"version\":1,\"enabled\":true,\"schedule\":{\"kind\":\"cron\",\"expr\":\"0 17 1 6 *\",\"tz\":\"Asia/Shanghai\"}}",
"state": {
"nextRunAtMs": 1811840400000,
"lastRunAtMs": 1780304403652,
"lastRunStatus": "ok",
"lastStatus": "ok",
"lastDurationMs": 4767,
"lastDelivered": true,
"lastDeliveryStatus": "delivered",
"lastFailureNotificationDeliveryStatus": "not-requested",
"consecutiveErrors": 0,
"consecutiveSkipped": 0
}
},
"057d94d0-7c9b-45f1-b824-add73ecb068c": {
"updatedAtMs": 1780910697142,
"scheduleIdentity": "{\"version\":1,\"enabled\":false,\"schedule\":{\"kind\":\"at\",\"at\":\"2026-06-08T09:00:00.000Z\"}}",
"state": {
"lastRunAtMs": 1780910426045,
"lastRunStatus": "error",
"lastStatus": "error",
"lastDurationMs": 271097,
"lastDiagnostics": {
"summary": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.",
"entries": [
{
"ts": 1780910697119,
"source": "tool",
"severity": "error",
"message": "LLM request timed out."
},
{
"ts": 1780910697119,
"source": "tool",
"severity": "error",
"message": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."
},
{
"ts": 1780910697141,
"source": "agent-run",
"severity": "error",
"message": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."
}
]
},
"lastDiagnosticSummary": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.",
"lastErrorReason": "timeout",
"lastDelivered": false,
"lastDeliveryStatus": "not-delivered",
"lastDeliveryError": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.",
"lastFailureNotificationDelivered": false,
"lastFailureNotificationDeliveryStatus": "not-delivered",
"lastFailureNotificationDeliveryError": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.",
"consecutiveErrors": 4,
"consecutiveSkipped": 0,
"lastError": "The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."
}
}
}
}
-80
View File
@@ -1,80 +0,0 @@
{
"version": 1,
"jobs": [
{
"id": "5d7aed00-aa6e-4c81-9c2b-d347e4832721",
"agentId": "main",
"sessionKey": "agent:main:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat",
"name": "周五周报提醒",
"enabled": true,
"createdAtMs": 1778669245552,
"schedule": {
"kind": "cron",
"expr": "0 10 * * 5",
"tz": "Asia/Shanghai"
},
"sessionTarget": "main",
"wakeMode": "now",
"payload": {
"kind": "systemEvent",
"text": "📋 周报提醒:今天是周五10:00,请告诉我这周的工作内容,我来生成周报草稿供你审核。审核通过后会在17:00-17:30之间随机时间发送给 liuqiang@witsoft.cn,抄送 wurd@witsoft.cn, chenm@witsoft.cn, zengli@witsoft.cn"
},
"state": {}
},
{
"id": "12c1165b-ae83-4451-ab27-460455a1e4ae",
"agentId": "travel",
"sessionKey": "agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat",
"name": "预约天安门城楼",
"description": "明天下午5点提醒预约天安门城楼",
"enabled": true,
"deleteAfterRun": true,
"createdAtMs": 1780239857701,
"schedule": {
"kind": "cron",
"expr": "0 17 1 6 *",
"tz": "Asia/Shanghai"
},
"sessionTarget": "session:agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat",
"wakeMode": "now",
"payload": {
"kind": "agentTurn",
"message": "⏰ 现在是6月1日下午5点,提醒杨轩:记得预约天安门城楼参观!预约方式:微信搜索「天安门城楼参观预约」小程序或官网。注意12号就要去北京了,提前约好哦!",
"timeoutSeconds": 300
},
"delivery": {
"mode": "announce",
"to": "o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat",
"channel": "openclaw-weixin",
"accountId": "4a0926e2cb5f-im-bot"
},
"state": {}
},
{
"id": "057d94d0-7c9b-45f1-b824-add73ecb068c",
"agentId": "travel",
"sessionKey": "agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat",
"name": "七天提醒-6月8日",
"enabled": false,
"deleteAfterRun": true,
"createdAtMs": 1780275491249,
"schedule": {
"kind": "at",
"at": "2026-06-08T09:00:00.000Z"
},
"sessionTarget": "isolated",
"wakeMode": "now",
"payload": {
"kind": "agentTurn",
"message": "⏰ 现在是下午5点,提醒你记得之前说的事情!📌"
},
"delivery": {
"mode": "announce",
"to": "o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat",
"channel": "openclaw-weixin",
"accountId": "4a0926e2cb5f-im-bot"
},
"state": {}
}
]
}
@@ -1,4 +0,0 @@
{"ts":1780909476852,"jobId":"057d94d0-7c9b-45f1-b824-add73ecb068c","action":"finished","status":"error","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","diagnostics":{"summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","entries":[{"ts":1780909476785,"source":"tool","severity":"error","message":"LLM request timed out."},{"ts":1780909476785,"source":"tool","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},{"ts":1780909476839,"source":"agent-run","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."}]},"delivered":false,"deliveryStatus":"not-delivered","deliveryError":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","failureNotificationDelivery":{"delivered":false,"status":"not-delivered","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},"delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":false,"delivered":false},"sessionId":"99a470f6-2a33-4452-b36e-7cc6fbc545da","sessionKey":"agent:travel:cron:057d94d0-7c9b-45f1-b824-add73ecb068c:run:99a470f6-2a33-4452-b36e-7cc6fbc545da","runAtMs":1780909203644,"durationMs":273197,"nextRunAtMs":1780909506841,"model":"deepseek-v4-flash","provider":"deepseek"}
{"ts":1780909778142,"jobId":"057d94d0-7c9b-45f1-b824-add73ecb068c","action":"finished","status":"error","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","diagnostics":{"summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","entries":[{"ts":1780909778079,"source":"tool","severity":"error","message":"LLM request timed out."},{"ts":1780909778079,"source":"tool","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},{"ts":1780909778129,"source":"agent-run","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."}]},"delivered":false,"deliveryStatus":"not-delivered","deliveryError":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","failureNotificationDelivery":{"delivered":false,"status":"not-delivered","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},"delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":false,"delivered":false},"sessionId":"211ead5b-153c-4acc-9add-b216eec529c6","sessionKey":"agent:travel:cron:057d94d0-7c9b-45f1-b824-add73ecb068c:run:211ead5b-153c-4acc-9add-b216eec529c6","runAtMs":1780909510454,"durationMs":267677,"nextRunAtMs":1780909838131,"model":"deepseek-v4-flash","provider":"deepseek"}
{"ts":1780910122408,"jobId":"057d94d0-7c9b-45f1-b824-add73ecb068c","action":"finished","status":"error","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","diagnostics":{"summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","entries":[{"ts":1780910122373,"source":"tool","severity":"error","message":"LLM request timed out."},{"ts":1780910122373,"source":"tool","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},{"ts":1780910122401,"source":"agent-run","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."}]},"delivered":false,"deliveryStatus":"not-delivered","deliveryError":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","failureNotificationDelivery":{"delivered":false,"status":"not-delivered","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},"delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":false,"delivered":false},"sessionId":"d22ed27e-9aed-4345-b5c2-d78598ee1ac6","sessionKey":"agent:travel:cron:057d94d0-7c9b-45f1-b824-add73ecb068c:run:d22ed27e-9aed-4345-b5c2-d78598ee1ac6","runAtMs":1780909845794,"durationMs":276608,"nextRunAtMs":1780910422402,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":16415,"output_tokens":348,"total_tokens":31263}}
{"ts":1780910697147,"jobId":"057d94d0-7c9b-45f1-b824-add73ecb068c","action":"finished","status":"error","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","diagnostics":{"summary":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","entries":[{"ts":1780910697119,"source":"tool","severity":"error","message":"LLM request timed out."},{"ts":1780910697119,"source":"tool","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},{"ts":1780910697141,"source":"agent-run","severity":"error","message":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."}]},"delivered":false,"deliveryStatus":"not-delivered","deliveryError":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run.","failureNotificationDelivery":{"delivered":false,"status":"not-delivered","error":"The model did not produce a response before the model idle timeout. Please try again, or increase `models.providers.<id>.timeoutSeconds` for slow local or self-hosted providers. If `agents.defaults.timeoutSeconds` or a run-specific timeout is lower, raise that ceiling too; provider timeouts cannot extend the whole agent run."},"delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":false,"delivered":false},"sessionId":"df8c4392-a74f-4867-a418-f2ac120bc6a9","sessionKey":"agent:travel:cron:057d94d0-7c9b-45f1-b824-add73ecb068c:run:df8c4392-a74f-4867-a418-f2ac120bc6a9","runAtMs":1780910426045,"durationMs":271097,"model":"deepseek-v4-flash","provider":"deepseek"}
@@ -1,2 +0,0 @@
{"ts":1780448437488,"jobId":"08a61ced-7f1d-47a7-b511-d1a4b18c4821","action":"finished","status":"error","error":"cron: job execution timed out (last phase: model-call-started)","diagnostics":{"summary":"cron: job execution timed out (last phase: model-call-started)","entries":[{"ts":1780448437480,"source":"cron-setup","severity":"error","message":"cron: job execution timed out (last phase: model-call-started)"}]},"deliveryStatus":"unknown","failureNotificationDelivery":{"status":"unknown"},"runAtMs":1780448404319,"durationMs":33161,"nextRunAtMs":1780448467480}
{"ts":1780448472350,"jobId":"08a61ced-7f1d-47a7-b511-d1a4b18c4821","action":"finished","status":"ok","summary":"🚨 **天安门城楼预约提醒!**\n\n杨轩,今天是 **6月3日**,天安门城楼预约开放啦!\n\n**🎯 行动清单:**\n\n1. **预约日期**6月13日(周六)\n2. **预约场次**:上午场(8:30-12:00\n3. **预约入口**:微信小程序 → 搜索「天安门城楼参观预约」\n4. **关键时间**:⏰ 今天下午 **5点** 准时放票!\n\n**⚡ 提前准备:**\n- ✅ 在小程序里提前添加好参观人信息(姓名+身份证号)\n- ✅ 确保网络畅通\n- ⚠️ 天安门城楼票很抢手,建议提前几分钟进小程序等着,到点立刻提交!\n\n祝抢票顺利 🎫✨","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"3c732995-6ec5-4755-ae01-d8e261bee3f2","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runAtMs":1780448469600,"durationMs":2749,"nextRunAtMs":1780448467480,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":6264,"output_tokens":182,"total_tokens":14840}}
@@ -1 +0,0 @@
{"ts":1780390687025,"jobId":"0d960664-8033-4b3b-bd6b-5d5849b82ea6","action":"finished","status":"ok","summary":"This is the cron job firing — it's configured to deliver the announcement directly to the 杨轩 via openclaw-weixin. The delivery is set to \"announce\" mode, which means the message will be sent to the chat channel. Since this is an isolated agentTurn with `delivery.mode=announce`, the response will be delivered automatically.\n\n⏰ **现在是16:58,提醒杨轩:**\n\n🚨 **抢天安门城楼票!**\n\n- **日期:** 6月9日(周二)\n- **放票时间:** 17:00 准时开抢!\n- **平台:** 微信小程序「天安门城楼参观预约」\n\n🏃💨 还有不到2分钟,赶紧打开小程序等着!17:00准时点进去!\n\n> ⚠️ 天安门城楼的票非常抢手,提前准备好:\n> 1. 打开小程序并登录好\n> 2. 提前填好参观人信息\n> 3. 17:00一过立即点击预约\n> 4. 准备好手速和网速!","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"b2ec8579-d557-4b90-9af6-8662faaf156a","sessionKey":"agent:travel:cron:0d960664-8033-4b3b-bd6b-5d5849b82ea6:run:b2ec8579-d557-4b90-9af6-8662faaf156a","runAtMs":1780390681630,"durationMs":5388,"nextRunAtMs":1780390680000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":14205,"output_tokens":297,"total_tokens":14111}}
@@ -1,2 +0,0 @@
{"ts":1780239872173,"jobId":"12c1165b-ae83-4451-ab27-460455a1e4ae","action":"finished","status":"ok","summary":"收到,但我看下时间——现在是**5月31日周日晚11点**,而提醒设置在**6月1日下午5点**。这个cron任务触发的时机不对,是我刚才**手动测试触发了**,所以提前收到了。\n\n**这不是真的到时间了!** 真正的提醒会在 **明天(6/1)下午5点** 准时推送给你,到时候再来通知你预约天安门城楼。\n\n放心,任务已经设好了,明天到了时间会自动提醒你的 😊","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"b8e58782-2b00-4427-9c33-f0f8576bf3ec","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runId":"manual:12c1165b-ae83-4451-ab27-460455a1e4ae:1780239859366:1","runAtMs":1780239859367,"durationMs":12804,"nextRunAtMs":1780304400000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":46996,"output_tokens":106,"total_tokens":46996}}
{"ts":1780304408424,"jobId":"12c1165b-ae83-4451-ab27-460455a1e4ae","action":"finished","status":"ok","summary":"好的,收到提醒!不过天安门城楼**6月8日闭馆**,所以今天抢的8号的票用不上。没关系,我这边已经帮你安排了:\n\n- ✅ **明天(6月2日)16:58** 会再次提醒你,抢 **6月9日(周二)** 的票\n- ✅ 今天可以先熟悉流程,不提交\n\n准备好明天17:00准时开抢就行!💪","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"58a71359-0817-42a3-b2a5-de43a1dc8ff2","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runAtMs":1780304403652,"durationMs":4767,"nextRunAtMs":1811840400000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":20217,"output_tokens":94,"total_tokens":21625}}
@@ -1,4 +0,0 @@
{"ts":1780408839067,"jobId":"23cee062-ec01-4509-b204-6b8d2eebb7ad","action":"finished","status":"error","error":"cron: job execution timed out (last phase: model-call-started)","diagnostics":{"summary":"cron: job execution timed out (last phase: model-call-started)","entries":[{"ts":1780408839059,"source":"cron-setup","severity":"error","message":"cron: job execution timed out (last phase: model-call-started)"}]},"deliveryStatus":"unknown","failureNotificationDelivery":{"status":"unknown"},"runAtMs":1780408805644,"durationMs":33415,"nextRunAtMs":1780408869059}
{"ts":1780408904726,"jobId":"23cee062-ec01-4509-b204-6b8d2eebb7ad","action":"finished","status":"error","error":"cron: job execution timed out (last phase: model-call-started)","diagnostics":{"summary":"cron: job execution timed out (last phase: model-call-started)","entries":[{"ts":1780408904723,"source":"cron-setup","severity":"error","message":"cron: job execution timed out (last phase: model-call-started)"}]},"deliveryStatus":"unknown","failureNotificationDelivery":{"status":"unknown"},"runAtMs":1780408871867,"durationMs":32856,"nextRunAtMs":1780408964723}
{"ts":1780409003047,"jobId":"23cee062-ec01-4509-b204-6b8d2eebb7ad","action":"finished","status":"error","error":"cron: job execution timed out (last phase: model-call-started)","diagnostics":{"summary":"cron: job execution timed out (last phase: model-call-started)","entries":[{"ts":1780409003041,"source":"cron-setup","severity":"error","message":"cron: job execution timed out (last phase: model-call-started)"}]},"deliveryStatus":"unknown","failureNotificationDelivery":{"status":"unknown"},"runAtMs":1780408970056,"durationMs":32985,"nextRunAtMs":1780409303041}
{"ts":1780409308561,"jobId":"23cee062-ec01-4509-b204-6b8d2eebb7ad","action":"finished","status":"ok","summary":"⏰ **晚上10点提醒到!**\n\n别忘啦,**把带洗脸巾放进包里** 🧴🧳\n\n6月12号出发去北京,趁现在还有时间,把要带的东西慢慢收拾起来~还有什么需要我帮忙的吗?😊","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"2a799cd5-21a8-43c8-911d-ab5cedb9cbab","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runAtMs":1780409305930,"durationMs":2629,"nextRunAtMs":1780409303041,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":20120,"output_tokens":58,"total_tokens":21912}}
@@ -1,4 +0,0 @@
{"ts":1778833358417,"jobId":"5d7aed00-aa6e-4c81-9c2b-d347e4832721","action":"finished","status":"ok","summary":"📋 周报提醒:今天是周五10:00,请告诉我这周的工作内容,我来生成周报草稿供你审核。审核通过后会在17:00-17:30之间随机时间发送给 liuqiang@witsoft.cn,抄送 wurd@witsoft.cn, chenm@witsoft.cn, zengli@witsoft.cn","deliveryStatus":"not-requested","runAtMs":1778833351270,"durationMs":7145,"nextRunAtMs":1779415200000}
{"ts":1779446924117,"jobId":"5d7aed00-aa6e-4c81-9c2b-d347e4832721","action":"finished","status":"ok","summary":"📋 周报提醒:今天是周五10:00,请告诉我这周的工作内容,我来生成周报草稿供你审核。审核通过后会在17:00-17:30之间随机时间发送给 liuqiang@witsoft.cn,抄送 wurd@witsoft.cn, chenm@witsoft.cn, zengli@witsoft.cn","deliveryStatus":"not-requested","runAtMs":1779446913505,"durationMs":10609,"nextRunAtMs":1780020000000}
{"ts":1780020001414,"jobId":"5d7aed00-aa6e-4c81-9c2b-d347e4832721","action":"finished","status":"ok","summary":"📋 周报提醒:今天是周五10:00,请告诉我这周的工作内容,我来生成周报草稿供你审核。审核通过后会在17:00-17:30之间随机时间发送给 liuqiang@witsoft.cn,抄送 wurd@witsoft.cn, chenm@witsoft.cn, zengli@witsoft.cn","deliveryStatus":"not-requested","sessionKey":"agent:main:cron:5d7aed00-aa6e-4c81-9c2b-d347e4832721:run:1780020001403","runAtMs":1780020001403,"durationMs":8,"nextRunAtMs":1780624800000}
{"ts":1780624800038,"jobId":"5d7aed00-aa6e-4c81-9c2b-d347e4832721","action":"finished","status":"ok","summary":"📋 周报提醒:今天是周五10:00,请告诉我这周的工作内容,我来生成周报草稿供你审核。审核通过后会在17:00-17:30之间随机时间发送给 liuqiang@witsoft.cn,抄送 wurd@witsoft.cn, chenm@witsoft.cn, zengli@witsoft.cn","deliveryStatus":"not-requested","sessionKey":"agent:main:cron:5d7aed00-aa6e-4c81-9c2b-d347e4832721:run:1780624800011","runAtMs":1780624800011,"durationMs":19,"nextRunAtMs":1781229600000}
@@ -1 +0,0 @@
{"ts":1780649884178,"jobId":"80b2f7dc-f466-4479-9132-49b5207a7b4f","action":"finished","status":"ok","summary":"⏰ **16:58 到点啦!该预约天安门城楼了!**\n\n预约方式:\n\n1️⃣ **微信小程序**:搜索「天安门城楼参观预约」\n2️⃣ **官网预约**:访问官方预约平台\n3️⃣ **预约时间**:需提前 **1-7天**,建议尽早约\n4️⃣ **参观须知**:记得带好 **身份证原件**\n\n📌 天安门城楼目前参观需按预约时段入场,过时可能无法进入,建议选上午时段避开人流高峰。\n\n需要我帮你查一下近期的可预约日期和时间段吗?","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"916ef8cf-10db-496f-b734-364fbb4799f7","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runAtMs":1780649880002,"durationMs":4172,"nextRunAtMs":1780649880000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":12292,"output_tokens":129,"total_tokens":15748}}
@@ -1 +0,0 @@
{"ts":1780275307704,"jobId":"b5ed5459-4a40-4de7-bbb0-9cb6afe9e510","action":"finished","status":"ok","summary":"⏰ **喝水提醒!** 💧\n\n杨轩,早上好!现在已经 8:55 了,记得喝杯水再开始工作哦~ 🚰\n\n早起一杯水,精神一整天!今天记得多喝水 💪","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"51a9cb19-9381-4f4f-a292-388dce05ae12","sessionKey":"agent:travel:cron:b5ed5459-4a40-4de7-bbb0-9cb6afe9e510:run:51a9cb19-9381-4f4f-a292-388dce05ae12","runAtMs":1780275300003,"durationMs":7699,"nextRunAtMs":1780275300000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":13677,"output_tokens":53,"total_tokens":13677}}
@@ -1 +0,0 @@
{"ts":1780736285608,"jobId":"cf24cda0-8033-4208-bbd7-299fd03f108b","action":"finished","status":"ok","summary":"杨轩,⚠️ **天安门城楼抢票提醒!**\n\n现在是16:58,还有2分钟就要开抢了!\n\n**📌 抢票信息**\n- **参观日期:** 2026年6月13日(周六)\n- **开抢时间:** **17:00**(马上!)\n- **预约渠道:** 微信搜索「天安门城楼参观预约」小程序\n\n**📋 提前准备**\n- ✅ 身份证号提前复制好\n- ✅ 确认小程序已打开,登录状态正常\n- ✅ 网络通畅(建议用5G/WiFi双保险)\n\n6月13日是天安门城楼每周的预约日,通常放票后很快会被抢完,一定要准点冲!祝你好运 🍀","delivered":true,"deliveryStatus":"delivered","delivery":{"intended":{"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"resolved":{"ok":true,"channel":"openclaw-weixin","to":"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat","accountId":"4a0926e2cb5f-im-bot","source":"explicit"},"fallbackUsed":true,"delivered":true},"sessionId":"e431996f-9842-4273-8ad9-a126648e73cb","sessionKey":"agent:travel:openclaw-weixin:direct:o9cq80w6znnpgitw-ggackwd69ba@im.wechat","runAtMs":1780736280020,"durationMs":5583,"nextRunAtMs":1780736280000,"model":"deepseek-v4-flash","provider":"deepseek","usage":{"input_tokens":6052,"output_tokens":166,"total_tokens":14628}}
+20
View File
@@ -0,0 +1,20 @@
# bk02 openclaw 文档目录
> 本目录存放**本机 OpenClaw 系统**的运维文档。
> **新会话 / 新人接手请先读第 1 份**,无需依赖任何历史对话。
| # | 文档 | 内容 |
|---|---|---|
| 1 | `bk02-openclaw-系统说明.md` | **接手入口**:主机与访问、架构、关键路径速查、服务与运维命令、存储结论(SQLite-only)、配置与凭据位置、插件、备份/回滚/Git 仓库、**排查手册**、已知边界与坑 |
| 2 | `openclaw-升级与维护.md` | 2026-09-16 升级实测记录:Node 22.23.1→26.8.2、OpenClaw 2026.8.1→2026.9.4、清理 4.6G、踩坑清单、回滚步骤 |
| 3 | `agent-创建规范与自动化-设计.md` | **待实现的设计**:新建 agent 的命名规范(id 用 ASCII / 展示层全中文)、每 agent 专属 MySQL 库与专用账号、中文模板四件套、每日备份改造(硬编码→动态发现)、技能强制性(档①)与决策记录 |
| 4 | `agent-创建规范-实现计划.md` | 上述设计的实现计划:任务切分(A 脚本+模板 / B skill / C 备份改造 / D 红线 / E 存量)、关键代码与验收标准 |
| 5 | `agent-juaner-卷儿-检查报告.md` | juaner(卷儿)检查报告与决策:基本档案、职责设定 vs 实际行为、权限边界、**4 项发现**(记账零数据 / 无定时提醒 / bash 中文变量名不可用 / DREAMS 语言无配置解)、**2026-09-16 安全放宽决策**、邮箱登记与未决待办 |
## 目录约定
1. **不含明文口令**:仅记录凭据的存放位置(见系统说明 §6);备份包含凭据,勿外发。
2. **文档是快照**:版本、磁盘占用、插件清单等会变化,下判断前先用命令核对(首选 `openclaw doctor`)。
3. **改动后要推送**:本目录属于 `~/.openclaw` 这个 git 仓库(分支 `314`、remote 为 Gitea)。
该仓库的 `auto-commit-config.sh` 在「无变更」时会**直接退出、不推送**,因此**手动提交后必须自己 `git push origin 314`**。
4. **新增文档**:按 `序号` 或明确主题命名,并登记到本文件。
+169
View File
@@ -0,0 +1,169 @@
# juaner(卷儿)agent 检查报告与决策记录
> 检查日期:2026-09-16 宿主:bk02`xuan-asus-nj`)| 对象:OpenClaw agent `juaner`
> 本文是**快照**:数据量、行数、配置字段都可能变化,下判断前请先用 §8 的命令复核。
## 0. 30 秒速览
`juaner`(中文名**卷儿** 🐑)是 **王芳**(昵称"卷儿"/"王卷儿")的专属个人助手,经**微信**接入,自称定位为「家庭记账 · 待办提醒 · 日程管理 · 生活助手」。
但截至检查日,它**实际在做**的是王芳的**工伤认定材料整理**(2026-09-16)与杨锦书**成长档案**2026-09-07);而它**承诺的记账与定时提醒,两个核心职责均无任何数据落地**。
## 1. 基本档案
| 项目 | 值 |
|---|---|
| agent id | `juaner`(本机 11 个 agent 之一) |
| 中文名 / 头像 | 卷儿 / 🐑 / `minio.climbcube.cn/img/assistant.jpg` |
| 服务对象 | **王芳**(不是本机主用户 yangxuan;主人档案见 `agents/juaner/agent/IDENTITY.md` |
| 宿主服务 | `openclaw-gateway.service`systemd user unit,端口 18789 |
| 模型 | `deepseek/deepseek-flash` |
| 接入渠道 | **微信** `openclaw-weixin`accountId `89623f3b5d79-im-bot` |
| 绑定关系 | `openclaw.json``bindings[]`bot `89623f3b5d79-im-bot``juaner`;另一个 bot `e48ace9814f0-im-bot``main` |
| 工作区 | `~/.openclaw/workspace-juaner` |
| agent 目录 | `~/.openclaw/agents/juaner/agent`(含 `openclaw-agent.sqlite`,约 9.5 MB |
| 专属数据库 | MySQL 库 `juaner`,专用账号 `agent_juaner`**唯一入口 `~/.openclaw/scripts/db-conn.sh juaner`**(口令存 `.env``DB_PASSWORD_卷儿`,由脚本内部读取,不进命令行) |
| 记忆检索 | `BAAI/bge-m3` 向量索引(siliconflow);每夜 03:00 跑 light→REM→deep 三段 dreaming |
## 2. 职责设定(设计期,来自 agent 自带文档)
出自 `agents/juaner/agent/IDENTITY.md``SOUL.md`
1. **家庭记账** —— 分类含餐饮/购物/交通/医疗/教育/日用/人情/其他
2. **待办与重要日期提醒** —— 生日、纪念日**提前 1–3 天**关怀提醒
3. **子女成长档案** —— 杨锦书的 `jinshu/` 知识库
4. **生活助手** —— 代查、代填、代办
5. **安全守则** —— 防提示词注入、资金操作需确认、隐私不外泄
## 3. 权限边界
- `tools.profile = "full"``agents.defaults.sandbox.mode = "off"`**无沙箱**
- `deny`: `group:web``browser`;但 `web.search`(searxng)、`web.fetch` **开启**
- `agentToAgent.enabled = true`,可与全部 11 个 agent 互调
- 运行用户 `yangxuan`,该用户在 **`docker` 组**(事实等同 root
- 启用技能:`agent-browser``Github`,加全局 `openclaw-office-toolkit`(填表用)、`table-alias``dws`
## 4. 实际行为(有据可查)
| 时间 | 事项 | 证据 |
|---|---|---|
| 2026-09-16 09:35 | 完成 7 份**工伤认定**材料填写 → `data/工伤认定/已填写/`,附 10 条待补问题,并主动给出「单位 30 日内申请(约 10-09 前)」时限提醒 | 会话记录 + 文件 mtime |
| 2026-09-07 | 整理杨锦书**大班阶段**档案,建 `jinshu/大班阶段.md`,并建议做成课表提醒 | `memory/manual/2026-09-07.md` |
| 每夜 03:00 | dreaming 三段式记忆固化 | `memory/dreaming/rem/``deep/` 连续 09-02 ~ 09-16 |
业务背景:王芳 2026-09-09 17:43 下班途中遭遇交通事故(对方全责),正在走工伤申请——这是卷儿当前最活跃的任务线。
## 5. 检查发现
### 5.1 记账 / 待办职责零数据(未解决)
`juaner``transactions``todos` 两表**均为 0 行**2026-08-26 的备份 `db/juaner_latest.sql` 里也只有建表语句、无一条 INSERT。
在现存可检索的会话记录(119 条 transcript 事件)中,`mysql` 仅出现 1 次、`transactions` 出现 **0 次****没有任何写库痕迹**。
**判断**:记账/待办链路是「建成但从未投入使用」,**不是故障**。历史归档(`agents/juaner/sessions/*.zst`,每个约 2 KB)体量极小,也不像含记账操作。
补充(同日 11:28 复核):专用账号入口已由 `scripts/db-conn.sh` 打通并实测可连(见 §5.3),即**通道是好的、数据是空的**——问题在"没人让它记",不在"它记不进去"。
### 5.2 「提前提醒」缺自动化载体(未解决)
- `HEARTBEAT.md` 为纯注释模板(该形态本身即"跳过心跳"的约定)
- `~/.openclaw/cron/runs` 为空;`openclaw.json` 只有 `cron.triggers.enabled = true`**无任何任务**
- `heartbeat_outcomes` 表 0 行
**判断**:「生日/纪念日提前 3 天提醒」**目前不会自动送达**,完全依赖主人主动发起对话。
### 5.3 中文口令键名问题 —— **已由 `db-conn.sh` 解决**2026-09-16
**背景(本报告独立实测)**:早期 `AGENTS.md` 的示范命令是
`mysql -h 127.0.0.1 -u agent_juaner -p"${DB_PASSWORD_卷儿}" juaner`,而这个写法在 shell 层面就不成立:
| shell | `DB_PASSWORD_卷儿=abc` | `${DB_PASSWORD_卷儿}` 展开 |
|---|---|---|
| bash | 「未找到命令」 | 「错误的替换」(bash 变量名必须是 ASCII 标识符) |
| zsh | 正常 | 正常展开为 `abc` |
**结论(用户侧判定更彻底,见设计文档附录 A 第 8 条)**:中文键名连「作为环境变量注入 agent 执行环境」都不可行——
① gateway 进程 `/proc/<pid>/environ` 中不存在 `DB_PASSWORD_<中文名>`
`OPENCLAW_SERVICE_MANAGED_ENV_KEYS` 是白名单且不含 `DB_PASSWORD_*`
`openclaw secrets store --kind env` 要求名称匹配 `^[A-Z][A-Z0-9_]{0,127}$`(纯大写 ASCII)。
**现行方案**:统一入口 `~/.openclaw/scripts/db-conn.sh <agent_id>` —— 按 id 反查 `agents.entries.<id>.name` → 读 `.env` 里的 `DB_PASSWORD_<中文名>` → 经 `MYSQL_PWD` 环境变量转发给 `docker exec`**口令不进 argv、不进 stdout**`--print` 只打印占位符)。11 个 `AGENTS.md``AGENTS.md.tpl``new-agent.sh` 已同步改用该入口。
**本报告实测(2026-09-16 同日)**
```
$ bash ~/.openclaw/scripts/db-conn.sh juaner --sql "select database();"
juaner
```
⇒ 入口**已通**。`DB_PASSWORD_<中文名>` 的定位是 `.env` 内的**存储键名**,不再是 agent 的环境变量。故本项**已关闭**,不必再改示范命令或引入 ASCII 别名。
### 5.4 DREAMS.md 的英文无法用配置改成中文(结论:不处理)
- `DREAMS.md` 由 memory-core 的 dreaming **自动生成**:以 `<!-- openclaw:dreaming:diary:start/end -->` 为标记,每夜 03:00 重写日记区
- 英文源自插件内**硬编码**的 `NARRATIVE_SYSTEM_PROMPT`"You are keeping a dream diary..."),该 prompt **未指定语言**
- `plugins.entries["memory-core"].config.dreaming` 的可用字段只有 `enabled / frequency / timezone / storage / execution / phases / model` —— **没有语言或自定义 prompt 项**
**判断**:人工翻译会被下一次 sweep 覆盖;改 dist 源码会在升级时丢失且违反升级维护约定。**决定:保留英文,不处理。**
### 5.5 凭据与隐私暴露面(已知边界,已按 §6.1 放宽)
- `agents/juaner/agent/IDENTITY.md``workspace-juaner/MEMORY.md` 明文存有主人身份证号,以及 QQ、Apple ID、交管 12123、12306 等账号口令;两者均属**常驻上下文文件**
- 工作区另有 `data/私聊_王芳.txt`10.5 MB)、`data/工伤认定/王芳的身份证.docx``下班路线图.jpg`
- 前情:`workspace-juaner/data/私聊_*.json` **曾被自动提交并推送到 Gitea**`.git` 一度涨到 199 MB(见 `bk02-openclaw-系统说明.md` §8.2
## 6. 决策记录
### 6.1 2026-09-16:安全问题放宽(用户决定)
> 口径:本地自建 openclaw、走 tailscale 访问、不出外网,安全问题可以放宽。
据此定案:
- **不做**沙箱加固(`agents.defaults.sandbox.mode` 维持 `off`
- **不做**凭据搬出工作区(`MEMORY.md` 等的口令保持原位)
- §5.5 降级为「已知边界」,**不再作为阻塞项**,后续会话不必重复提示
同时记录两条与"不出外网"前提相关的**边界事实**(仅供日后判断,不代表要处理):
1. **tailscale 只隔离 gateway 的 18789 端口,不覆盖卷儿的入口。** 卷儿的消息来自微信(bot 经 `ilinkai.weixin.qq.com`),处于公网侧——**能给该微信号发消息的人即可给卷儿下指令**,隔离不靠 tailscale。
2. **agent 有能力主动出网**`web.fetch` 开启,加上 `full` shell`curl` 即可出网。故"不出外网"在能力层面不成立。
### 6.2 2026-09-16:模板中文化 + 登记邮箱(本次已执行)
| 文件 | 改动 | 备份 |
|---|---|---|
| `workspace-juaner/IDENTITY.md` | 英文模板 → 中文 | `*.bak-20260915-232419-zh` |
| `workspace-juaner/USER.md` | 英文模板 → 中文;**新增「邮箱:1159785314@qq.com」** | 同上 |
| `workspace-juaner/HEARTBEAT.md` | 英文注释 → 中文注释(**保持"仅注释即跳过心跳"语义不变**) | 同上 |
- **生效时机**workspace 常驻上下文文件在**新建会话**时读取,无需重启 gateway。
- **邮箱主位约定**`USER.md` 的「邮箱」字段为**唯一主位**`MEMORY.md` 社交账号区的邮箱仅为账号标识(Apple ID 用户名),不随联系方式变更。
## 7. 待办(未解决项)
| # | 事项 | 说明 |
|---|---|---|
| 1 | 记账/待办是否真要启用 | 库、专用账号、表结构均已就绪且实测可连;需决定"教会卷儿用起来"还是"关掉该职责、改掉承诺" |
| 2 | 定时提醒 | 二选一:真建 cron 任务;或改写 `IDENTITY.md` 里"提前 3 天提醒"的承诺,避免承诺大于能力 |
| 3 | ~~中文变量名写法~~ | **已关闭**:由 `scripts/db-conn.sh` 统一入口取代(2026-09-16),入口实测可连,见 §5.3 |
| 4 | 未提交改动 | `workspace-juaner/AGENTS.md`(数据库规范,+6 行)与本文档同属未提交状态,按 `README.md` §目录约定 3 需手动 `git push origin 314` |
## 8. 复核命令速查
```
# 表与数据量(走专用账号入口,勿用 root / 勿 docker exec 直连)
~/.openclaw/scripts/db-conn.sh juaner --sql "select count(*) from transactions; select count(*) from todos;"
# 入口连通性自检
~/.openclaw/scripts/db-conn.sh juaner --sql "select database()"
# 打印等价命令(口令以占位符显示,可安全粘贴)
~/.openclaw/scripts/db-conn.sh juaner --print
# dreaming 配置(确认无语言项)
openclaw config get plugins.entries.memory-core.config.dreaming
# 会话记录里的记账痕迹
python3 -c "import sqlite3;c=sqlite3.connect('file:$HOME/.openclaw/agents/juaner/agent/openclaw-agent.sqlite?mode=ro',uri=True);print(c.execute(\"select count(*) from transcript_events where event_json like '%mysql%'\").fetchone())"
```
+526
View File
@@ -0,0 +1,526 @@
# agent 创建规范与数据库自动化 —— 实现计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use subagent-driven-development to implement this plan task-by-task.
>
> **Goal:** 让 main 一条命令创建带专属 MySQL 库与全中文配置的新 agent,并让新建库自动进入每日备份。
>
> **Architecture:** 特权操作全部收敛到 `new-agent.sh`(建库 → 建号 → 授权 → 写 .env → 创建 agent → 渲染中文模板 → 自检);skill 只负责触发与约束;备份脚本由硬编码清单改为动态发现。
>
> **Spec:** `~/.openclaw/docs/agent-创建规范与自动化-设计.md`(执行者需同时读此文档)
>
> **执行环境:** ⚠️ **所有文件位于 bk02,不是本机**。通过 `sshpass -p '<密码>' ssh yangxuan@bk02` 操作;本地写好的文件用 `scp` 传给 bk02 再 `mv` 到目标路径。
>
> **Global Constraints**
> - `agent_id` 必须匹配 `^[a-z][a-z0-9-]{0,23}$`
> - 库名 = `agent_id`;账号 = `agent_<id>`**只授权 `<id>.*`**
> - 展示层(模板与文档内容、`name`、`identity.name`**全中文**;标识层(id/库名/账号/目录名)**全 ASCII**
> - 脚本**不硬编码任何密码**root 凭据从 `~/.openclaw/.env` 的 `MYSQL_PWD_ROOT` 读
> - **默认拒绝覆盖**:库 / agent 条目 / workspace 任一已存在即失败退出
> - 改动提交到 `~/.openclaw` 仓库(分支 `314`)并 **push**(该仓库 auto-commit 在无变更时不推送)
---
## 任务依赖图
```
Task A(脚本+模板)──► Task E(存量改造,串行)
Task Bskill
Task C(备份改造) ├─ 与 A 无文件冲突,可并行
Task D(红线+索引) ┘
```
---
## Task Aprovisioning 脚本 + 中文模板
**Files**
- Create `~/.openclaw/scripts/new-agent.sh``chmod 755`
- Create `~/.openclaw/scripts/agent-templates/IDENTITY.md.tpl`
- Create `~/.openclaw/scripts/agent-templates/SOUL.md.tpl`
- Create `~/.openclaw/scripts/agent-templates/AGENTS.md.tpl`
- Create `~/.openclaw/scripts/agent-templates/MEMORY.md.tpl`
**InterfacesProducesTask B/E 依赖)**
- CLI`new-agent.sh <id> <中文名> [--dry-run] [--reset-password]`
- 成功时 stdout 末尾打印四行:`DATABASE=` / `USER=` / `PASSWORD_ENV=` / `WORKSPACE=`
- 审计日志追加一行到 `~/.openclaw/workspace/db/agent-provision.log`
**Steps**
- [ ] **1. 写四个中文模板**
`IDENTITY.md.tpl`
```markdown
# IDENTITY.md —— 我是谁?
- **名称:** {{AGENT_NAME}}
- **编号:** {{AGENT_ID}}
- **定位:** (一句话说明我负责什么)
- **创建时间:** {{CREATED_AT}}
```
`SOUL.md.tpl`
```markdown
# SOUL.md —— 我的性格与表达
- **风格:** 简洁、直接、先给结论再给依据。
- **原则:** 不确定时先问,不猜测;做破坏性操作前必须先请示。
- **语言:** 一律用中文回复。
- **边界:** 只处理我职责范围内的事,跨范围时转交对应 agent。
```
`AGENTS.md.tpl`
```markdown
# AGENTS.md —— 我的工作规范
## 会话启动
1.`IDENTITY.md`(我是谁)
2.`MEMORY.md`(长期记忆)
3.`memory/` 下最近两天的记录
## 记忆
- 每日记录写 `memory/YYYY-MM-DD.md`
- 长期结论写 `MEMORY.md`
## 数据库规范
- **默认库:** `{{AGENT_ID}}` —— 这就是我自己的库
- **账号:** `agent_{{AGENT_ID}}`
- **连接(推荐):** `~/.openclaw/scripts/db-conn.sh {{AGENT_ID}}`(交互式)或 `~/.openclaw/scripts/db-conn.sh {{AGENT_ID}} --sql "select database()"`
- **口令:** 由该脚本自动从 `~/.openclaw/.env` 读取(键名 `DB_PASSWORD_{{AGENT_NAME}}`),口令不会出现在命令行中
- **禁止:** 使用 root、使用 `docker exec`、访问其他 agent 的库、跨库写入
- **建表前**先确认字段与索引;**破坏性语句**DROP / TRUNCATE / 无条件 DELETE)必须先请示
## 红线
- 绝不泄露私密数据
- 未经请示绝不运行破坏性命令
```
`MEMORY.md.tpl`
```markdown
# MEMORY.md —— 长期记忆
> 只写经过筛选的、长期有效的结论;原始流水写 `memory/YYYY-MM-DD.md`。
## 关于我的职责
## 关于我的库 `{{AGENT_ID}}`
## 重要决定
```
- [ ] **2. 写脚本骨架(参数校验 + 冲突检查 + dry-run**
```bash
#!/usr/bin/env bash
# 新建 OpenClaw agent:建库 → 建号 → 授权 → 写 .env → 创建 agent → 渲染中文模板 → 自检
set -euo pipefail
ENV_FILE="$HOME/.openclaw/.env"
TEMPLATE_DIR="$HOME/.openclaw/scripts/agent-templates"
OPENCLAW_ROOT="$HOME/.openclaw"
LOG_DIR="$OPENCLAW_ROOT/workspace/db"
LOG_FILE="$LOG_DIR/agent-provision.log"
MYSQL_CONTAINER="mysql"
AGENT_ID="${1:-}"; AGENT_NAME="${2:-}"; shift 2 2>/dev/null || true
DRY_RUN=0; RESET_PASSWORD=0
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
--reset-password) RESET_PASSWORD=1 ;;
*) echo "未知参数: $arg" >&2; exit 2 ;;
esac
done
usage() { echo "用法: new-agent.sh <id> <中文名> [--dry-run] [--reset-password]"; }
# —— ① 入参校验 ——
[[ -n "$AGENT_ID" && -n "$AGENT_NAME" ]] || { usage; exit 2; }
[[ "$AGENT_ID" =~ ^[a-z][a-z0-9-]{0,23}$ ]] || { echo "id 非法:只允许小写字母开头、[a-z0-9-]、最长 24 字符"; exit 2; }
[[ "$AGENT_NAME" =~ ^[^[:space:]]{2,20}$ ]] || { echo "中文名非法:2–20 个字符且不含空白"; exit 2; }
WORKSPACE="$OPENCLAW_ROOT/workspace-$AGENT_ID"
DB_USER="agent_$AGENT_ID"
PASSWORD_VAR="DB_PASSWORD_$AGENT_NAME"
# —— root 凭据:从 .env 读,绝不硬编码 ——
MYSQL_ROOT_PWD="$(grep -E '^MYSQL_PWD_ROOT=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"'"'"'')"
[[ -n "$MYSQL_ROOT_PWD" ]] || { echo "无法从 $ENV_FILE 读取 MYSQL_PWD_ROOT"; exit 1; }
mysql_root() { docker exec -e MYSQL_PWD="$MYSQL_ROOT_PWD" "$MYSQL_CONTAINER" mysql -uroot -N -B -e "$1"; }
```
- [ ] **3. 冲突检查(默认拒绝覆盖)**
```bash
# —— ② 冲突检查 ——
DB_EXISTS="$(mysql_root "select count(*) from information_schema.schemata where schema_name='$AGENT_ID';")"
USER_EXISTS="$(mysql_root "select count(*) from mysql.user where user='$DB_USER';")"
AGENT_EXISTS="$(python3 -c "
import json
d=json.load(open('$OPENCLAW_ROOT/openclaw.json'))
print(1 if '$AGENT_ID' in (d.get('agents') or {}).get('entries',{}) else 0)
")"
WS_EXISTS=$([[ -d "$WORKSPACE" ]] && echo 1 || echo 0)
if [[ "$RESET_PASSWORD" == "1" ]]; then
[[ "$USER_EXISTS" == "1" ]] || { echo "账号 $DB_USER 不存在,无法重置密码"; exit 1; }
else
[[ "$DB_EXISTS" == "0" ]] || { echo "❌ 库 $AGENT_ID 已存在 —— 已存在请使用 --reset-password,或改用 new-agent.sh 管理"; exit 1; }
[[ "$USER_EXISTS" == "0" ]] || { echo "❌ 账号 $DB_USER 已存在 —— 请使用 --reset-password"; exit 1; }
[[ "$AGENT_EXISTS" == "0" ]] || { echo "❌ agent 条目 $AGENT_ID 已存在"; exit 1; }
[[ "$WS_EXISTS" == "0" ]] || { echo "❌ 目录 $WORKSPACE 已存在"; exit 1; }
fi
```
- [ ] **4. 建库建号授权 + 密码生成**
```bash
# —— ③ 生成密码 ——
NEW_PWD="$(openssl rand -base64 24 | tr -d '/+=' | cut -c1-32)"
# —— ④ SQLdry-run 只打印)——
SQL_CREATE_DB="CREATE DATABASE \`$AGENT_ID\` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;"
SQL_CREATE_USER="CREATE USER '$DB_USER'@'%' IDENTIFIED BY '$NEW_PWD';"
SQL_GRANT="GRANT ALL PRIVILEGES ON \`$AGENT_ID\`.* TO '$DB_USER'@'%';"
if [[ "$DRY_RUN" == "1" ]]; then
echo "[dry-run] 将执行:"; echo " $SQL_CREATE_DB"; echo " $SQL_CREATE_USER"; echo " $SQL_GRANT"
echo "[dry-run] 将写入 $ENV_FILE$PASSWORD_VAR=<32位随机>"
echo "[dry-run] 将创建 workspace$WORKSPACE"
echo "[dry-run] 将执行:openclaw agents add $AGENT_ID --workspace $WORKSPACE --non-interactive"
exit 0
fi
mysql_root "$SQL_CREATE_DB" >/dev/null
if [[ "$RESET_PASSWORD" == "1" ]]; then
mysql_root "ALTER USER '$DB_USER'@'%' IDENTIFIED BY '$NEW_PWD';" >/dev/null
else
mysql_root "$SQL_CREATE_USER" >/dev/null
fi
mysql_root "$SQL_GRANT" >/dev/null
```
- [ ] **5. .env 幂等写入**
```bash
# —— ⑤ 写 .env(同键覆盖,不重复追加)——
if grep -q "^${PASSWORD_VAR}=" "$ENV_FILE"; then
python3 - "$ENV_FILE" "$PASSWORD_VAR" "$NEW_PWD" <<'PY'
import sys
path, key, val = sys.argv[1], sys.argv[2], sys.argv[3]
lines = open(path, encoding='utf-8').read().splitlines()
out = [f'{key}={val}' if l.startswith(key + '=') else l for l in lines]
open(path, 'w', encoding='utf-8').write('\n'.join(out) + '\n')
PY
else
printf '%s=%s\n' "$PASSWORD_VAR" "$NEW_PWD" >> "$ENV_FILE"
fi
chmod 600 "$ENV_FILE"
```
- [ ] **6. 创建 agent + 渲染模板 + 同步中文名**
```bash
# —— ⑥ 创建 agent ——
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"; nvm use 26 >/dev/null 2>&1
openclaw agents add "$AGENT_ID" --workspace "$WORKSPACE" --non-interactive >/dev/null
# —— ⑦ 渲染中文模板(覆盖 openclaw 生成的英文骨架)——
CREATED_AT="$(date '+%Y-%m-%d')"
for tpl in IDENTITY SOUL AGENTS MEMORY; do
sed -e "s/{{AGENT_ID}}/$AGENT_ID/g" \
-e "s/{{AGENT_NAME}}/$AGENT_NAME/g" \
-e "s/{{CREATED_AT}}/$CREATED_AT/g" \
"$TEMPLATE_DIR/$tpl.md.tpl" > "$WORKSPACE/$tpl.md"
done
mkdir -p "$WORKSPACE/memory"
# —— ⑧ 中文名同步进配置 ——
openclaw agents set-identity --agent "$AGENT_ID" --from-identity >/dev/null 2>&1 || \
openclaw agents set-identity --agent "$AGENT_ID" --name "$AGENT_NAME" >/dev/null
```
- [ ] **7. 自检(核心:用新账号实连)**
```bash
# —— ⑨ 自检:证明授权真的生效 ——
if docker exec -e MYSQL_PWD="$NEW_PWD" "$MYSQL_CONTAINER" mysql -u"$DB_USER" -N -B -e "SELECT 1;" "$AGENT_ID" >/dev/null 2>&1; then
SELFCHECK="ok"
else
SELFCHECK="FAILED"
fi
mkdir -p "$LOG_DIR"
printf '[%s] id=%s name=%s user=%s selfcheck=%s dry_run=%s\n' \
"$(date '+%Y-%m-%d %H:%M:%S')" "$AGENT_ID" "$AGENT_NAME" "$DB_USER" "$SELFCHECK" "$DRY_RUN" >> "$LOG_FILE"
cat <<EOF
✅ 已创建 agent$AGENT_NAME$AGENT_ID
DATABASE=$AGENT_ID
USER=$DB_USER
PASSWORD_ENV=$PASSWORD_VAR
WORKSPACE=$WORKSPACE
自检=$SELFCHECK
EOF
[[ "$SELFCHECK" == "ok" ]] || { echo "⚠️ 自检失败:请检查授权"; exit 1; }
```
**验收(Task A**
```bash
# 1) 语法与 dry-run
bash -n ~/.openclaw/scripts/new-agent.sh
bash ~/.openclaw/scripts/new-agent.sh tprobe 测试探针 --dry-run
# 2) 实跑一个临时 agent,验证三件事,然后清理
bash ~/.openclaw/scripts/new-agent.sh tprobe 测试探针
# → 库存在? docker exec -e MYSQL_PWD=... mysql mysql -uroot -e "show databases like 'tprobe';"
# → 账号只对本库有权限? docker exec ... mysql -uroot -e "show grants for 'agent_tprobe'@'%';"
# → 模板全中文? head -3 ~/.openclaw/workspace-tprobe/AGENTS.md
# 3) 幂等:再跑一次应被拒绝(提示已存在)
# 4) 清理:删除测试 agent / 库 / 账号 / workspace / .env 行 / 日志行
```
> ⚠️ 清理必须彻底:`openclaw agents delete tprobe`、`DROP DATABASE`、`DROP USER`、删 workspace、删 `.env` 中的 `DB_PASSWORD_测试探针`。
---
## Task Bskill `agent-provisioning`
**Files**
- Create `~/.openclaw/skills/agent-provisioning/SKILL.md`
**Interfaces**
- ConsumesTask A 的 CLI 契约(`new-agent.sh <id> <中文名>`
- Producesmain 在相应语境下加载本 skill 并调用脚本
**Steps**
- [ ] **1. 写 SKILL.md**
```markdown
---
name: agent-provisioning
description: "新建 OpenClaw agent 的唯一正确流程:当用户说「新建 agent」「创建 agent」「加一个 agent」「给某人开一个助手」时使用。负责为 agent 建专属 MySQL 库、专用账号、中文配置与 workspace。禁止绕过本流程手工建库。"
---
# 新建 agent(唯一正确流程)
## 何时使用
用户表达"新建 / 创建 / 增加一个 agent(助手 / 机器人 / 专属助理)"时。
## 唯一正确做法
```bash
bash ~/.openclaw/scripts/new-agent.sh <id> <中文名>
```
- `<id>`ASCII,小写字母开头,只含 `[a-z0-9-]`,≤24 字符(例:`reading`
- `<中文名>`220 字符,不含空白(例:`阅读`
先与用户确认这两个值,再执行。
## 红线(禁止)
- ❌ 禁止自行拼 SQL 建库、建账号
- ❌ 禁止用 `mysql` / `docker exec` 直接操作数据库来创建 agent
- ❌ 禁止为建库读取或使用 root 凭据
- ❌ 禁止手工创建 `workspace-*` 目录或手改 `openclaw.json` 的 agents 条目
以上任一被绕过,都会造成"库存在但未被备份登记 / 账号缺失 / 配置中英混杂"的不一致。
## 执行后
脚本会输出四行结果(`DATABASE` / `USER` / `PASSWORD_ENV` / `WORKSPACE`)。
把结果转述给用户,并提示:新库将在**次日 03:00 自动进入每日备份**。
## 参数
| 参数 | 用途 |
|---|---|
| `--dry-run` | 只打印将执行的 SQL 与文件操作,不落地(先给用户看过再执行) |
| `--reset-password` | 仅重置已存在 agent 的账号密码(库/账号已存在时用) |
```
**验收(Task B**
```bash
# 1) frontmatter 合法(name + description 齐备,否则会被跳过)
head -5 ~/.openclaw/skills/agent-provisioning/SKILL.md
# 2) 重启后不再出现 Skipping invalid skill,且该 skill 被加载
export NVM_DIR=$HOME/.nvm; . $NVM_DIR/nvm.sh; nvm use 26 >/dev/null
openclaw gateway restart && sleep 20
journalctl --user -u openclaw-gateway --since "2 min ago" | grep -iE 'agent-provisioning|Skipping invalid'
```
---
## Task C:每日备份脚本改造(动态发现)
**Files**
- Modify `/usr/local/bin/backup-agent-dbs.sh`(需 `sudo`
**Interfaces**
- ConsumesMySQL 中由 Task A 创建的 `agent_<id>` 账号与 `<id>`
- Produces:所有 agent 库每日备份,无需人工登记
**Steps**
- [ ] **1. 先备份原脚本**
```bash
sudo cp /usr/local/bin/backup-agent-dbs.sh /usr/local/bin/backup-agent-dbs.sh.bak-20260916
```
- [ ] **2. 把硬编码 `DB_MAP` 换成动态发现**
删除原 `declare -A DB_MAP=(...)`,替换为:
```bash
# ===== 动态发现:agents.entries 的 id ∩ MySQL 实际库(排除系统库)=====
SYSTEM_DBS="mysql|information_schema|performance_schema|sys"
AGENT_IDS="$(python3 -c "
import json
d=json.load(open('/home/yangxuan/.openclaw/openclaw.json'))
print('\n'.join(sorted((d.get('agents') or {}).get('entries',{}).keys())))
")"
DB_LIST="$(mysql_root "select schema_name from information_schema.schemata where schema_name not regexp '^(${SYSTEM_DBS})\$';")"
# 交集:只备份「配置里存在的 agent」且「库真实存在」的
TARGETS=""
while IFS= read -r db; do
[ -n "$db" ] || continue
echo "$AGENT_IDS" | grep -qx "$db" && TARGETS="$TARGETS $db"
done <<< "$DB_LIST"
TARGETS="$(echo $TARGETS)"
echo "[${TIMESTAMP}] 备份目标:${TARGETS}" >> "$LOG_FILE"
```
- [ ] **3. 目录映射改为按 id 推导**
```bash
ws_dir_for() { # $1 = agent id → workspace 目录名
[ "$1" = "main" ] && echo "workspace" || echo "workspace-$1"
}
```
并把原循环改为遍历 `$TARGETS`,备份目录用 `"$BACKUP_ROOT/$(ws_dir_for "$DB")/db"`
- [ ] **4. 不再硬编码密码**
```bash
# 从 .env 读(脚本内不再出现明文)
ENV_FILE="/home/yangxuan/.openclaw/.env"
MYSQL_PASS="$(grep -E '^MYSQL_PWD_ROOT=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"'"'"'')"
PG_PASS="$(grep -E '^PGPASSWORD=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"'"'"'')"
```
- [ ] **5. 30 天清理与 git 提交段改为遍历动态目录**
原清理循环 `for WS in workspace workspace-resume ...` 改为遍历 `$TARGETS` 推导出的目录。
`git add "workspace-${WS}/db/"` 同理。
**验收(Task C**
> ⚠️ **实测教训(2026-09-16,已造成真实故障)**
> **绝不要用 `sudo` 跑本脚本**:生产路径是 **yangxuan 的 crontab**root crontab 为空)。
> 用 `sudo` 跑会生成 **root 属主**的备份目录/文件,导致**次日 3:00 的 yangxuan cron 写不进去**
> 备份从此天天失败。实测证据:`workspace-{juaner,wellness,tab}/db` 曾是 root 属主,
> 这 3 个库自 **2026-08-26** 起每天 `❌ 备份失败`(日志 `workspace/db/backup.log`)。
```bash
# 0) 前置:修复 root 属主的 db 目录(否则这 3 个库必然继续失败)
for d in /home/yangxuan/.openclaw/workspace*/db; do
[ -d "$d" ] && [ "$(stat -c %U "$d")" = "root" ] && sudo -n chown -R yangxuan:yangxuan "$d"
done
stat -c '%U:%G %n' /home/yangxuan/.openclaw/workspace*/db # 应全部为 yangxuan:yangxuan
# 1) 语法
bash -n /usr/local/bin/backup-agent-dbs.sh
# 2) 手动跑一次(以 yangxuan 身份,**不加 sudo**
/usr/local/bin/backup-agent-dbs.sh; tail -20 ~/.openclaw/workspace/db/backup.log
# → 期望日志出现「备份目标:…」且成功的库数 = 库真实存在且已在 agents.entries 中的 agent 数
# 3) 确认备份文件落在各 workspace 的 db/ 下且已 gz、属主为 yangxuan
ls -la ~/.openclaw/workspace-*/db/*_$(date +%Y%m%d).sql.gz 2>/dev/null | head
# 4) 确认脚本内无明文密码
grep -nE 'MYSQL_PASS="|PG_PASS="' /usr/local/bin/backup-agent-dbs.sh
```
> **另一处必须知道的差异**`.env` 中**没有** `MYSQL_PWD_ROOT`(只有 `MYSQL_PWD`)。
> 正确写法是「优先 `MYSQL_PWD_ROOT`、回退 `MYSQL_PWD`」,这样 Task A/E 之后补上该键会自动生效。
> 另注意:`openclaw` 不在 `agents.entries`(当前只有 11 个 id),**它必须先进入该配置才会被动态发现**(Task E 处理)。
---
## Task Dmain 红线 + 文档索引
**Files**
- Modify `~/.openclaw/workspace/AGENTS.md`(在既有「## 红线」章节内追加)
- Modify `~/.openclaw/docs/README.md`(登记实现计划)
**Steps**
- [ ] **1. 在 `workspace/AGENTS.md` 的「## 红线」章节追加两条**
```markdown
- **创建 agent 红线**:新建 agent 必须且只能执行 `bash ~/.openclaw/scripts/new-agent.sh <id> <中文名>`
禁止自行拼 SQL、禁止用 `mysql`/`docker exec` 建库、禁止为建库读取任何 root 凭据、禁止手工创建 `workspace-*` 或手改 agents 配置。
- **数据库红线**:每个 agent 只能访问自己的库(库名 = 自己的 agent id),账号为 `agent_<id>`;禁止使用 root、禁止跨库写入。
```
- [ ] **2. `docs/README.md` 文档表追加一行**
```markdown
| 4 | `agent-创建规范-实现计划.md` | 上述设计的实现计划:任务切分(A 脚本+模板 / B skill / C 备份改造 / D 红线 / E 存量)、关键代码与验收标准 |
```
**验收(Task D**
```bash
grep -n '创建 agent 红线' ~/.openclaw/workspace/AGENTS.md
grep -c 'agent-创建规范-实现计划' ~/.openclaw/docs/README.md # 期望 1
```
---
## Task E:存量改造(12 个 agent,依赖 A)
**Files**
- Modify `~/.openclaw/.env`(补变量)
- Modify 各 `~/.openclaw/workspace-<id>/AGENTS.md`(补/改数据库段)
**Steps**
- [ ] **1. 已缺库的 4 个:按 A 的流程补建**
`note`(笔记)、`pbs`(PBS备份) 直接走 `new-agent.sh` 的**建库建号部分**(因 agent 已存在,需用 `--reset-password` 之外的分支 → 实际用 `--adopt-existing` 或分步执行:建库建号授权 + 手工补文档)。
`sql`(SQL):保留远程 VPS 业务库定位,另建私有库。
`openclaw`:先确认纳入 `agents.entries``agentToAgent.allow` 的影响,再建库建号。
- [ ] **2. 已有库的 8 个:建专用账号并改文档**
`main` `juaner` `wellness` `tab` `finances` `fitness` `resume` `travel`
-`agent_<id>` 账号 + `GRANT ALL ON \`<id>\`.*` + 写 `DB_PASSWORD_<中文名>`
- **改各自 `AGENTS.md`**:删掉"用 root 连接"的表述,替换为 §Task A 的数据库段
- [ ] **3. 每改一个 agent 立即验证**
```bash
docker exec -e MYSQL_PWD="<新密码>" mysql mysql -uagent_<id> -N -B -e "SELECT 1;" <id>
```
**验收(Task E**
```bash
# 全部 12 个 agent 都有库与账号
docker exec -e MYSQL_PWD="$MYSQL_PWD_ROOT" mysql mysql -uroot -e \
"select user from mysql.user where user like 'agent\_%';"
# 各 workspace 的 AGENTS.md 不再出现 root 直连表述
grep -rn 'u root' ~/.openclaw/workspace*/AGENTS.md
```
---
## Self-Review(计划自查)
| 检查 | 结果 |
|---|---|
| Spec 覆盖 | §2 命名→A 的校验;§3 组件→A/B;§4 九步→A 的 ①–⑨;§5 模板→A Step1;§6 幂等安全→A Step3/5;§7 验证→A 自检;**§8 存量→E**;§10 备份→C**§11 六条→B(2) + D(1) + A(日志/提示)** ✅ |
| 占位符扫描 | 无 TBD/TODO;所有代码块均给出可执行内容 |
| 类型/命名一致 | `agent_<id>`、`DB_PASSWORD_<中文名>`、`$PASSWORD_VAR`、`ws_dir_for()` 在 A/C/E 中一致 ✅ |
| 已知待现场确认 | ① `openclaw agents add` 生成的文件清单(决定模板是覆盖还是补充)② `set-identity --from-identity` 对 IDENTITY.md 的解析要求 —— 实现时先验证,若不符则用 `--name` 兜底(A Step6 已写兜底分支) |
@@ -0,0 +1,237 @@
# agent 创建规范与数据库自动化(设计)
> **状态**:设计已确认(2026-09-16)· **待实现**
> **适用**bk02 上的 OpenClaw(前置阅读:`bk02-openclaw-系统说明.md`
> **决策记录**:见 §12
>
> ⚠️ 本文不含明文口令。
---
## 1. 目标与范围
**目标**
1. **main agent 在对话中即可创建新 agent**,且新 agent 的配置(`IDENTITY.md`/`SOUL.md`/`AGENTS.md`/`MEMORY.md``openclaw.json``name`/`identity.name`**全部为中文**。
2. **每个 agent 自动获得专属 MySQL 库**(库名 = `agent_id`+ **专用账号**(只授权自己的库,不再用 root)。
3. 新建 agent 的库**次日自动进入每日备份**,无需人工登记。
**范围**
- 新增:`new-agent.sh`provisioning 脚本)、中文模板一组、`agent-provisioning` skill
- 改造:既有每日备份脚本 `backup-agent-dbs.sh`(硬编码 → 动态发现)
- **不修改** OpenClaw 自身(纯配置/文件层扩展)
**明确不做**:见 §9。
---
## 2. 命名与标识规范
| 概念 | 形式 | 示例 |
|---|---|---|
| `agent_id` | ASCII slug,正则 `^[a-z][a-z0-9-]{0,23}$` | `reading` |
| 中文名 | 26 个汉字 | `阅读` |
| MySQL 库 | **= `agent_id`** | `reading` |
| MySQL 账号 | `agent_<id>` | `agent_reading` |
| 密码变量 | `DB_PASSWORD_<中文名>`(写入 `~/.openclaw/.env` | `DB_PASSWORD_阅读` |
| workspace | `~/.openclaw/workspace-<id>` | `workspace-reading` |
| agentDir | `~/.openclaw/agents/<id>/agent` | — |
**中文只用于展示层**`name``identity.name`、文档正文、`.env` 变量名后缀)。
`id` / 库名 / 账号 / 目录名一律 ASCII —— 依据:既有的 `Obsidian``obsidian`(仅大小写不同)曾导致 `openclaw backup create --verify`*portable path collision* 失败。
---
## 3. 组件与职责
| 组件 | 路径 | 职责 |
|---|---|---|
| provisioning 脚本 | `~/.openclaw/scripts/new-agent.sh` | **唯一特权入口**:建库、建账号、授权、写 `.env`、创建 agent、渲染模板、设置中文名、自检 |
| 中文模板 | `~/.openclaw/scripts/agent-templates/{IDENTITY,SOUL,AGENTS,MEMORY}.md.tpl` | 新建 agent 的文档骨架 |
| skill | `~/.openclaw/skills/agent-provisioning/SKILL.md` | 中文;定义触发词、参数、约束、输出格式;约束 main **只能调用脚本** |
| 审计日志 | `~/.openclaw/workspace/db/agent-provision.log` | 脚本每次执行追加一行(时间/参数/结果),供事后对账 |
| 备份脚本(改造) | `/usr/local/bin/backup-agent-dbs.sh` | 见 §10 |
**设计要点**
- 特权动作(root 建库)只存在于脚本内;main 的 skill 里写死"只允许调用脚本"。
- skill 与 `~/.openclaw` 同处一个 git 仓库,规范可版本化、可追溯。
---
## 4. 数据流(main 创建 agent
```
用户:“新建一个 agent,id 用 reading,中文名 阅读”
main 读 skills/agent-provisioning/SKILL.md(约束 + 流程)
main 执行:bash ~/.openclaw/scripts/new-agent.sh reading 阅读
脚本(幂等,逐步输出):
① 入参校验:id 正则 / 中文名非空且长度合法
② 冲突检查:库、agent 条目、workspace 目录任一已存在 → 失败退出(见 §6)
③ 生成 32 位随机密码
④ MySQLroot 凭据取自 ~/.openclaw/.env 的 MYSQL_PWD_ROOT):
CREATE DATABASE `<id>` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
CREATE USER 'agent_<id>'@'%' IDENTIFIED BY '<随机密码>';
GRANT ALL PRIVILEGES ON `<id>`.* TO 'agent_<id>'@'%';
⑤ 写入 ~/.openclaw/.envDB_PASSWORD_<中文名>='<随机密码>'
(同键则替换,不重复追加;.env 已在 .gitignore
⑥ openclaw agents add <id> --workspace ~/.openclaw/workspace-<id> --non-interactive
⑦ 渲染中文模板到 workspace-<id>/(覆盖 openclaw 生成的英文骨架)
⑧ openclaw agents set-identity --agent <id> --from-identity
(从 IDENTITY.md 读中文名写入配置)
⑨ 自检(§7)并输出汇总:库名 / 账号 / 凭据变量 / workspace / 下一步
```
**为什么用 `--from-identity`**:中文名先落在 `IDENTITY.md`(人可读),再一条命令同步进 `openclaw.json`,避免两处手工维护不一致。
---
## 5. 中文模板
四件套(全中文,`.tpl` 内用占位符 `{{AGENT_ID}}``{{AGENT_NAME}}`):
- **`IDENTITY.md`** —— 我是谁(含中文名、emoji)
- **`SOUL.md`** —— 性格与表达风格
- **`AGENTS.md`** —— 工作规范(**核心是数据库段**)
- **`MEMORY.md`** —— 长期记忆骨架
`AGENTS.md.tpl` 的数据库段(沿用 `workspace-sql` 已验证的范式):
```markdown
## 数据库规范
- 默认库:`{{AGENT_ID}}` —— 这就是你自己的库
- 账号:`agent_{{AGENT_ID}}`
- 连接(推荐):`~/.openclaw/scripts/db-conn.sh {{AGENT_ID}}`(交互式)或 `db-conn.sh {{AGENT_ID}} --sql "select database()"`
- 口令:由该脚本自动从 `~/.openclaw/.env` 读取(键名 `DB_PASSWORD_{{AGENT_NAME}}`),口令不会出现在命令行中
- 禁止:使用 root、使用 docker exec、访问其他 agent 的库、跨库写入
- 破坏性语句(DROP / TRUNCATE / 无条件 DELETE)必须先请示
```
---
## 6. 幂等、错误处理与安全
| 场景 | 行为 |
|---|---|
| id 非法 / 中文名为空 | 立即失败并打印用法 |
| 库或 agent 或 workspace **已存在** | **默认失败**(不覆盖、不改动);仅 `--reset-password` 才重置账号密码 |
| 中途失败 | 已完成的步骤保留;重跑时明确提示"已完成到第 N 步",不静默改写 |
| `.env` 写入 | 幂等替换(同键覆盖,避免重复行) |
| SQL 注入 | id 必须通过白名单正则后才参与拼接 |
| 凭据 | 脚本**不硬编码**密码,从 `~/.openclaw/.env` 读;生成的密码只写 `.env` |
---
## 7. 验证方式
- `new-agent.sh --dry-run`:打印将执行的 SQL 与文件操作,**不落地**
- 创建后自动自检:
1. 库存在
2. **用新账号实连一次 `SELECT 1`**(证明授权真的生效)
3. `workspace-<id>/` 四件套齐全
4. 输出可直接复制给用户的凭据行
---
## 8. 存量处置(所有 agent
**范围:全部 11 个 agent 都要有库 + 专用账号**(原写 12,含已废弃的 `openclaw`2026-09-16 校正)。
| 分组 | agent | 动作 |
|---|---|---|
| 已有库,需改造 | `main` `juaner` `wellness` `tab` `finances` `fitness` `resume` `travel` | 建 `agent_<id>` 账号 + 授权 + 改各自 `AGENTS.md` 数据库段(由 root 直连改为专用账号) |
| 缺库需新建 | `note`(笔记) `pbs`(PBS备份) | 建库建号 + 补文档 |
| 特例 | `sql`(SQL) | 保留其**远程 VPS 业务库**定位,另给一个私有库做工作区 |
| 待纳入 | `openclaw` | 当前不在 `agents.entries``agentToAgent.allow`;按「所有 agent」口径**纳入并建库建号**(纳入前确认不影响既有行为) |
> 存量改造是**一次性迁移**,建议作为独立步骤执行(含改 `.env` 变量与各 agent 文档),与新建流程分开验证。
---
## 9. 非目标(YAGNI
- 不做可视化界面 / 批量重建工具
- 不做库结构版本迁移工具
- 不去改 skill 机制使其按 agent 隔离 —— OpenClaw 的 `skills.entries` 是**全局开关(52 项,仅 `enabled`)**,无法按 agent 配置;权限隔离由 **MySQL 账号**承担(这也是"专用账号"从建议变为必需的原因)
---
## 10. 每日备份改造
**现状**(已存在,非自建部分):`crontab 0 3 * * * /usr/local/bin/backup-agent-dbs.sh`
- 逐库 `mysqldump --single-transaction --routines --triggers --events`**用 root**
- 备份到各自 workspace 的 `db/`(如 `workspace-resume/db/resume_20260916.sql.gz`),另留一份 `*_latest.sql`
- 清理 30 天前备份
- 结束后 `git commit` + **push 到自建 Gitea**
**问题**:库清单是**硬编码的 8 条 `DB_MAP`** ⇒ **新建 agent 不会被备份**
**改造目标**
1. **动态发现**:备份目标 = `agents.entries` 的 id ∩ `information_schema.schemata`(排除 `mysql`/`information_schema`/`performance_schema`/`sys`),这样 provisioning 建的库**次日自动纳入**
2. **不硬编码密码**:改为从 `~/.openclaw/.env` 读(而非脚本内明文)
3. 保留策略(30 天)与 **push 到 Gitea 保持现状**Gitea 为自建)
4. PostgreSQL`openclaw` 库)分支保持不动
---
## 11. 技能强制性 = 档 ①(纯规范,不改环境)
**已明确接受的前提**:不剥夺凭据、不收窄 sudo、不启用 exec 审批。因此 main **技术上仍可能**从 `.env` / 备份脚本取得 root 自行建库 —— 规范能大幅降低概率,但**不能归零**
在纯规范档下,把约束强化到六点:
1. **写入 main 的「红线」章节**`workspace/AGENTS.md` 已有该章节):
> 创建 agent 必须且只能执行 `bash ~/.openclaw/scripts/new-agent.sh <id> <中文名>`
> 禁止自行拼 SQL、禁止用 `mysql`/`docker exec` 建库、禁止为建库读取任何 root 凭据。
2. **SKILL.md 的 `description` 精确化**(skill 触发的唯一依据):写明触发场景与关键词("新建 agent""创建 agent""加一个 agent")。
3. **让正确路径比绕过更省事**(行为引导):脚本一条命令完成 9 步;绕过则需自行拼 SQL、处理 `.env`、写四个中文模板 —— 复杂度差本身就是约束。
4. **脚本内不硬编码密码**(见 §6)。
5. **脚本自带轻量审计**:每次执行追加一行到 `workspace/db/agent-provision.log`;**不改环境**,但事后可对账 —— 库中多出的账号若不在日志里,即为绕过证据。
6. **阻断态显式提示**:出现"库已存在但账号缺失"等异常时,输出"请改用 `new-agent.sh`"的明确指引。
---
## 12. 决策记录
| # | 决策点 | 结论 | 日期 |
|---|---|---|---|
| 1 | 落地形态 | **方案 B**:脚本 + skill,由 main 调用(否决纯人工脚本、否决把 root 交给 main 自行拼 SQL | 2026-09-16 |
| 2 | 目标库与账号 | **本机 docker MySQL**;**每个 agent 专用账号**(停用 root 直连) | 2026-09-16 |
| 3 | 存量范围 | **所有 agent**(含 `openclaw`)都要有库与账号 | 2026-09-16 |
| 4 | 中文范围 | 展示层全中文;`id`/库名/账号/目录名保持 ASCII | 2026-09-16 |
| 5 | 备份 | 改造为动态发现;**保持 push 到自建 Gitea** | 2026-09-16 |
| 6 | 技能强制性 | **档 ①(纯规范)**:不改凭据、不收窄 sudo、不加 exec 审批 | 2026-09-16 |
| 7 | 授权模型 | skill 层无法按 agent 隔离(`skills.entries` 全局)⇒ 隔离必须由 MySQL 账号承担 | 2026-09-16 |
---
## 附:实现时需现场确认的两点
1. `openclaw agents add` 生成的骨架文件清单与内容 —— 决定模板是**覆盖**还是**补充**
2. `set-identity --from-identity``IDENTITY.md` 格式的具体要求(字段名/解析规则)
---
## 附录 A:实现期间的实测发现(2026-09-16)
> 本节回答 §「附:实现时需现场确认的两点」,并记录实现中撞出的偏差与处置。
| # | 发现 | 处置 |
|---|---|---|
| 1 | `.env` 中**没有** `MYSQL_PWD_ROOT`(真实键名是 `MYSQL_PWD`);且计划里的 `grep` 写法在 `set -euo pipefail` 下会因无匹配**静默退出**(连报错都没有) | 脚本抽出 `read_env_var()` 并做 `MYSQL_PWD_ROOT → MYSQL_PWD` 回退 |
| 2 | `openclaw agents add` 生成 `AGENTS/BOOTSTRAP/IDENTITY/SOUL/USER.md` **+ 一个 `.git` 仓库**,且**不生成** `MEMORY.md`/`memory/`;存量 12 个 workspace 都没有 `.git` | 脚本渲染 5 个中文模板(补齐 MEMORY/USER),并删除 `BOOTSTRAP.md`(身份已定,避免首启"起名仪式")与 `.git`(避免嵌套仓库) |
| 3 | `set-identity --from-identity` **只认英文标签** `- Name: xxx`,对中文模板的 `- **名称:**` 解析失败(`No identity data found` | 设计目标(配置中存中文名)由 `--name` 兜底达成;脚本保留兜底分支。**这不是 bug,是既定偏差** |
| 4 | 存量 `.env` 里 6 行 `DB_PASSWORD_<中文名>` 的**值与 MySQL root 密码相同** | 意味着现状下"每 agent 一账号"并未真正隔离。Task E 将生成**独立随机口令**并替换存量行 |
| 5 | 同机 3 个 `workspace-{juaner,tab,wellness}/db` 属主为 root → 这 3 个库自 2026-08-26 起**每天备份失败** | 已 `chown` 修复;备份脚本验收明确改为**不加 `sudo`**(生产路径是 yangxuan 的 crontab;用 sudo 跑正是该事故成因) |
| 6 | `agents delete` 会连 workspace 一起删,但留下 `~/.openclaw/agents/<id>/` 空壳 | 清理流程需手工 `rm -rf`(已写入脚本注释与计划文档) |
| 7 | 中文名含 `&` 时,调用侧若不加引号会被 shell 解析;实测已导致一次意外创建 | 已回灌进 `agent-provisioning` skill**必须写成 `<id> '<中文名>'`** |
| 8 | **中文键名不可能作为环境变量暴露给 agent** —— 三条实测依据:(a) gateway 进程 `/proc/<pid>/environ` 里只有 `MYSQL_PWD_ROOT`/`DB_PASSWORD_ROOT`**没有** `DB_PASSWORD_<中文名>`(b) service 的 `OPENCLAW_SERVICE_MANAGED_ENV_KEYS` 是白名单,只列 9 个键、不含 `DB_PASSWORD_*`,而键数随 agent 数量增长,维护白名单不现实;(c) 官方把凭据注入 agent 执行环境的机制 `openclaw secrets store --kind env` 要求名称匹配 `^[A-Z][A-Z0-9_]{0,127}$`(**纯大写 ASCII**),中文键名语法上就不合法 | ⇒ 以「环境变量」形式暴露中文键名**不可行**,改用统一入口 `~/.openclaw/scripts/db-conn.sh <agent_id> [--sql "<SQL>"] [--print]`:按 id 反查 `agents.entries.<id>.name` → 读 `.env``DB_PASSWORD_<中文名>` → 经 `MYSQL_PWD` 环境变量注入 `docker exec`(口令不进 argv、不进 stdout`--print` 只打印占位符)。已同步:11 个 `AGENTS.md``AGENTS.md.tpl``new-agent.sh` 汇总输出、本文 §5 示例。**§2 命名规范里的「密码变量 `DB_PASSWORD_<中文名>`」依然成立,但它的定位是 `.env` 内的存储键名,不再是 agent 的环境变量** |
**审计日志格式(Task E 解析用)**
`[时间] id=… name=… user=… mode=create|reset-password selfcheck=… dry_run=…`
+334
View File
@@ -0,0 +1,334 @@
# bk02 openclaw 系统说明
> **用途**:本机 OpenClaw 系统的总说明。**新会话 / 新人接手请先读本文件**,无需依赖任何历史对话。
> **配套**`openclaw-升级与维护.md`2026-09-16 升级 Node 22→26 与清理 4.6G 的实测记录)
> **主机**bk02 / `xuan-asus-nj` · Debian 12 bookworm · 更新时间 2026-09-16
>
> ⚠️ 本目录**不含明文口令**,凭据位置见 §6。
---
## 0. 30 秒速览
| 项 | 值 |
|---|---|
| 服务 | `openclaw-gateway.service`**用户级** systemd,必须用 `systemctl --user` |
| 版本 | OpenClaw **2026.9.4** (3a9d69d) |
| 运行时 | nvm **Node v26.8.2****不要**用系统 `/usr/bin/node` 22.x,版本不够) |
| 本机监听 | `127.0.0.1:18789`+ `[::1]:18789`),不对外暴露 |
| 访问入口 | **`https://bk02.baiji-algieba.ts.net`**tailscale serve,仅 tailnet 内可达) |
| 状态目录 | `~/.openclaw`(约 1.5G |
| 存储 | SQLite**不支持** PostgreSQL/MySQL,见 §5 |
**最常用的三条命令**(都在 `~/.openclaw` 主机上执行):
```bash
export NVM_DIR=$HOME/.nvm; . $NVM_DIR/nvm.sh; nvm use 26 # 每次登录先做,否则 openclaw 命令不在 PATH
openclaw doctor # 健康检查(问题与修复建议都在这里)
journalctl --user -u openclaw-gateway -f # 实时日志
```
---
## 1. 主机与访问
| 项 | 值 |
|---|---|
| 主机名 | `xuan-asus-nj`tailnet 名 `bk02` |
| 系统 | Debian GNU/Linux 12 (bookworm),内核 6.1.0-50-amd64 |
| 内网 IP | `192.168.3.14`enp4s0f2 |
| tailscale IP | `100.115.195.192` |
| 登录用户 | `yangxuan`(凭据由机主掌握) |
| 磁盘 | 根分区 109G,当前约 24G23% |
| 内存 | 7.6Ggateway 进程 RSS ≈ 580MB |
| 容器 | postgres(pgvector)、mysql、clashdocker,与 openclaw 无耦合,可作 agent 工具数据源) |
**从 wit01 的实测链路**`tailscale ping bk02``via DERP(lian) ≈ 23ms`**非直连**wit01 侧 `MappingVariesByDestIP: true`,对称 NAT)。因此经 tailscale 访问比局域网直连多约 120ms/请求,属正常现象。
---
## 2. 架构
```
浏览器 / App
│ https://bk02.baiji-algieba.ts.net ← tailscale serve 在 443 终止 TLS
本机回环 127.0.0.1:18789 ← openclaw gatewaynode 进程)
├─ 配置 ~/.openclaw/openclaw.json
├─ 状态 ~/.openclaw/state/openclaw.sqlite (共享状态)
├─ 会话 ~/.openclaw/agents/<id>/agent/openclaw-agent.sqlite (每 agent 一个)
├─ 插件 ~/.openclaw/npm/projects/<plugin>/
└─ 工作区 ~/.openclaw/workspace*/ (agent 的文件空间)
```
| 组件 | 说明 |
|---|---|
| gateway | `openclaw .../dist/index.js gateway --port 18789`,启动约 **14.5s**(首次更久) |
| tailscale serve | `gateway.tailscale.mode = serve`,gateway 启动时自动声明/恢复 HTTPS 路由 |
| 前端 | Control UIHTTP/2 + Brotli,压缩后约 348KB9 个资源) |
| 协议 | HTTP + WebSocketUI 的所有数据与操作走 WS RPC) |
**ExecStart 实际内容**
```
/home/yangxuan/.nvm/versions/node/v26.8.2/bin/node --max-old-space-size=3913 \
/home/yangxuan/.nvm/versions/node/v26.8.2/lib/node_modules/openclaw/dist/index.js \
gateway --port 18789
```
---
## 3. 关键路径速查
| 用途 | 路径 |
|---|---|
| 主配置 | `~/.openclaw/openclaw.json` |
| 环境变量/密钥 | `~/.openclaw/.env` |
| 共享状态库 | `~/.openclaw/state/openclaw.sqlite` |
| agent 会话库 | `~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite` |
| 迁移归档 | `~/.openclaw/agents/<id>/session-sqlite-import-archive/`(**保留,勿删**,见 §10) |
| 日志(文件) | `/tmp/openclaw/openclaw-YYYY-MM-DD.log` |
| 日志(journal | `journalctl --user -u openclaw-gateway` |
| 插件安装目录 | `~/.openclaw/npm/projects/` |
| 备份归档 | `~/openclaw-backups/*.tar.gz` |
| 服务定义 | `~/.config/systemd/user/openclaw-gateway.service` |
| 本目录(文档) | `~/.openclaw/docs/` |
| 配置 git 仓库 | `~/.openclaw/.git`(分支 `314` |
**agent 清单(11 个)**`main` `note` `tab` `sql` `pbs` `wellness` `finances` `fitness` `resume` `travel` `juaner`
---
## 4. 服务与运维命令
```bash
# —— 必须的环境准备 ——
export NVM_DIR=$HOME/.nvm; . $NVM_DIR/nvm.sh; nvm use 26
# —— 生命周期 ——
openclaw gateway start
openclaw gateway restart
openclaw gateway stop --force # 不加 --force 会被拒绝(保护性设计)
systemctl --user status openclaw-gateway
systemctl --user is-active openclaw-gateway
# —— 健康与诊断 ——
openclaw doctor # 总健康检查 + 修复建议
openclaw doctor --fix # 应用修复(会迁移遗留文件、轮转配置备份)
openclaw status
openclaw plugins list
openclaw sessions --all-agents
# —— 备份(改动前必做)——
openclaw backup create --verify --output ~/openclaw-backups
# —— 离线维护(必须先停 gateway)——
openclaw doctor --session-sqlite compact --session-sqlite-all-agents
openclaw doctor --state-sqlite compact --json
# —— 升级 ——
openclaw update status # 看当前版本与可用版本
openclaw update --dry-run --yes # 预览计划
openclaw update --yes # 执行(注意 Node 版本要求,见 §9)
```
---
## 5. 存储:只能用 SQLite
**官方结论**`openclaw update` 相关文档原文):
> *SQLite remains the supported runtime store. Preparation for PostgreSQL should improve the existing store owners and their tests **before adding a driver or configuration option**.*
| 检查 | 结果 |
|---|---|
| 存储实现 | Node 内置 `node:sqlite`(无外部数据库依赖) |
| 官方文档 `mysql` / `mariadb` | **0 次命中** |
| 代码里的 PostgreSQL/MySQL 字样 | 来自 **SQL 语法高亮方言**与报错文案,**非存储后端** |
| 表结构示例 | `session_nodes` / `transcript_events` / `session_transcript_archives`(BLOB) / `memory_index_*` 等 |
| 库规模(2026-09-16 | 共享状态库 12.7MB;各 agent 库合计约 143MB;共 35 个库(`agents/openclaw` 的 sqlite 为遗留,已于同日移入 `backups/removed-20260916/` |
**推论**:本机 docker 的 postgres/mysql **不能**替代 openclaw 的存储;但可以经 `sql-toolkit` 等工具**给 agent 当数据源**(配置里已有 `"MySQL":{"enabled":true}`),两者是不同层面。
---
## 6. 配置与凭据
| 项 | 位置(不记录明文) |
|---|---|
| gateway 认证 | `openclaw.json``gateway.auth``mode: password` |
| 允许来源 | `gateway.controlUi.allowedOrigins` |
| 受信代理 | `gateway.trustedProxies`(含 tailnet 段) |
| 模型/渠道密钥 | `~/.openclaw/.env` + `openclaw.json``secrets` 段;systemd 通过 `OPENCLAW_SERVICE_MANAGED_ENV_KEYS` 注入 |
| 主机登录 | 由机主掌握(ssh `yangxuan@bk02` |
| 备份包 | `~/openclaw-backups/*.tar.gz`**含凭据,勿外发** |
**配置备份环(官方机制,勿手删)**
```
openclaw.json ← 当前配置
openclaw.json.bak / .bak.1 … .bak.4 ← 每次配置写入自动轮转的备份环
openclaw.json.last-good ← 解析失败时的自动恢复源
openclaw.json.pre-update ← 升级前快照
```
---
## 7. 插件与渠道
安装位置 `~/.openclaw/npm/projects/`,版本应与核心(2026.9.4)一致。
```bash
openclaw plugins list
openclaw plugins update <name> # 同步到当前核心版本
openclaw plugins uninstall <name> --force # 注意是 --force(无 --non-interactive 参数)
openclaw daemon install # 服务定义重建(会顺带修正 Node 路径)
```
常见插件:`feishu``searxng``deepseek`provider)、`openclaw-weixin``dingtalk-connector``memory-core``ollama`
渠道(钉钉/微信等)在 gateway 启动日志中会打印 `starting ... provider``client ready`
---
## 8. 备份、回滚与 Git 仓库
### 8.1 备份
```bash
openclaw backup create --verify --output ~/openclaw-backups
```
- **`--verify` 必须能通过**才算可靠备份
- ⚠️ 若 workspace 下存在**仅大小写不同**的重复目录(曾发生 `skills/Obsidian``skills/obsidian`),会因 *portable path collision* 导致验证失败 → 用 `diff -r` 确认后把重复项移出(`mv` 到备份区,不要 `rm`),再重新备份
### 8.2 配置仓库(Gitea
| 项 | 值 |
|---|---|
| 仓库 | `~/.openclaw`(本身是 git 仓库,分支 `314` |
| remote | `https://gitea.climbcube.cn/yangxuan/openclaw-config.git` |
| 自动提交 | `auto-commit-config.sh`,每 6 小时 `git add -A` + commit + push |
| 提交信息 | `auto: sync OpenClaw config <时间>` / `auto: agent DB backup <日期>` |
**手动提交注意**:该脚本在 `git status` 为空时会**直接退出、不 push**。因此手动提交后**必须自己 push**,否则提交永远不会上远端:
```bash
cd ~/.openclaw && git add -A && git commit -m "..." && git push origin 314
```
**隐私红线**`.gitignore` 已加固,排除大体积/隐私数据:
```gitignore
workspace-*/data/
agents/*/session-sqlite-import-archive/
```
(曾发生 `workspace-juaner/data/私聊_*.json` 等被自动提交并推送到 Gitea`.git` 一度涨到 199M。历史重写未做。)
### 8.3 回滚
```bash
# 服务定义
cp ~/.config/systemd/user/openclaw-gateway.service.bak ~/.config/systemd/user/openclaw-gateway.service
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway
# 版本回退(注意:nvm v25.9.0 与旧 openclaw 已于 2026-09-16 删除,需重新下载)
nvm install 25.9.0 && nvm exec 25.9.0 npm i -g openclaw@2026.8.1
```
数据恢复用 `~/openclaw-backups/` 里的验证备份。
---
## 9. 排查手册(按症状查)
### 9.1 「页面打开慢 / 卡顿」
**先分层定位,不要凭感觉**
```bash
# ① 服务端自身是否慢(应 <10ms)
curl -o /dev/null -s -w "code=%{http_code} ttfb=%{time_starttransfer}s\n" http://127.0.0.1:18789/
# ② 服务端 RPC 耗时统计(WS RPC 是 UI 的数据通道)
journalctl --user -u openclaw-gateway --since "10 min ago" --no-pager \
| grep -oE 'res ✓ [a-zA-Z.]+ [0-9]+ms' | sort -t' ' -k3 -rn | head -15
# ③ 是否落在 gateway 重启后的冷启动窗口
cat ~/.openclaw/logs/gateway-restart.log; journalctl --user -u openclaw-gateway --since "5 min ago" | grep -i started
```
判断基线(2026-09-16 实测):
| 层 | 正常值 | 异常信号 |
|---|---|---|
| 服务端首页 | 本地 **45ms** | > 500ms |
| WS RPC | 稳态 **60300ms**,无 >1s 调用 | 出现 1.54.4s 的一批调用 ⇒ **gateway 刚重启**(冷启动约 20s,之后恢复) |
| 前端资源 | 压缩后 348KB,9 资源并发 **0.160.8s** | — |
| 链路 | 经 DERP 中继,多约 120ms/请求 | — |
> **常见误判**:把"页面卡"归因于"数据/缓存太多"。实测 `main` 库仅 37MB、transcript 1327 行、会话 6 个 —— 数据量很小,磁盘 23%。若服务端 RPC 正常,**卡顿通常在浏览器渲染侧**(同时打开的面板越多、订阅越多,重渲染越重)。
### 9.2 服务不响应 / 502
1. `ss -tlnp | grep 18789` —— 无监听说明进程没起来
2. `systemctl --user is-active openclaw-gateway`
3. `journalctl --user -u openclaw-gateway -n 100` —— 看是否在启动中(**启动需约 14.5s**)
4. 启动后确认日志出现 `[gateway] ready`
### 9.3 外网域名访问不了
```bash
tailscale serve status # 确认 443 → 127.0.0.1:18789 映射存在
journalctl --user -u openclaw-gateway | grep -i 'serve enabled'
```
gateway 重启会自动重新声明路由,日志应出现:
`[tailscale] serve enabled: https://bk02.baiji-algieba.ts.net/`
### 9.4 SQLite 相关
- 维护类命令(`compact`**必须先停 gateway**,否则会因占用锁被拒绝
-`wal_checkpoint` busy:确认没有残留子进程或其它 SQLite 维护命令在跑
- 健康检查看 `integrityCheck`(应 `ok`)与 `freelistPages`(应 `0`
### 9.5 升级前必查(Node 版本陷阱)
新版本对 Node 有硬性要求,例如 2026.9.4 要求 `>=24.16.0 <25 || >=26.1.0` —— **注意 25.x 被整体排除**
gateway 用的是 `ExecStart` 里**硬编码的 node 绝对路径**,与登录 shell 的 node 可能不同。
```bash
/usr/bin/node --version # 系统 node(升级前是 22.23.1,不够用)
nvm exec default node --version # 当前默认
grep '^ExecStart' ~/.config/systemd/user/openclaw-gateway.service # 服务实际用的
```
---
## 10. 已知边界与坑(重要)
| 事项 | 说明 |
|---|---|
| **迁移归档勿删** | `agents/*/session-sqlite-import-archive/`(约 525MB)是 2026-08-31 会话迁入 SQLite 时的原始归档。官方 `openclaw update cleanup` **拒绝清理**`historical-manifest-without-import-proof`)。已验证它们**不是运行时依赖**`session_transcript_archives` 表用 BLOB 存内容、不引用文件路径),删除**不影响运行**,但会**永久失去降级回旧 JSONL 版本的能力** ⇒ 目前**保留** |
| **数据库不可替换** | 见 §5PostgreSQL/MySQL 均不支持 |
| **npm 11 拦 install scripts** | 全局安装 openclaw 时须带 `--allow-scripts=openclaw,@google/genai,koffi,tree-sitter-bash,protobufjs`,否则原生模块不构建(koffi / tree-sitter-bash |
| **配置备份环勿手删** | `.bak` `.bak.1~4` `last-good` `pre-update` 均为官方机制 |
| **skill 重名冲突** | 日志中 `Skill precedence collision`workspace 覆盖 bundled)属**设计内优先级行为**,非错误 |
| **skill 必须有 frontmatter** | 新版要求 `SKILL.md` 顶部有 YAML `name` + `description`,否则日志报 `Skipping invalid skill` 并跳过 |
| **改动后要重启** | 插件变更、skill 变更需 `openclaw gateway restart` 才生效 |
| **引用检查的两个 zsh 陷阱** | bk02 登录 shell 是 **zsh**,用 ssh 跑 grep 检查引用时:①`--include=*.sh` 等**未加引号的 glob** 会被 zsh 提前展开,无匹配时报 `zsh: no matches found` 并使**整条命令中止、grep 根本没执行**,只见空输出;②`grep ... -- "$pat"` 会让其后的 `--include/--exclude-dir` 被当作**文件名**,过滤条件全部失效。两者叠加足以伪造出「零引用」结论 ⇒ 选项必须加引号(`--include="*.sh"`),且**用一个确定存在的串做对照组**验证 grep 真在工作(2026-09-16 全量清理时两次独立踩中) |
| **agent 权威映射只有一处** | `openclaw.json``agents.entries` 是唯一权威(`name` 中文名 + `identity.name`),现存 **11 个**main=助手 resume=简历 travel=旅行 fitness=健康 finances=理财 juaner=卷儿 sql=SQL note=笔记 pbs=PBS备份 wellness=放松保健 tab=导航页。`scripts/db-conn.sh``entries.<id>.name` 反查 `.env``DB_PASSWORD_<中文名>`**改 name 会连带改口令键名**。旧中文名(卷儿记账/理财财务/健身健康/后端开发/简历管理/旅行规划/按摩放松)已于 2026-09-16 清理完毕 |
| **2026-09-16 清理与回滚路径** | 当日:删 `.env` 6 个零引用旧键(现 11 键)、删空目录 `workspace-attestations/``agents/openclaw/` 移出;7 个曾用 id + 2 个陈旧沙箱 + `archived/*` 共 13 项移入 `backups/removed-20260916/`(含 `MANIFEST-taskD.txt` 回滚映射;同盘 `mv` 可瞬时移回)。`.env``backups/` 都在 `.gitignore` 内、**不受版本管理** ⇒ 该备份目录是这些文件的唯一副本,勿随手删 |
| **db-query 技能改走新入口** | 本地库一律 `~/.openclaw/scripts/db-conn.sh <agent_id>`(账号 `agent_<id>`,口令经 `MYSQL_PWD` 转发,不进 argv/stdout);远程 3 个 VPS 主库配置在 `~/.config/clawdbot/db-remote.json`(仅存 `password_env` 键名,无明文);旧 `db-config.json` 改名 `db-config.json.deprecated-20260916`。本地库输出为 **TSV 无表头**`mysql -N -B`)。⚠️ 该技能改动**需重启 gateway 才生效**,且 `workspace/skills/**``.gitignore` 覆盖不入库 |
---
## 11. 新会话接手顺序
1. **本文件**(系统全貌、路径、命令、排查)
2. `openclaw-升级与维护.md`2026-09-16 升级与清理的完整实测过程、踩坑与回滚)
3. 需要时用 `openclaw doctor` 获取当前真实状态(文档是快照,doctor 是实时)
**信息时效**:本文数据取自 2026-09-16 实测;版本、磁盘、插件清单等会变化,判断前请用命令核对。
+302
View File
@@ -0,0 +1,302 @@
# openclaw 升级与维护运维手册(bk02)
> 主机:**bk02** / `xuan-asus-nj`Debian 12 bookworm`192.168.3.14`tailscale `100.115.195.192`
> 组件:OpenClaw Gateway(用户级 systemd+ tailscale serveHTTPS 入口)
> 版本:OpenClaw `2026.8.1` → **`2026.9.4`**;运行 Node `/usr/bin/node 22.23.1` → **nvm `v26.8.2`**
> 更新:2026-09-16(本次为实测记录,含命令、证据与踩坑)
>
> ⚠️ 本文不写明文口令。凭据位置见 §7。
---
## 1. 架构总览
```
浏览器 / App
↓ https://bk02.baiji-algieba.ts.net tailscale serve443 终止 TLS
↓ 转发到本机回环
bk02: node 进程 127.0.0.1:18789 openclaw gateway
存储:~/.openclaw/state/openclaw.sqlite(共享状态)
~/.openclaw/agents/<id>/agent/openclaw-agent.sqlite(每 agent 会话/记忆)
```
| 项 | 值 |
|---|---|
| 服务单元 | `openclaw-gateway.service`**用户级** systemd`systemctl --user` |
| 监听 | `127.0.0.1:18789`+ `[::1]:18789`),不直接对外 |
| 对外入口 | `gateway.tailscale.mode = serve``https://bk02.baiji-algieba.ts.net` |
| 启动命令 | `/home/yangxuan/.nvm/versions/node/v26.8.2/bin/node --max-old-space-size=3913 <openclaw>/dist/index.js gateway --port 18789` |
| 插件 | 8 个 enableddingtalk-connector、feishu、memory-core、ollama、openclaw-weixin、searxng 等 |
| 状态目录 | `~/.openclaw`(本次清理前 2.6G,清理后 1.5G) |
---
## 2. 本次升级:2026.8.1 → 2026.9.4
### 2.1 阻塞点:Node 版本(先踩后解)
`openclaw update` 直接拒绝,原文:
```
Node 22.23.1 at /usr/bin/node is too old for openclaw@2026.9.4.
The requested package requires >=24.16.0 <25 || >=26.1.0
```
关键点:**gateway 服务实际用的是系统 `/usr/bin/node`22.23.1**,而 nvm 里的 `v25.9.0` **也不被支持**(要求排除整个 25.x)。
| Node | 版本 | 满足 2026.8.1 | 满足 2026.9.4 |
|---|---|---|---|
| 系统 `/usr/bin/node`(升级前在用) | 22.23.1 | ✅ | ❌ |
| nvm | v25.9.0 | ✅ | ❌(25.x 被排除) |
| nvm | **v26.8.2**(本次采用) | — | ✅ |
### 2.2 执行步骤(可复现)
```bash
# 1) 装 Node 26(用户级,不动系统 node —— 同机还有 VS Code Server 等依赖它)
export NVM_DIR=$HOME/.nvm; . $NVM_DIR/nvm.sh
nvm install 26 # → v26.8.2
nvm alias default 26 # 让新 shell 与 gateway 版本一致
# 2) 全局安装新版本(必须放行 install scripts,否则原生模块不构建,见 §3.1)
nvm use 26
npm i -g openclaw@2026.9.4 \
--allow-scripts=openclaw,@google/genai,koffi,tree-sitter-bash,protobufjs
# 3) 用官方命令重建服务定义,让 gateway 切到 Node 26
systemctl --user stop openclaw-gateway
openclaw daemon install # 自动检测并替换不支持的 Node,见下
```
`openclaw daemon install` 会自己发现并修掉旧 Node,原文输出:
```
Node 22.23.1: node:sqlite truncates TEXT at embedded NUL (nodejs/node#61954); use 24.16+/26.1+
Replacing unsupported Gateway service Node 22.23.1 (/usr/bin/node) with ~/.nvm/versions/node/v26.8.2/bin/node
Previous unit backed up to: ~/.config/systemd/user/openclaw-gateway.service.bak
```
> **顺带修掉一个数据隐患**Node 22 的 `node:sqlite` 存在「TEXT 遇内嵌 NUL 被截断」的已知 bugnodejs/node#61954)。
> 升级前每条含空字符的消息都可能被静默截断 —— 换到 Node 26 后不再发生(历史已截断的数据无法自动还原)。
```bash
# 4) 同步插件到同版本(doctor 会逐个点名)
openclaw plugins update feishu
openclaw plugins update @openclaw/searxng-plugin@2026.9.4
openclaw plugins update @openclaw/deepseek-provider@2026.9.4
openclaw gateway restart
```
### 2.3 验收证据(实测)
| 验证项 | 结果 |
|---|---|
| 版本 | `OpenClaw 2026.9.4 (3a9d69d)` |
| 运行 Node | `/proc/<pid>/exe → v26.8.2/bin/node` |
| 服务状态 | `active``NRestarts=0` |
| 启动日志 | `[gateway] ready``[tailscale] serve enabled: https://bk02.baiji-algieba.ts.net/` |
| 插件 | 6→8 个加载,`feishu`/`searxng`/`deepseek``2026.9.4` |
| 远端首页 | HTTP/2 **200**ttfb ≈ **0.139s** |
| 前端资源 | 压缩后 **348KB**(原始 1387KBBrotli),9 个资源并发 **0.160.79s** |
| WS 端点 | **200** |
| 数据完整性 | 12 个 agent 全在、36 个 SQLite 库、自动完成 v16/v17 状态迁移 |
---
## 3. 踩坑清单(复现时必读)
### 3.1 npm 11 会静默拦下 install scripts
首次 `npm i -g openclaw@2026.9.4` 虽然「成功」,但这些脚本**没执行**:
```
openclaw (postinstall: postinstall-bundled-plugins.mjs)
koffi (install: cnoke.cjs --prebuild) ← 原生模块
tree-sitter-bash (install: node-gyp-build) ← 原生模块
protobufjs / @google/genai
```
**必须带 `--allow-scripts=...` 重装**,否则运行时才暴露缺模块。
### 3.2 服务里的 Node 路径是硬编码的
`ExecStart` 记录的是绝对路径与具体 Node 版本目录。手工改 systemd 容易漏(`PATH` 环境变量里也含版本号),**优先用 `openclaw daemon install` 重建**,它会连带更新 `PATH`、保留原有 `Environment=` 注入。
### 3.3 两个命令需要显式 `--force`
| 命令 | 不加 force 的表现 |
|---|---|
| `openclaw gateway stop` | 拒绝:「This stops the operator's running gateway service… re-run with `--force`」 |
| `openclaw plugins uninstall <id>` | 交互确认;非交互环境需 `--force`**没有** `--non-interactive` 这个参数) |
---
## 4. 存储结论:只能用 SQLite(不能换 PG/MySQL
官方文档 `llms-full.txt` 原文:
> **SQLite remains the supported runtime store.** Preparation for PostgreSQL should improve the existing store owners and their tests **before adding a driver or configuration option**.
即 PG 支持**连驱动和配置项都还没有**,仅处于前瞻设计阶段。旁证:
| 检查 | 结果 |
|---|---|
| 官方文档 `mysql` / `mariadb` 命中 | **0 次 / 0 次** |
| 官方文档 `postgres` 命中 | 6 次,全在「Preparing for another database backend」一节 |
| 代码里 PostgreSQL/MySQL 字样来源 | **SQL 语法高亮方言**CodeMirror / kysely dialect)与报错文案,**非存储后端** |
| 实际驱动 | `node:sqlite`Node 内置,无外部依赖) |
| 存储位置 | `state/openclaw.sqlite` + `agents/<id>/agent/openclaw-agent.sqlite`(共 36 个库) |
**但是**:本机 docker 里的 pgsql / mysql **可以作为 agent 的工具数据源**(配置里 `"MySQL":{"enabled":true}` + `sql-toolkit`),这与「openclaw 自身存储」是两层,互不影响。
> 结论:想提升存储层,**升级 Node 比换数据库更实在**(§2.2 的 NUL 截断 bug 就是典型)。
---
## 5. 清理历史版本配置 / 缓存 / 残留
### 5.1 官方清理入口
| 目标 | 命令 | 备注 |
|---|---|---|
| 迁移「回滚原始文件」 | `openclaw update cleanup --dry-run` → 停机后 `openclaw update cleanup` | 官方专用于清理 upgrade 残留 |
| agent 库 VACUUM | `openclaw doctor --session-sqlite compact --session-sqlite-all-agents` | 需停机 |
| 共享状态库压缩 | `openclaw doctor --state-sqlite compact --json` | 需停机,会设置 `auto_vacuum=INCREMENTAL` |
| 列表/删除历史会话 | `openclaw sessions` | |
| 继承文件迁移 | `openclaw doctor --fix` | 会归档为 `<源>.migrated.<sha256>.<id>` |
| 卸载插件(含目录) | `openclaw plugins uninstall <id> --force` | |
停机维护的官方推荐顺序:
```bash
openclaw backup create --verify # 先备份(必做)
openclaw gateway stop --force
openclaw doctor --session-sqlite compact --session-sqlite-all-agents
openclaw doctor --state-sqlite compact --json
openclaw gateway start
```
### 5.2 本次清理成效(实测)
| 项目 | 手段 | 释放 |
|---|---|---|
| npm 缓存 | `npm cache clean --force` | **1.7 GB** |
| 旧版 Node 25(含 openclaw 2026.8.1 | `nvm uninstall 25.9.0` | **1.5 GB** |
| `memory-lancedb`disabled 插件) | `openclaw plugins uninstall memory-lancedb --force` | **950 MB** |
| 旧版本 UI 资源缓存 | 核对当前 build 引用后删旧 hash 目录 | **28 MB** |
| SQLite 空闲页 | 上述两个 compact | 2.9 MB |
| 重复 skill 目录 | 全量比对后移出 | 20 KB |
| 验证失败的备份包 | 删除 | 378 MB |
**根分区 26G/109G (26%) → 24G/109G (23%)**`~/.openclaw` 2.6G → 1.5G。
共享状态库 compact 实测输出(可作判据基线):
```json
{ "before": { "autoVacuum": 0, "dbSizeBytes": 15339520, "freelistPages": 435 },
"after": { "autoVacuum": 2, "dbSizeBytes": 12771328, "freelistPages": 0 },
"reclaimedBytes": 2568192, "integrityCheck": "ok" }
```
### 5.3 不能动的东西(官方设计,删了会出问题)
| 路径 | 为什么保留 |
|---|---|
| `openclaw.json.bak` + `.bak.1`~`.bak.4` | 官方**配置备份环**:任何配置写入都会轮转(`--fix` 亦然) |
| `openclaw.json.last-good` | 解析失败时的自动恢复源 |
| `openclaw.json.pre-update` | 升级前备份 |
| `agents/*/agent/*.sqlite` | 当前会话/记忆数据 |
| `~/.openclaw/.git` | 配置备份仓库(见 §6 |
### 5.4 边界:`update cleanup` 拒绝清理的那 525MB
`agents/*/session-sqlite-import-archive/` 下有 654 个 `*.imported-*`(约 **525MB**),是 2026-08-31 会话从 JSONL 迁入 SQLite 时的归档。官方 cleanup **拒绝清理**
```
Candidates: 0 bytes; verification required: 550782825; protected: 0; blocked: 0
原因: historical-manifest-without-import-proof
```
- `doctor --session-sqlite validate` / `dry-run` 均返回 `0 target(s)`:没有待导入的遗留源
- `compact` 报告 `archived-unreferenced-jsonl=0`openclaw 认为这些归档**仍被清单引用**
- 独立验证:`session_transcript_archives` 表用 **`archive_blob` BLOB 把内容存在库内**,全表**不引用外部文件路径** ⇒ 这些 JSONL 确如文档所述「**not runtime fallbacks**」(非运行时依赖),**删除不影响运行**,但会**永久失去降级回旧 JSONL 版本的能力**
**结论:暂不清理**(保留 525MB 换历史恢复能力)。若将来确认不需要降级,可手动删除该目录 —— 但官方不背书,删前务必备份迁移凭证 `session-sqlite-migration-runs/`
---
## 6. 备份、配置仓库与回滚
### 6.1 备份
```bash
openclaw backup create --verify --output ~/openclaw-backups
```
⚠️ 若 workspace 下存在**仅大小写不同**的重复目录(本次为 `skills/Obsidian``skills/obsidian`),`--verify` 会因 *portable path collision* **失败**。处理方式:
```bash
diff -r skills/obsidian skills/Obsidian # 确认内容一致(本次仅 .clawhub/origin.json 的安装元数据不同)
mv skills/Obsidian ~/openclaw-backups/removed-skills/ # 移出而非删除
```
### 6.2 配置仓库(Gitea
| 项 | 值 |
|---|---|
| 仓库 | `~/.openclaw`(工作区内的 git 仓库,分支 `314` |
| remote | `https://gitea.climbcube.cn/yangxuan/openclaw-config.git` |
| 自动提交 | `auto-commit-config.sh`,每 6 小时 `git add -A` + commit + push,无变更则跳过 |
| 提交信息 | `auto: sync OpenClaw config <时间>` / `auto: agent DB backup <日期>` |
**体积治理(本次)**`.git` 曾达 199M / 249 次提交。根因**不是** SQLite`.gitignore` 已忽略 `*.sqlite`),而是 workspace 里的大数据文件被自动提交并推送:
```
90.2 MB workspace-juaner/data/私聊_王芳.json
36.9 MB workspace-juaner/data/私聊_王芳.jsonl
11.7 MB agents/*/session-sqlite-import-archive/*.imported-*
```
⚠️ **隐私提示**`.gitignore` 原未忽略 `workspace-*/data/`,导致私聊内容进入 git 历史并推送到 Gitea。
已加固 `~/.openclaw/.gitignore`
```gitignore
workspace-*/data/
agents/*/session-sqlite-import-archive/
```
`git rm -r --cached`(保留本地文件)使既有大文件脱离跟踪,后续提交不再增长。**历史重写(filter-repo)未做**,如需彻底清除需另行评估(会与 remote 冲突,需 force push)。
### 6.3 回滚
```bash
# 服务定义
cp ~/.config/systemd/user/openclaw-gateway.service.bak ~/.config/systemd/user/openclaw-gateway.service
nvm install 25.9.0 && nvm exec 25.9.0 npm i -g openclaw@2026.8.1
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway
```
> 注意:本次已删除 nvm `v25.9.0`1.5G)与 `memory-lancedb`**回滚需重新下载**`~/openclaw-backups/` 内的验证备份(351MB,不含 workspace)仍可恢复数据。
---
## 7. 凭据与密钥位置(不含明文)
| 用途 | 位置 |
|---|---|
| gateway 认证 | `~/.openclaw/openclaw.json``gateway.auth`password 模式) |
| 机主登录 | 由机主掌握;本机 `~` 用户 `yangxuan` |
| 模型 / 渠道密钥 | `~/.openclaw/.env``openclaw.json``secrets` 段(systemd 以 `OPENCLAW_SERVICE_MANAGED_ENV_KEYS` 注入) |
| 备份包 | `~/openclaw-backups/*.tar.gz`(含凭据,勿外发) |
---
## 8. 遗留观察点
1. **`.git` 仍为 199M** —— 索引清理只阻止未来增长,历史未重写。
2. **525MB 迁移归档保留**(§5.4),如需释放需人工决策。
3. **skill 重名冲突 5 条**`weather`/`obsidian`/`blogwatcher`/`mcporter`/`baidu-text-translate`):workspace 覆盖 bundled,属**设计内优先级行为**,非错误,可不管。
4. **gateway 重启频率**:升级前曾出现单日 5 次重启(2026-09-15),重启后 20 秒内 RPC 会达 1.5–4.4s(冷启动),稳态 0 次慢调用。若再遇「打开很慢」,先查是否落在重启窗口。
5. **链路**wit01 ↔ bk02 走 DERP 中继(`MappingVariesByDestIP: true`,对称 NAT),实测首屏 0.160.79s,服务端本身 < 10ms。
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Lark Technologies Pte. Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+76
View File
@@ -0,0 +1,76 @@
# OpenClaw Lark/Feishu Plugin
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![npm version](https://img.shields.io/npm/v/@larksuite/openclaw-lark.svg)](https://www.npmjs.com/package/@larksuite/openclaw-lark)
[![Node.js Version](https://img.shields.io/badge/node-%3E%3D22-blue.svg)](https://nodejs.org/)
[中文版](./README.zh.md) | English
This is the official Lark/Feishu plugin for OpenClaw, developed and maintained by the Lark/Feishu Open Platform team. It seamlessly connects your OpenClaw Agent to your Lark/Feishu workspace, enabling it to directly read from and write to messages, docs, bases, calendars, tasks, and more.
## Features
This plugin provides comprehensive Lark/Feishu integration for OpenClaw, including:
| Category | Capabilities |
|------|------|
| 💬 Messenger | Read messages (group/DM history, thread replies), send messages, reply to messages, search messages, download images/files |
| 📄 Docs | Create, update, and read documents |
| 📊 Base | Create/manage bases, tables, fields, records (CRUD, batch operations, advanced filtering), views |
| 📈 Sheets | Create, edit, and view spreadsheets |
| 📅 Calendar | Manage calendars and events (create/query/update/delete/search), manage attendees, check free/busy status |
| ✅ Tasks | Manage tasks (create/query/update/complete), manage task lists, subtasks, and comments |
Additionally, the plugin supports:
- **📱 Interactive Cards**: Real-time status updates (Thinking/Generating/Complete), plus confirmation buttons for sensitive operations
- **🌊 Streaming Responses**: Live streaming text directly within message cards
- **🔒 Permission Policies**: Flexible access control policies for DMs and group chats
- **⚙️ Advanced Group Configuration**: Per-group settings including allowlists, skill bindings, and custom system prompts
## Security & Risk Warnings (Read Before Use)
This plugin integrates with OpenClaw AI automation capabilities and carries inherent risks such as model hallucinations, unpredictable execution, and prompt injection. After you authorize Lark/Feishu permissions, OpenClaw will act under your user identity within the authorized scope, which may lead to high-risk consequences such as leakage of sensitive data or unauthorized operations. Please use with caution.
To reduce these risks, the plugin enables default security protections at multiple layers. However, these risks still exist. We strongly recommend that you do not proactively modify any default security settings; once relevant restrictions are relaxed, the risks will increase significantly, and you will bear the consequences.
We recommend using the Lark/Feishu bot connected to OpenClaw as a private conversational assistant. Do not add it to group chats or allow other users to interact with it, to avoid abuse of permissions or data leakage.
Please fully understand all usage risks. By using this plugin, you are deemed to voluntarily assume all related responsibilities.
**Disclaimer:**
This software is licensed under the MIT License. When running, it calls Lark/Feishu Open Platform APIs. To use these APIs, you must comply with the following agreements and privacy policies:
- [Feishu Privacy Policy](https://www.feishu.cn/en/privacy?from=openclaw_plugin_readme)
- [Feishu User Terms of Service](https://www.feishu.cn/en/terms?from=openclaw_plugin_readme)
- [Feishu Store App Service Provider Security Management Specifications](https://open.larkoffice.com/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/management-practice/app-service-provider-security-management-specifications)
- [Lark Privacy Policy](https://www.larksuite.com/user-terms-of-service)
- [Lark User Terms of Service](https://www.larksuite.com/privacy-policy)
## Requirements & Installation
Before you start, make sure you have the following:
- **Node.js**: `v22` or higher.
- **OpenClaw**: OpenClaw is installed and works properly. For details, visit the [OpenClaw official website](https://openclaw.ai).
> **Note**: OpenClaw version must be **2026.2.26** or higher. Check with `openclaw -v`. If below this version, you may encounter issues. Upgrade with:
> ```bash
> npm install -g openclaw
> ```
## Usage Guide
[How to Use the Official Lark/Feishu Plugin for OpenClaw](https://bytedance.larkoffice.com/docx/MFK7dDFLFoVlOGxWCv5cTXKmnMh)
## Contributing
Community contributions are welcome! If you find a bug or have feature suggestions, please submit an [Issue](https://github.com/larksuite/openclaw-larksuite/issues) or a [Pull Request](https://github.com/larksuite/openclaw-larksuite/pulls).
For major changes, we recommend discussing with us first via an Issue.
## License
This project is licensed under the **MIT License**. See [LICENSE](./LICENSE.md) for details.
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env node
import { createRequire } from 'node:module';
import { dirname, join } from 'node:path';
const mod = ['child', 'process'].join('_');
const { execFileSync } = createRequire(import.meta.url)(`node:${mod}`);
// --tools-version <ver> lets the user pin a specific version
const args = process.argv.slice(2);
let version = 'latest';
const vIdx = args.indexOf('--tools-version');
if (vIdx !== -1) {
version = args[vIdx + 1];
// Remove --tools-version <ver> from forwarded args
args.splice(vIdx, 2);
}
const allArgs = ['--yes', '--prefer-online', `@larksuite/openclaw-lark-tools@${version}`, ...args];
try {
if (process.platform === 'win32') {
// On Windows, npx is a .cmd shim that can be broken or trigger
// DEP0190. Bypass it entirely: run node with the npx-cli.js
// script located next to the running node binary.
const npxCli = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js');
execFileSync(process.execPath, [npxCli, ...allArgs], {
stdio: 'inherit',
env: {
...process.env,
NODE_OPTIONS: [process.env.NODE_OPTIONS, '--disable-warning=DEP0190'].filter(Boolean).join(' '),
},
});
} else {
execFileSync('npx', allArgs, { stdio: 'inherit' });
}
} catch (error) {
process.exit(error.status ?? 1);
}

Some files were not shown because too many files have changed in this diff Show More