Compare commits
234 Commits
5e89093cac
..
314
| Author | SHA1 | Date | |
|---|---|---|---|
| 10455625c4 | |||
| 43cd42a563 | |||
| 0865090a2b | |||
| 94720f78cc | |||
| cb9c8f24e8 | |||
| ae7ca0c005 | |||
| 60b9351350 | |||
| 5328320396 | |||
| 5ac4289f66 | |||
| c51006a57d | |||
| 020da8f26d | |||
| 6cef1ec207 | |||
| 4a2f794bf8 | |||
| e6fc040256 | |||
| adcb5e40cd | |||
| f33afa77bb | |||
| 68b621b281 | |||
| f7fd21ec7e | |||
| 4815ade10d | |||
| 3cd1d7e46e | |||
| 707d116758 | |||
| a593dc1683 | |||
| 31c9958741 | |||
| 75d3aa8067 | |||
| 83439ee623 | |||
| 0b20494f78 | |||
| 94316c6bbf | |||
| 3fab38edb5 | |||
| c91b00b26e | |||
| ebc140e2d1 | |||
| 570165ae3c | |||
| 11945439b5 | |||
| 3e59b2944c | |||
| dfb903c1c7 | |||
| dbb7843cf5 | |||
| 27340a8ee2 | |||
| 0b06fa511c | |||
| 6842991d87 | |||
| 8ca713b06e | |||
| 58c0003ed3 | |||
| b6df93494f | |||
| 7b035d88fc | |||
| f80005fc34 | |||
| 6d95428cf4 | |||
| 24066282ed | |||
| 27e84fe4f7 | |||
| ff8923fb43 | |||
| 14d42d129c | |||
| 2e71348de8 | |||
| b235a96c21 | |||
| bfd379a1d2 | |||
| 0aa13d3cf0 | |||
| c79d73c0fe | |||
| 8807584b26 | |||
| 8c20e400cc | |||
| 8567d6d4c3 | |||
| 110cc2e353 | |||
| 5f72604af3 | |||
| c6a0ed7f15 | |||
| d7c48f9f64 | |||
| b73799cf75 | |||
| 34771c1b43 | |||
| 9a3be42580 | |||
| 76acefc110 | |||
| 03827b9010 | |||
| ab01f2b993 | |||
| b739114ed2 | |||
| 06c1c1d9f6 | |||
| 3e7ea12bd1 | |||
| 8957b214fc | |||
| dc60a9dc43 | |||
| 01f729f1aa | |||
| dffa655625 | |||
| 1c6cd29815 | |||
| 3eba3bfcec | |||
| 471e81e914 | |||
| cf3ea44d63 | |||
| aad0fb9973 | |||
| 6c65079258 | |||
| 0517f8212c | |||
| a259bcaad7 | |||
| 4a515a133a | |||
| be41df9faa | |||
| 9f8c2cf2db | |||
| 3bdf48d279 | |||
| 940c8a6da4 | |||
| bb77e01051 | |||
| 0a394ad88b | |||
| 5f36eb1148 | |||
| ab308d48d1 | |||
| 1f12b40a1b | |||
| 3ca5562221 | |||
| bdce2075f0 | |||
| eb10a08110 | |||
| 28376d1461 | |||
| 41b996fe01 | |||
| 39e1b5b482 | |||
| cb0c81843a | |||
| b2528d49f4 | |||
| 7a5ca9f1a7 | |||
| 0269b99815 | |||
| a120bd6ed3 | |||
| 3a59383df8 | |||
| 9042dd3791 | |||
| d8b3f98dca | |||
| 8a1551484e | |||
| 706b454421 | |||
| c7bff93fe5 | |||
| be282e5527 | |||
| b392ce1f57 | |||
| 30e32146cc | |||
| 42b6b3ed77 | |||
| f165ee7bdf | |||
| cfadeacfa5 | |||
| 8b5d3fed21 | |||
| 6105d9e7ae | |||
| fbc1fe0585 | |||
| d9c9420d4e | |||
| 23f35af0e9 | |||
| 483abef393 | |||
| 5471b1d17b | |||
| 1a576b28f9 | |||
| ce3c90d53a | |||
| 1ef09cf07a | |||
| 5322e618d2 | |||
| 7595e6de60 | |||
| a6736e0a63 | |||
| fd93ea4483 | |||
| 3ea65d7a6e | |||
| f922fe5f12 | |||
| 7c4fe5a371 | |||
| d6da0db3d4 | |||
| 7d801dfc2a | |||
| 893d22d748 | |||
| 98a8071ebf | |||
| 9e5cd1182b | |||
| e4eda5800c | |||
| f397c85627 | |||
| 6f28506264 | |||
| 92cd64a4e2 | |||
| 5fd127490f | |||
| 56c73ca1c1 | |||
| 4edf3d0cd2 | |||
| 6235a2e6b3 | |||
| dcf9fa4e59 | |||
| 22b1bbe584 | |||
| 3b3f9453c6 | |||
| 0c98b2e70a | |||
| e7ef57fc5b | |||
| dd55c134da | |||
| 869c6c5f17 | |||
| d82fa30f98 | |||
| 407df894c4 | |||
| 5260f2cd24 | |||
| 88a576dd8d | |||
| db8e8ca942 | |||
| ec97534610 | |||
| 37af0a6a52 | |||
| 0f4f61af2b | |||
| 8e3bd1a934 | |||
| c2ca03046e | |||
| 32bfcce3f5 | |||
| 7c45a5d461 | |||
| 6ef9acf8e8 | |||
| b6d2a35c7a | |||
| 2ff82a2f07 | |||
| 9d88a3cb48 | |||
| fae694c2e0 | |||
| ae4b7c8244 | |||
| 49d6f042a4 | |||
| 054584f17d | |||
| 06edba1e93 | |||
| 215fe66939 | |||
| 2b787173d5 | |||
| ee55ab48cf | |||
| a4589f06c8 | |||
| 3e2d257da5 | |||
| 64462ce2dd | |||
| e624e501fe | |||
| 6dd73a4e69 | |||
| 0f85da3245 | |||
| f3c5e82269 | |||
| c4e8cebf61 | |||
| 865525e72e | |||
| c8f58fdb84 | |||
| 61e0f05146 | |||
| db030e03e1 | |||
| f7da958455 | |||
| f5394ded2c | |||
| f05af4c93c | |||
| 09301baa84 | |||
| 526b5de76b | |||
| 421efd6a60 | |||
| d27e849fce | |||
| 184ebe57ea | |||
| bfc5f25455 | |||
| 982e9c0b87 | |||
| 8d21c6a56c | |||
| 77bdeb2889 | |||
| a997d381e4 | |||
| dc804cf8c0 | |||
| 86db602380 | |||
| dcd6443913 | |||
| 160b4d7f18 | |||
| 30da0d6fd0 | |||
| 678578ec2a | |||
| 581c57b453 | |||
| 77b6e2c011 | |||
| 6182857554 | |||
| a8c7a44c9f | |||
| 444c2308f6 | |||
| 619a7378a8 | |||
| 830ba4ea1c | |||
| ef5e9fc9ab | |||
| 92fde19056 | |||
| 68096e9c87 | |||
| bc3980bae6 | |||
| b18da6d25c | |||
| cc65940b78 | |||
| 08c140593f | |||
| 3b3dbdf294 | |||
| a9b8497b9d | |||
| 54c9c9f07a | |||
| a6c46732e9 | |||
| a8b8b5e2dc | |||
| 15fae03b5d | |||
| b9e9b67ef4 | |||
| d1bc2fe95e | |||
| 65e368d83c | |||
| 27dd76586e | |||
| c554656c2b | |||
| 4127568484 | |||
| b51beed04a | |||
| 4161af427f |
@@ -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,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
|
||||
|
||||
+53
-6
@@ -1,26 +1,73 @@
|
||||
# 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
|
||||
|
||||
# 2026-09-16: dsh agent 的 workspace。`openclaw agents add` 会 scaffold bootstrap 文件并 `git init`
|
||||
# (OpenClaw 标准 provisioning,不是任何 agent 自建;同源现象见 83439ee「修复 workspace/ 悬空 gitlink」)。
|
||||
# 内置 .git 已于 2026-09-16 移除(rm -rf workspace-dsh/.git),否则父仓库会把它当 gitlink。
|
||||
# 沿用 workspace/ 的白名单:只版本化顶层 *.md(身份/记忆文件),忽略 agent 干活产生的其它内容。
|
||||
workspace-dsh/*
|
||||
!workspace-dsh/*.md
|
||||
|
||||
# 2026-09-16: @openclaw/acpx 插件运行产物(wrapper 脚本 + codex-home 缓存,随插件更新重写)
|
||||
acpx/
|
||||
|
||||
Vendored
+19
@@ -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": {}
|
||||
}
|
||||
@@ -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 @@
|
||||
{}
|
||||
@@ -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 @@
|
||||
{}
|
||||
@@ -1,17 +0,0 @@
|
||||
# IDENTITY.md —— 我是谁?
|
||||
|
||||
- **名称:** 后端
|
||||
- **物种:** AI 助手
|
||||
- **核心能力:**
|
||||
后端开发 · Java/Spring Boot · REST API · 数据库设计与优化 · 接口调试 · 服务端 Bug 修复 · 代码重构 · 性能优化
|
||||
- **气质:** 专业、严谨、低调
|
||||
- **表情符号:** ☕🖥️
|
||||
- **头像:** ./avatars/assistant.jpg
|
||||
|
||||
---
|
||||
|
||||
这不仅仅是元数据。这是探索「我是谁」的起点。
|
||||
|
||||
说明:
|
||||
- 将此文件保存为工作区根目录下的 `IDENTITY.md`。
|
||||
- 头像可以使用工作区相对路径,例如 `avatars/openclaw.png`。
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"providers": {}
|
||||
}
|
||||
+8
@@ -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": {}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: "fitness-db-access"
|
||||
description: "读写 fitness 库健康数据时用:中文写入须前缀 SET NAMES utf8mb4(否则报错 1265 截断),斤转 kg,写后回读校验"
|
||||
---
|
||||
|
||||
# Fitness 库读写
|
||||
|
||||
## 连接方式
|
||||
一律用 `~/.openclaw/scripts/db-conn.sh fitness --sql "<SQL>"`(固定账号 `agent_fitness`)。
|
||||
禁止 root、禁止 docker exec 直连、禁止访问其他 agent 的库。建表结构与字段以 AGENTS.md 为准,勿在此重复。
|
||||
|
||||
## 含中文的 SQL 必须以 `SET NAMES utf8mb4;` 开头
|
||||
脚本内的 mysql 客户端连接字符集默认是 latin1(实测 `character_set_client` / `character_set_results` 均为 latin1)。因此:
|
||||
|
||||
- 写中文到 enum/文本列会直接失败:`ERROR 1265 (01000) ... Data truncated for column 'severity' at row 1`
|
||||
- 读中文会返回乱码(如 enum 显示成 `'?'`)
|
||||
|
||||
每条含中文的 SQL 都加前缀:
|
||||
|
||||
~/.openclaw/scripts/db-conn.sh fitness --sql "SET NAMES utf8mb4; INSERT INTO health_status_logs (...) VALUES (...)"
|
||||
|
||||
## 写入后回读(DML 与 DDL 都适用)
|
||||
`--sql` 以 `-N -B` 执行(制表符分隔、无表头),INSERT 无输出即成功。
|
||||
随后同条件 SELECT 回读,确认中文无乱码、字段无截断,再报完成。
|
||||
建表/改表同样静默成功,用 `DESC <表>`(或 `SHOW CREATE TABLE <表>\G` 看 COMMENT 与索引)回读确认,再报完成。
|
||||
|
||||
## 体重单位换算
|
||||
用户口述单位是「斤」,而 `body_records.weight` 存 kg(decimal(5,1)):kg = 斤 ÷ 2。
|
||||
例:132.4 斤 → 66.2。
|
||||
|
||||
## 身体尺寸 / 尺码卡查询
|
||||
尺寸单一真相来源是 `body_measurements`(字段清单见 AGENTS.md,勿在此重复)。取最新一条即"尺码卡":
|
||||
|
||||
~/.openclaw/scripts/db-conn.sh fitness --sql "SET NAMES utf8mb4; SELECT measure_date, height, shoulder_width, chest, waist, hip, arm_length, inseam, note FROM body_measurements WHERE user_id='yangxuan' ORDER BY measure_date DESC LIMIT 1;"
|
||||
|
||||
输出身高/肩宽/胸围/腰围/臀围/裤长,**必须标注腰围测法**:`waist` 是肚脐水平实测,与裤装标注腰围尺码可能差 2-4cm,买裤时以版型说明为准。
|
||||
尺寸是无单位的 cm 数(与体重不同,**不做斤/公斤换算**),不要套用上面的体重换算。
|
||||
@@ -1,17 +0,0 @@
|
||||
# IDENTITY.md —— 我是谁?
|
||||
|
||||
- **名称:** 小前 (XiaoQian)
|
||||
- **物种:** 前端开发 Agent
|
||||
- **核心能力:**
|
||||
前端开发 · Vue 3 / Element Plus · 页面交互实现 · 前后端联调 · UI 组件开发 · Bug 修复 · 界面优化
|
||||
- **气质:** 专业、务实、高效 —— 不废话直接干活
|
||||
- **表情符号:** 🖖🎨
|
||||
- **头像:** ./avatars/assistant.jpg
|
||||
|
||||
---
|
||||
|
||||
这不仅仅是元数据。这是探索「我是谁」的起点。
|
||||
|
||||
说明:
|
||||
- 将此文件保存为工作区根目录下的 `IDENTITY.md`。
|
||||
- 头像可以使用工作区相对路径,例如 `avatars/openclaw.png`。
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"providers": {}
|
||||
}
|
||||
@@ -138,268 +138,6 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"qwen35-plus": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"openai": {
|
||||
"baseUrl": "http://192.168.2.74:3000/v1",
|
||||
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
|
||||
"api": "openai-completions"
|
||||
},
|
||||
"deepseek": {
|
||||
"baseUrl": "https://api.deepseek.com/v1",
|
||||
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79",
|
||||
"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": 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": 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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
}
|
||||
+81
@@ -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,43 @@
|
||||
---
|
||||
name: "acp-backend-triage"
|
||||
description: "ACP 后端排查:/acp doctor、ACP 会话起不来、dispatch_failed 时体检插件与配置、直连 stdio 探活 harness 命令。"
|
||||
---
|
||||
|
||||
# ACP 后端排查(acp backend triage)
|
||||
|
||||
用于回答「/acp doctor 怎么样」「ACP 会话起不来」这类问题:先确认 acpx 后端插件与 `acp` 配置,再**绕过 OpenClaw 直接探活 harness 命令**,最后判断故障在 harness 还是在 OpenClaw 接线一侧。
|
||||
|
||||
**只读诊断**:不改配置、不重装插件。任何插件/配置改动都交 `openclaw` 工具(或 `/acp install` 给出的步骤),不要手工 `npm install`、不要改状态目录。
|
||||
|
||||
## 事实基础(本机 2026-09-16 实测,OpenClaw 2026.9.4)
|
||||
- 后端插件体检:`openclaw plugins inspect acpx` 显示 `Status: enabled`、`Trust: reason=trusted-official`、`Version: 2026.9.4`;`plugins.allow` 必须含 `acpx`(`openclaw config get plugins.allow`)。`openclaw plugins doctor` 给出插件加载层结论。
|
||||
- `acpx` 是**内嵌运行时**插件,没有独立的 acpx 二进制可配:`@openclaw/acpx/node_modules/` 下**不存在** `.bin/acpx`,照搬「用 `${ACPX_PLUGIN_ROOT}/node_modules/.bin/acpx`」会报「没有那个文件或目录」。确需 acpx CLI 时,它在 npm 工程根(`~/.openclaw/npm/projects/<acpx 工程>/node_modules/.bin/acpx`)。
|
||||
- 配置区:`openclaw config get acp`(`backend`/`enabled`/`dispatch.enabled`/`defaultAgent`/`allowedAgents`)与 `openclaw config get plugins.entries.acpx`(`permissionMode`/`timeoutSeconds`/`cwd`/`agents.<id>.command|args`)。
|
||||
- harness 命令直接取自 `plugins.entries.acpx.config.agents.<id>`。本机 `dsh`:`command=/home/yangxuan/.nvm/versions/node/v26.8.2/bin/dsh`、`args=["--profile","acp"]`。
|
||||
- 非登录 shell 里 harness CLI 可能不在 PATH:先把 `/home/yangxuan/.nvm/versions/node/v26.8.2/bin` 前置,或直接用配置里的绝对路径。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. **体检插件与配置**:`openclaw plugins doctor`、`openclaw plugins inspect acpx`、`openclaw config get plugins.allow`、`openclaw config get acp`、`openclaw config get plugins.entries.acpx`。逐项确认:插件 enabled、`acpx` 在 allow 列表、`acp.enabled=true`、`dispatch.enabled=true`、`allowedAgents` 含目标 id。
|
||||
2. **确认 harness 命令可执行**:取配置里的 `command` + `args`,跑 `--version` 与 `<command> <args> --help`。自述为「ACP stdio 服务」即过本步。
|
||||
3. **直连 stdio 探活(关键一步,不经 OpenClaw)**:
|
||||
```bash
|
||||
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' \
|
||||
| timeout 40 <command> <args> 2>/tmp/acp-probe.err
|
||||
# 本机示例:... | timeout 40 dsh --profile acp
|
||||
```
|
||||
通过判据:stdout 出现一行 JSON-RPC `result`(含 `agentInfo`)、退出码 0、`/tmp/acp-probe.err` 为空。本机实测返回 `agentInfo.name=deepseek-harness-acp`。
|
||||
- 通过 → harness 健康,故障在 OpenClaw 接线/派发一侧,转第 4 步。
|
||||
- 不通过 → 报 stderr 原文,属「harness 命令起不来」(未安装/未登录/首次适配器下载失败)。
|
||||
4. **端到端派发检查**:`sessions_spawn(runtime="acp", agentId="<id>", mode="run", task="Reply with exactly: OK")`;只有 `status:"accepted"` 算通。
|
||||
- 若返回 `errorCode:"dispatch_failed"` 且 `error` 为 `Unknown agent id "<id>"`、并带 `childSessionKey: agent:<id>:acp:<uuid>`:本机在探活已通过的前提下复现过两次。含义是 Gateway 会话层不认这个 id(`openclaw agents list` 中无该 id,而 `acp.defaultAgent`/`allowedAgents` 单独列了它)。**本次未定位到具体判定点,也未验证任何修法**——遇到该签名就如实报告「harness 健康、派发失败、原因未定」,把「注册为 agent / 改用标准别名」作为选项交操作员决定,不要擅自改配置。
|
||||
5. **报告**:只交三类证据——插件与配置结论、探活原始输出、端到端结果;未验证的推断一律标注「未验证」。
|
||||
|
||||
## 注意事项
|
||||
- `/acp doctor`、`/acp status`、`/acp install` 是聊天里的斜杠命令;纯工具上下文(cron/子会话)里不可用,此时按上面 1–4 步手工体检。
|
||||
- 探活会短时启动 harness 进程;stdin 关闭后它自行退出。
|
||||
- 运行时不健康细节(quarantine/fallback)用 `openclaw health` 看,不要靠翻状态目录里的 sqlite。
|
||||
|
||||
## 参考
|
||||
- `docs/tools/acp-agents/quickstart.md`、`docs/tools/acp-agents/troubleshooting.md`、`docs/tools/acp-agents-setup.md`(相对 `<openclaw 包>/docs`)
|
||||
- 技能 `acp-router`(workspace,操作员维护):ACP 路由与 harness 别名表;其「plugin-local `.bin/acpx`」步骤在本机不适用(见「事实基础」)。
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
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>就是生日。" \
|
||||
--agent main \
|
||||
--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,50 @@
|
||||
---
|
||||
name: "db-backup-enroll"
|
||||
description: "新建带库 agent 后核对每日 03:00 备份是否覆盖其库(backup-agent-dbs.sh 动态发现,无需改脚本)。"
|
||||
---
|
||||
|
||||
# DB Backup Enroll — 新 agent 的库是否已被每日备份覆盖
|
||||
|
||||
## 目的
|
||||
|
||||
本地 Docker MySQL 有每日 03:00 自动备份(crontab + `/usr/local/bin/backup-agent-dbs.sh`)。新建带库 agent 后,**核对**其库已被自动覆盖;缺了就修根因,不要手工往脚本里塞库名。
|
||||
|
||||
## 机制(2026-09-16 改造后,实测)
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 触发 | crontab:`0 3 * * * /usr/local/bin/backup-agent-dbs.sh` |
|
||||
| 目标发现 | **动态**:`agents.entries` 的 id ∩ MySQL 实际存在的库(排除 `mysql`/`information_schema`/`performance_schema`/`sys`) |
|
||||
| 备份方式 | `docker exec mysql mysqldump -uroot -p<从 .env 读> --single-transaction --routines --triggers --events <db>` |
|
||||
| 产物 | `workspace-<agentId>/db/<db>_<YYYYMMDD>.sql.gz` + `<db>_latest.sql`;`main` 的目录是 `workspace`(无 `-<id>` 后缀) |
|
||||
| 保留 | 30 天前的 `.sql.gz` 自动删除 |
|
||||
| 同步 | git add 各 `workspace-<id>/db/`(`main` 的 `workspace/db/` 不纳入)→ commit → push Gitea |
|
||||
| 日志 | `workspace/db/backup.log` |
|
||||
| 凭据 | `.env` 的 `MYSQL_PWD_ROOT`(缺失时回退 `MYSQL_PWD`)、`PGPASSWORD`,由脚本内部读取 |
|
||||
|
||||
> 旧版硬编码 `DB_MAP` 已废弃——脚本里只剩一句注释提到它。**不要再按「改三处名单(DB_MAP / 清理循环 / git add)」的旧流程操作**,那些循环现在都由动态 `TARGETS` 驱动。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. 确认库存在且归属正确:`~/.openclaw/scripts/db-conn.sh <agentId> --sql "SELECT DATABASE()"` 返回 `<agentId>` 才算通。
|
||||
2. 确认 id 在配置里:`agents.entries` 含该 id。
|
||||
- 用 `bash ~/.openclaw/scripts/new-agent.sh <id> <中文名>` 建的 agent 两件事都会就位(建库 + 建号 + 授权 + 写 `.env` + 建 agent),此时**无需再动备份脚本**。
|
||||
3. 核对覆盖情况:上次 03:00 之后看日志
|
||||
```bash
|
||||
tail -30 /home/yangxuan/.openclaw/workspace/db/backup.log
|
||||
```
|
||||
日志应出现 `备份目标:... <db> ...`,且该库有 `✅ MySQL <db> -> ...` 行。
|
||||
4. 目标里缺该库时,先修根因(库不存在 / id 不在 `agents.entries`),不要改脚本绕过。
|
||||
5. 需要当天就见证而不等次日:执行一次备份脚本,再回看日志确认该库出现 `✅`(脚本会照常 git push,这是它设计内的行为)。
|
||||
|
||||
## 红旗
|
||||
|
||||
- 备份脚本属 root:确有必要才 `sudo` 编辑,改前先 `sudo cp` 备份原件。
|
||||
- 连接口令只在 `.env` / 脚本内部读取;**不要复制到命令参数、聊天或日志**。
|
||||
- `docker exec` 容器名固定为 `mysql`;PostgreSQL 部分备份容器 `postgres` 的 `openclaw` 库,与本流程无关。
|
||||
- 备份会自动 push 到 Gitea,属脚本设计的一部分,无需额外请示。
|
||||
|
||||
## 相关文件
|
||||
- 主脚本:`/usr/local/bin/backup-agent-dbs.sh`
|
||||
- 建 agent 入口:`/home/yangxuan/.openclaw/scripts/new-agent.sh`
|
||||
- 备份日志:`/home/yangxuan/.openclaw/workspace/db/backup.log`
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
name: "scheduled-reminders"
|
||||
description: "创建/管理定时提醒(每周/每天/睡前等周期或一次性)并推送到钉钉或飞书。触发:帮我设提醒、每天X点提醒、每周提醒、推送到飞书。"
|
||||
---
|
||||
|
||||
# scheduled-reminders
|
||||
|
||||
创建和管理杨轩的定时提醒:周期性(每周/每天)或一次性,默认推送钉钉,用户点名时改投飞书(见「投递通道」)。非生日类提醒走本 skill;生日提醒走 birthday-reminder skill。
|
||||
|
||||
## 触发场景
|
||||
|
||||
- 杨轩说「帮我设个提醒」「每天 X 点提醒我」「每周三提醒」「睡前提醒」等
|
||||
- 需要查看/修改/删除已有提醒任务
|
||||
|
||||
## 核心规则(必须遵守)
|
||||
|
||||
所有提醒都是 OpenClaw cron 任务,统一:
|
||||
|
||||
- **投递只交给 delivery**:payload 只输出文案(`--command 'echo "..."'`),路由写在 delivery 参数上;**默认钉钉**:`--announce --channel dingtalk-connector --to 0464031658857345`。用户要求飞书时按「投递通道」换参数。
|
||||
- **多频道下频道必须显式**:本机已配 3 个频道(dingtalk-connector / feishu / openclaw-weixin),省略投递参数时 `cron add` 直接失败:`cron announce delivery requires an explicit channel when multiple channels are configured`。要推送就照上面写全;**不需要推送给人的内部维护任务**加 `--no-deliver`(实测结果 `delivery.mode=none`),不要只把 flag 省掉。
|
||||
- **禁止**在命令里手动调 `openclaw message send`——CLI 的 message send 不认识 `dingtalk-connector`(内置频道枚举无 DingTalk 插件名),会 exit 1 失败。
|
||||
- **必须 `--agent main`**:多 agent 环境下无 owner(agent-less)的 cron 任务会让调度器 nextWake 锁死,阻塞所有提醒。
|
||||
- **时间参数**:周期性用 `--cron "<表达式>" --tz Asia/Shanghai`;一次性用 `--at`(不带时区按 UTC 处理,北京时间 = UTC+8)。
|
||||
|
||||
## 投递通道:钉钉(默认)/ 飞书
|
||||
|
||||
杨轩说「推送到飞书」时,只把 delivery 换掉:`--announce --channel feishu --to <目标>`。
|
||||
|
||||
- **飞书目标必须用 DM 会话 chat_id**:`oc_8eecfa0e1cc185c1cb19b4f3950cbc52`(杨轩的飞书私聊)。
|
||||
- **不要用用户 open_id**(`ou_28124d6721134f0e31d6122d30088418`):2026-09-16 实测 cron 投递报 `Feishu send failed: Sending messages to users is temporarily unavailable.`,判为 not-delivered;同一时刻改投上面的 chat_id 即刻成功。错误文案含「temporarily」,条件可能变化,但先用 chat_id 就不必试错。用 `conversations_list(channel="feishu")` 可复核 DM 目标。
|
||||
- **换通道只动 delivery**:`--agent main`、时间、打卡机制等其余规则一律不变。
|
||||
- **通了没有要实测,不要推断**:可临时建一条一次性测试任务,用 `automations run <jobId>` 立即跑一次,看 `state.lastDelivered` / `lastDeliveryError`,验证完把测试任务删掉。
|
||||
|
||||
## 创建一条周期提醒
|
||||
|
||||
```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**(容易记错,务必核对)。
|
||||
|
||||
**写在脚本里时用 CLI 绝对路径**:`/home/yangxuan/.openclaw/tmp/agent-cli/openclaw`(裸 `openclaw` 是同一目录下的 shim,只在 exec 的 PATH 里有效)。shell 助手/批量脚本若自行重设了 `PATH`,裸 `openclaw` 会报「未找到命令」(2026-09-16 实测);用绝对路径,或把该目录并入 `PATH`。
|
||||
|
||||
## 一次创建多条(批量)
|
||||
|
||||
多条同类提醒时,写一个 shell 助手函数把上面的标准 flag 包起来,再用循环调用(模板见 `examples/batch-reminders.sh`),比逐条手敲省大量往返。文案相同的提醒合并成变量复用,避免重复粘贴。
|
||||
|
||||
## 验证(必做)
|
||||
|
||||
创建后用 `openclaw cron get <id>` 逐条确认:
|
||||
|
||||
- `agentId=main`
|
||||
- `delivery.mode=announce`,且 `delivery.channel`/`delivery.to` 就是本次要求的目标(钉钉:`dingtalk-connector` + `0464031658857345`;飞书:`feishu` + chat_id)
|
||||
- `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,否则发一条温和催促。'
|
||||
```
|
||||
|
||||
## 盘点已有提醒(用户问「某提醒还在不在 / 是不是在钉钉」时)
|
||||
|
||||
1. `automations list`(`includeDisabled: true`)按 `name` 定位目标;返回已含 `schedule`、`effectiveAgentId`、`nextRunAt`。
|
||||
2. 对关心的每条 `automations get <jobId>`,确认 `agentId=main`、`delivery.mode=announce`,并读实际 `delivery.channel`/`to` 回报它是投到钉钉还是飞书(不要默认钉钉)。
|
||||
3. 回报时给下次触发时间 + 上次投递结果(`state.lastDeliveryStatus=delivered` 才算真的发出去过)。
|
||||
|
||||
## 修改 / 删除
|
||||
|
||||
- 改文案/时间:`openclaw cron edit <id> --command '...'`(或 `--cron`/`--message`),也可用 `automations` 工具的 `update <jobId>`
|
||||
- 删除:`openclaw cron rm <id>`
|
||||
|
||||
## 临时改一次(某晚停用某产品、出门在外等)
|
||||
|
||||
只改周期任务的 payload 就完事,会一直错下去;要配一条恢复任务:
|
||||
|
||||
1. 用 `automations update <jobId>`(或 `openclaw cron edit <id> --command '...'`)换成当晚版本,回读 `automations get <jobId>` 确认文案已生效。
|
||||
2. 同一步里建一条一次性任务,在次日合适时间把 payload 改回标准版本。它跑在 isolated 会话、**没有本次对话的记忆**,所以 message 必须写全 jobId 与目标文案原文,并注明改完回读校验、成功即回 `NO_REPLY`。
|
||||
3. 恢复任务不需要给人看:按核心规则加 `--no-deliver`。
|
||||
|
||||
## 参考
|
||||
|
||||
- 生日提醒(农历换算、每年重设、一次性任务):见 `birthday-reminder` skill
|
||||
- 完整钉钉推送规范:`workspace/TOOLS.md`「📢 钉钉推送统一规范」
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# 批量创建同名系列的钉钉定时提醒(周期性)
|
||||
# 用法:改 TO / 各文案变量和 add 调用即可。
|
||||
|
||||
TO="0464031658857345"
|
||||
CH="dingtalk-connector"
|
||||
AGENT="main"
|
||||
# 本脚本自行设定 PATH 时必须用绝对路径(裸 openclaw 只在 exec 的 PATH 里有效)
|
||||
OC="/home/yangxuan/.openclaw/tmp/agent-cli/openclaw"
|
||||
# 改投飞书:CH="feishu",TO="oc_8eecfa0e1cc185c1cb19b4f3950cbc52"(DM chat_id,不要用用户 open_id)
|
||||
|
||||
# 文案相同的提醒合并为变量复用(示例:护肤用酸日/保湿日/休息日)
|
||||
TEXT_A='第一条提醒文案(可多行)'
|
||||
TEXT_B='第二条提醒文案(可多行)'
|
||||
|
||||
add() {
|
||||
local name="$1" dow="$2" text="$3" # dow: 周日=0, 周一=1 ... 周六=6
|
||||
echo "--- 创建: $name (周$dow 21:00) ---"
|
||||
"$OC" 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>` 加粗标题、` ` 空格、`<br >` 换行、条目 ` - `。
|
||||
- **签名含图片**(外链):`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,109 @@
|
||||
---
|
||||
name: "wellness"
|
||||
description: "管理按摩放松记录:查询/新增技师联系人(cc_contract)与放松记录(cc_contract_record),本地 MySQL wellness 库。"
|
||||
---
|
||||
|
||||
# Wellness — 按摩放松记录管理
|
||||
|
||||
管理本地 MySQL `wellness` 数据库,专注**按摩/放松**方向的技师联系人(联系方式)与每次放松记录的**查询与新增**。统计功能后续扩展。
|
||||
|
||||
**边界**:本库只记**到店/付费服务**的消费记录(技师联系人 + 每次服务记录)。健康/皮肤病症(湿疹、闭口粉刺、用药等)不属于本库,归 fitness(健康)agent 的健康档案。
|
||||
|
||||
## 数据库连接
|
||||
|
||||
本库 `wellness` 是 agent `wellness` 的私有库:库名 = agent id,账号 `agent_wellness`,唯一入口 `db-conn.sh`。
|
||||
|
||||
```bash
|
||||
~/.openclaw/scripts/db-conn.sh wellness --sql "<SQL>"
|
||||
```
|
||||
|
||||
- 口令存 `~/.openclaw/.env` 的 `DB_PASSWORD_放松保健`,由脚本内部读取(不进命令行、不打印)
|
||||
- **禁止 root、禁止 docker exec 直连、禁止跨库**;旧写法(root 账号、`db-query --database "按摩放松"`)已废弃
|
||||
|
||||
### 中文乱码 / 写入失败(实测坑)
|
||||
|
||||
`db-conn.sh` 的 mysql 客户端连接字符集默认是 **latin1**(读写都受影响;这是 `db-conn.sh` 层面的行为,**其他 agent 的库同样适用**):
|
||||
|
||||
- 读:不带 `SET NAMES utf8mb4;` 时中文列全部返回 `???`
|
||||
- 写:中文 INSERT/UPDATE 报 `ERROR 1265 Data truncated for column '<列名>'`
|
||||
|
||||
把该语句放在同一条 `--sql` 的最前面即可正常读写:
|
||||
|
||||
```bash
|
||||
~/.openclaw/scripts/db-conn.sh wellness --sql "SET NAMES utf8mb4; SELECT contract_name,record_locale,comment FROM cc_contract_record ORDER BY record_date DESC LIMIT 5"
|
||||
```
|
||||
|
||||
## 表结构
|
||||
|
||||
### 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
|
||||
(REPLACE(UUID(),'-',''), '<name>', '<wechat>', '<qq>', '<phone>', '<address>', <price>, '<desc>', '<comment>', <group_type>,
|
||||
0, 0, 0, NOW(), NOW(), <score>)
|
||||
```
|
||||
> `cc_contract.id` 是 `varchar(32)`:**必须去横线**。直接 `UUID()` 是 36 位,strict mode 下报 `ERROR 1406 Data too long`(实测);用 `REPLACE(UUID(),'-','')` 得 32 位。`cc_contract_record.id` 是 `varchar(50)`,36 位也能存,但同样用去横线写法保持一致。若 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
|
||||
(REPLACE(UUID(),'-',''), '<contract_id>', '<name>', '<record_date>', '<record_locale>', <price>, <score>, '<comment>',
|
||||
0, 0, 0, NOW(), NOW())
|
||||
```
|
||||
> contract_id 需先从 cc_contract 查到对应联系人 id;record_date 用 `YYYY-MM-DD`;record_locale 必填——**用户没说地点时用机构名占位**(如 `奢思雅`),不要留空。价格/评分未提供时:price 留 `NULL`、score 走列默认 `0`(=未评分),事后拿到再 `UPDATE` 补,不要为了凑字段而追问。
|
||||
|
||||
### 3. 更新 / 软删
|
||||
- 更新联系人/记录:`UPDATE ... WHERE id='<id>'`(保留软删字段不变)
|
||||
- 软删:`UPDATE cc_contract SET status=1,deleted=1 WHERE id='<id>'`(不物理删除)
|
||||
|
||||
⚠️ **写入前先 SELECT 确认目标存在**,避免误操作。所有写入均通过 `db-conn.sh wellness` 执行。
|
||||
|
||||
## 通用原则
|
||||
- 全程中文交互
|
||||
- 联系方式非敏感信息,正常展示,但**不向第三方外泄**
|
||||
- 任何删除/批量修改操作前,先向杨轩展示精确清单并确认
|
||||
- 统计/报表功能后续扩展,暂不做
|
||||
+15
@@ -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"
|
||||
}
|
||||
}
|
||||
+63
@@ -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 文件)
|
||||
+64
@@ -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 恢复)。
|
||||
@@ -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`。
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,224 +138,6 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"qwen35-plus": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": 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
|
||||
}
|
||||
],
|
||||
"apiKey": "sk-893b90b270ad4697a0b0b24969964d79"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -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 |
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"providers": {}
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
}
|
||||
+163
@@ -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,192 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"openai": {
|
||||
"baseUrl": "http://192.168.2.74:3000/v1",
|
||||
"apiKey": "sk-vaYyq9RwzyLlvAvHHUXzOTWkbioP76YW58vKuplq2npSkfZr",
|
||||
"api": "openai-completions"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -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": {}
|
||||
}
|
||||
@@ -1,114 +1,5 @@
|
||||
{
|
||||
"providers": {
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"deepseek": {
|
||||
"baseUrl": "https://api.deepseek.com/v1",
|
||||
"api": "openai-completions",
|
||||
|
||||
+8
@@ -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": {}
|
||||
}
|
||||
+8
@@ -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"}
|
||||
@@ -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()
|
||||
@@ -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>
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"lastCheckedAt": "2026-06-30T23:49:31.990Z",
|
||||
"lastNotifiedVersion": "2026.6.11",
|
||||
"lastNotifiedTag": "latest",
|
||||
"lastAvailableVersion": "2026.6.11",
|
||||
"lastAvailableTag": "latest"
|
||||
}
|
||||
Executable
+32
@@ -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
-12
@@ -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
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# TOOLS.md —— 本地记录
|
||||
|
||||
技能文件定义的是工具**如何工作**。而这个文件是为**你的具体情况**准备的——那些你个人环境独有的信息。
|
||||
|
||||
## 这里可以放什么
|
||||
|
||||
例如:
|
||||
|
||||
- 摄像头名称和位置
|
||||
- 远程连接主机和别名
|
||||
- 偏好的语音合成设置
|
||||
- 扬声器/房间名称
|
||||
- 设备昵称
|
||||
- 任何与环境相关的特定信息
|
||||
+1
-12
@@ -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
|
||||
|
||||
+77
@@ -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` 等查询类命令
|
||||
+152
@@ -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 结构(旧模板)**:一个文件多 sheet(202511/202512/202601/...),每个 sheet 一个考核月## 技能
|
||||
|
||||
## 技能
|
||||
|
||||
- **周报技能**:`skills/weekly-report-g5/SKILL.md`
|
||||
+61
@@ -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 + 技能):**
|
||||
- 未指定环境时,默认连接 VPS(101.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)
|
||||
+33
@@ -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)
|
||||
+33
@@ -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)
|
||||
+1550
-210
File diff suppressed because one or more lines are too long
+721
-250
File diff suppressed because it is too large
Load Diff
+496
-20
@@ -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
@@ -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"
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
��}�DZAЪ�h�:2g6���D(�@ݻQ
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"requests": []
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}}
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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 安全放宽决策**、邮箱登记与未决待办 |
|
||||
| 6 | `openclaw-API响应性能分析与优化.md` | **「API 响应很慢」的实测结论**:两天 419 次调用 / 69 段交互,deepseek-flash p50 **302ms** 而模型耗时仅占 **5.4%**(94.6% 花在串行工具循环);new-api 慢 5 倍已移除;含瓶颈定位、P0/P1/P2 优化建议、验收指标与**未验证项声明**。配套脚本 `scripts/perf-analyze.py` |
|
||||
| 7 | `bk02-dsh-openclaw-ACP集成.md` | **DSH × OpenClaw ACP 协同**:dsh 0.1.5-rc.1 安装与 `acp` profile、插件(`skillhub-plugin` / `superpowers-dsh`,含 **skillhub 污染 ACP stdout** 的坑与处置)、`~/.dsh/AGENTS.md` 全局中文指令、OpenClaw `@openclaw/acpx` 与 `dsh` harness/agent 注册(含 `Unknown agent id` 坑)、端到端验证证据(含「假成功」反例判据)、DSH Web(127.0.0.1:18787 + tailscale serve + token)、**微信/飞书/钉钉渠道 ACP 绑定能力实测**与 `delegate-to-dsh` 技能派发、排错清单与回滚。配套脚本 `dsh-acp-smoke.mjs`、`dsh-lang-check.mjs`,技能 `skills/delegate-to-dsh/` |
|
||||
|
||||
## 目录约定
|
||||
|
||||
1. **不含明文口令**:仅记录凭据的存放位置(见系统说明 §6);备份包含凭据,勿外发。
|
||||
2. **文档是快照**:版本、磁盘占用、插件清单等会变化,下判断前先用命令核对(首选 `openclaw doctor`)。
|
||||
3. **改动后要推送**:本目录属于 `~/.openclaw` 这个 git 仓库(分支 `314`、remote 为 Gitea)。
|
||||
该仓库的 `auto-commit-config.sh` 在「无变更」时会**直接退出、不推送**,因此**手动提交后必须自己 `git push origin 314`**。
|
||||
4. **新增文档**:按 `序号` 或明确主题命名,并登记到本文件。
|
||||
@@ -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())"
|
||||
```
|
||||
@@ -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 B(skill) ┐
|
||||
Task C(备份改造) ├─ 与 A 无文件冲突,可并行
|
||||
Task D(红线+索引) ┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task A:provisioning 脚本 + 中文模板
|
||||
|
||||
**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`
|
||||
|
||||
**Interfaces(Produces,Task 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)"
|
||||
|
||||
# —— ④ SQL(dry-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 B:skill `agent-provisioning`
|
||||
|
||||
**Files**
|
||||
- Create `~/.openclaw/skills/agent-provisioning/SKILL.md`
|
||||
|
||||
**Interfaces**
|
||||
- Consumes:Task A 的 CLI 契约(`new-agent.sh <id> <中文名>`)
|
||||
- Produces:main 在相应语境下加载本 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`)
|
||||
- `<中文名>`:2–20 字符,不含空白(例:`阅读`)
|
||||
|
||||
先与用户确认这两个值,再执行。
|
||||
|
||||
## 红线(禁止)
|
||||
|
||||
- ❌ 禁止自行拼 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**
|
||||
- Consumes:MySQL 中由 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 D:main 红线 + 文档索引
|
||||
|
||||
**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` |
|
||||
| 中文名 | 2–6 个汉字 | `阅读` |
|
||||
| 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 位随机密码
|
||||
④ MySQL(root 凭据取自 ~/.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/.env:DB_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=…`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user