Install
openclaw skills install @liuyuming0823/ym-skillhub-chSkillHub(skillhub.cn)全套操作:搜索技能、安全安装第三方技能、把本地技能一键创建或更新到商店并复核线上状态。当用户说「skillhub」「技能商店」「搜索技能」「安装技能(从 skillhub)」「看看有没有 XX 技能」,或说「发布技能到 skillhub」「更新 skillhub 上的技能」「重新发一版」「技能发版」「上架 skillhub」「发布预检」「查线上技能状态」时使用。
openclaw skills install @liuyuming0823/ym-skillhub-ch国内优先的技能源。一份技能管三件事:找别人的技能、安全地装上、把自己的发上去。
它省掉的不是敲命令的力气,而是三类静默失败:字段写错不报错、发布成功但其实没上线、 目录里躺着个不该有的文件导致整单被拒。
| 用户说 | 场景 | 用什么 |
|---|---|---|
| 「skillhub 上有没有 XX 技能」 | A · 搜索与安装 | skillhub search / install + check_slug.py |
| 「把这个技能发到 skillhub」「重新发一版」 | B · 发布/更新 | skillhub_publish.py release |
| 「商店里名字是英文 / 字段不对」 | C · 补齐字段 | skillhub_publish.py fix |
| 「发了吗?线上什么版本」 | D · 查状态 | skillhub_publish.py status |
| 「分类不对」 | E · 分类 | 网页 dashboard(脚本改不了) |
~/.skillhub/skills_store_cli.py(Windows 下即 %USERPROFILE%\.skillhub\skills_store_cli.py)skillhub):
~/.local/bin/skillhub.cmd(cmd/PS)、skillhub(Git Bash)python.exe(managed 3.13 跑网络请求会 segfault);
覆盖用环境变量 SKILLHUB_PYTHON。skillhub login --key skh_xxx,token 落 ~/.skillhub/credentials.json。
不确定就跑 doctor 自检四项。⚠️ 在 Git Bash 里直接跑
skillhub会RuntimeError: Could not determine home directory(shim 的 HOME/PATH 残缺)。脚本已内置cli_env()绕开;手工排错时也要显式传HOME/USERPROFILE。
本技能的脚本只调用下面两个包外文件,不修改、不读取其中凭据,也不把内容外传。用前建议自行核对来源与内容:
| 依赖 | 来源 | 缺失时的表现 |
|---|---|---|
~/.skillhub/skills_store_cli.py | SkillHub 官方 CLI 的安装产物 | 发布类操作直接报错并给安装指引;可用 skillhub doctor 自检 |
~/.workbuddy/tools/push_via_api.py | 使用者本机自备的 GitHub 推送辅助脚本 | 仅「同步 GitHub」用得到;缺失时改用普通 git push |
除这两个本地文件外,本技能只访问 api.skillhub.cn 与 api.github.com 两个第一方服务。
skillhub search <关键词>
skillhub install <slug> --namespace <ns> --dir "<技能根目录>"
skillhub skill reports <slug> --namespace <ns> # 安全报告(腾讯云)
skillhub skill evaluation <slug> --namespace <ns> # 边界/触发质量评分
搜索结果每行 - install: skillhub install <slug> --namespace <ns> 就是可复制的命令,补上 --dir 即可。
其中 <技能根目录> 指 WorkBuddy 技能目录,Windows 下通常是 C:/Users/<用户名>/.workbuddy/skills(必须写绝对路径)。
标准流程(第三方技能必须走完):
--dir 先指到临时 quarantine 目录,不碰正式技能目录。os.system / subprocess / eval / exec / rmtree / 外联域名 / 读取无关文件;
同时拉 reports + evaluation。完整审查清单、拍平脚本、命名空间说明见
references/search-install.md。
python scripts/skillhub_publish.py release <技能目录> --changelog "本次改了什么"
首次使用先跑 doctor 自检(CLI / python / 登录 / 网络四项)。
脚本按 5 步走,每步都打印结论:
| 步 | 做什么 | 失败怎么办 |
|---|---|---|
| 1/5 fix | 补 slug / displayName / summary / tags,把块标量、多行列表、行尾注释规整成平台能读的形态 | 分类不在枚举内会提示用 --category 指定 |
| 2/5 bump | 版本递增(默认 patch) | 当前值不是 SemVer 时改用 --set X.Y.Z |
| 3/5 check | 平台字段 + 解析器怪癖 + 扩展名白名单 + 本地市场体检 + CLI dry-run | 有阻断自动中止发布,逐条列出原因 |
| 4/5 publish | 调 skillhub CLI publish | 返回非 ✓ 即失败,把原始输出贴出来 |
| 5/5 status | 查线上 latestVersion / category / 版本列表 | 网络问题只告警,不影响发布结论 |
讲结果时这三件事不能省:① 版本号与 skillId;② 线上当前 latestVersion 是哪个、
新版本在不在「已过审版本」列表里;③ 明确说「已上线」还是「审核中」 —— 两者在命令输出上
长得一模一样,只有版本列表能区分。
release 开关:--set X.Y.Z / --minor / --major / --fix-only(只补字段不发布)/
--force(预检有阻断也发)。退出码:0 通过 / 1 告警 / 2 阻断 / 3 环境不可用。
python scripts/skillhub_publish.py fix <技能目录> --category dev-programming
python scripts/skillhub_publish.py check <技能目录>
fix 是行级改写,只动要改的那几行,正文一字不改;重复跑不会累积改动。
python scripts/skillhub_publish.py status <slug> --expect 1.2.0
--expect 的版本出现在已过审版本列表里 = 已上线;stats.versions 比列表长度大 = 有版本在审核中
(也可能是历史被驳回的版本,公开接口区分不了,要定性只能看后台)。
不带 --expect 只报现状。
字段位置别找错:详情接口 GET /api/v1/skills/<slug> 的计数是 skill.stats.versions(嵌在 skill 里),
响应根节点没有 stats;根节点只有 latestVersion / namespace / securityReports。
已过审列表另走 GET /api/v1/skills/<slug>/versions?page=1&pageSize=50。
改不动就是改不动:CLI 发布 payload 里没有 category,平台也不解析 SKILL.md 里的 category。
fix --category 只能让仓库里的声明正确,线上分类必须去 https://skillhub.cn/dashboard 手动改。
遇到这种情况直接告诉用户去哪儿点,别反复重发。
pay-skill)付费技能发不了 CLI,必须网页后台手工上传。判不准就先问用户,别先发。
skillhub_publish.py 的 payload 里没有 pricing / capability / x402 / amount_fen 任何计费字段,
release 发出去的永远是普通免费技能,还可能被判「站外交易引流」。pay-skill(付费技能)
→ 计费模式选「按调用量计费」→ 填单价(元 / 次)。status 查 slug 返回 404 时,只能说明没有公开上线,无法区分「审核中」与「已驳回」;要定性就让用户看后台技能列表。SkillCatalog 配置 / 支付平台登记单价 / 上架表单标价。S=~/.workbuddy/skills/ym-skillhub/scripts
# ── 搜索 / 安装 ──
skillhub search <关键词>
skillhub install <slug> --namespace <ns> --dir "<技能根目录>"
python $S/check_slug.py ym-foo ym-bar # 批量查 slug 是否被占
# ── 发布 / 更新 ──
python $S/skillhub_publish.py doctor # 环境自检
python $S/skillhub_publish.py check <技能目录> # 发布预检
python $S/skillhub_publish.py fix <技能目录> # 补平台字段(幂等)
python $S/skillhub_publish.py bump <技能目录> # 版本递增
python $S/skillhub_publish.py status <slug> [--expect X.Y.Z]
python $S/skillhub_publish.py release <技能目录> --changelog "..."
# ── 批量上架(一次推一批:发布 + 同步 GitHub + 双项校验)──
python $S/batch_release.py ym-foo ym-bar --gap 40 # 指定技能
python $S/batch_release.py --from-list list.txt # 从清单读
python $S/batch_release.py ym-foo --stage github # 只补推 GitHub
python $S/batch_release.py ym-foo ym-bar --dry-run # 先看计划
scripts/skillhub_publish.py —— 发布全部逻辑(frontmatter 行级读写、CLI 调用、状态查询)scripts/check_slug.py —— 批量自查 slug 占用scripts/batch_release.py —— 批量上架:发布(固定间隔防限流)+ 建仓推 GitHub + 双项校验,
退出码 0 全成功 / 1 有失败 / 2 参数错。命令幂等,重跑失败项即可。references/search-install.md —— 搜索、安全审查清单、命名空间拍平、安装后配置references/platform-fields.md —— 平台字段规范、13 个分类枚举、解析器怪癖、文件白名单references/troubleshooting.md —— 按症状排错:发布 ≠ 上线、分类改不了、slug 占用、环境坑正文够用就不必读 references/;遇到「字段没生效」「发布被拒」「不知道线上为什么没变」再去查。
把 ✓ Published 当「已经上线」 —— 它只代表平台受理。线上字段分三档:tags 秒级生效;
version / summary / 描述 / 版本列表 / 下载包要等三线审核(实测约 3 分钟);category 走 CLI 永不变。
判据是版本列表里有没有那个版本号。
看到商店没变就立刻重发 —— stats.versions 把待审版本也计入,所以「计数涨了但版本列表没动」
= 审核中。重发只会多出无意义的版本号。
以为改 SKILL.md 的 category 能改分类 —— 分类写对、过审成为 latestVersion 之后线上仍是旧值。
平台根本不解析它,只能去网页 dashboard 改。
displayName 写成 display_name —— 平台只认驼峰。缺了不报错、发布照样成功,
只是商店显示英文 slug。要发布的技能两套都写。
category 用了 development —— 不在 13 枚举内,对应 dev-programming;填错不报错,显示「未分类」。
description 写成 YAML 折叠块(>-) —— 平台只读「key: 值」那一行,>- 被读成字面量两个字符。
tags: 写多行 - 项 同理读空。长文本折一行、列表用 [a, b]、注释独立成行。
把 trigger 也一起「规整」了 —— trigger / display_name / agent_created 是 WorkBuddy 本机字段,
平台不看。脚本只规整 PLATFORM_KEYS;擅自压平本机字段会把技能弄坏。
技能目录里留着非白名单文件 —— 平台按扩展名逐个校验,命中一个整单拒收
(「不支持的文件类型: xxx」)。最易忽略:.gitignore / .gitattributes(迁到 .git/info/)、
*.template(改 .md)、附件与 zip(放目录外)。「本地打包器排除了」≠「发布时不校验」。
自查:git ls-files | sed 's/.*\.//' | sort -u。
--dir 传了 MSYS 风格路径 —— /c/Users/... 会被原生 python 当相对当前盘解析,
实际装到 D:\c\Users\...。永远写 C:/Users/...。任何传给脚本的路径同理。
社区命名空间技能装完是两层嵌套 —— ~/.workbuddy/skills/@<ns>/<slug>/SKILL.md,
WorkBuddy 只扫平铺目录,必须拍平并改 lock 文件里的 installDir。
拿下载接口判断「slug 是不是被别人占了」 —— 200/302 只说明「该 slug 已被发布」,
自己发的也是 302;404 也不代表可用(草稿/审核中/私有同样是 404)。要认作者看 namespace.handle。
用搜索接口判重 —— search?q= 是模糊匹配,短前缀词会返回兜底热门榜,看着像无结果其实是没匹配上。
判重用 check_slug.py(下载接口),但仍需在发布表单里最终确认。
连续发布不加间隔 —— SkillHub 有频率限制,连发到第 4 个开始报「发布频率过高」。 每个之间 sleep 40 秒(实测连发 30 个零失败,约 20 分钟跑完)。批量发布直接照这个节奏, 别等报错再补救式重试。失败后同样按 40 秒间隔重发可以全部追回。
批量建仓时 GitHub 返回 422 —— 连推十几个仓库后 POST /git/trees 或 /git/commits
会返回 422 Unprocessable Entity,这不是参数错,是次级限流。隔一会儿重跑同一个仓库即可,
通常报「tree 已一致,无需推送」。push_via_api.py 已内建 403/422/429/5xx 退避重试(3 次)。
仓库里有中文等非 ASCII 文件名 —— git 默认 core.quotepath=true,
git ls-tree -r --name-only 会把中文文件名(例如 风险规则清单.md)输出成
"\351\243\216..." 这种八进制转义串,脚本据此 cat-file 必然取不到对象,
报「HEAD 中不存在该路径」而整仓库静默失败。push_via_api.py 现已改用
git -c core.quotepath=false ... -z,中文文件名可正常推送;自建脚本也要带这两个参数。
以为「审核」只是等一会儿 —— 三线审核里有一条安全评估(腾讯云 cloudsec),出独立报告,
结论分 benign / 可疑风险 / 恶意。判为可疑时等多久都不会过,必须改代码重发
(skillhub_publish.py status 只会显示"还在审核中",看不出被拦的原因,别一直挂后台等)。
实测被拦的两类模式(ym-pay-service-source 1.4.1,健康度 50):
SKILL.md 与脚本,且摘要校验形同虚设
→ 「供应链风险 / 远程脚本下载执行」。install -m 755 进 /usr/local/bin、无哈希校验
→ 「远程脚本下载执行」。
另有三条通用要求:全程 HTTPS + 域名白名单(文档里的明文 HTTP 裸 IP 示例也会被点名)、
不用 @latest 浮动版本、更新/安装前必须让用户确认并展示变更。
查结论:GET https://api.skillhub.cn/api/v1/skills/<slug> 的 securityReports.{keen,sanbu}
(带 reportUrl 可直接看报告)。⚠️ 该接口不提供包 sha256,只有
latestVersion.{version,changelog,createdAt} —— 所以"下载后核对平台摘要"这条路走不通,
要么自带发布方签名,要么干脆别让技能自动覆盖自己。被判「可疑风险」后的整改套路(2026-09-18 在 ym-pay-service-source 上跑通:1.4.1 被判可疑、
整改后 1.4.2 一次提交即过):
sync.py 从「下载整包 + 原地覆盖自己」改成只读版本自检器(只比对版本、
只给重装命令),命中项直接归零。教训:即便把摘要、签名、域名白名单全做齐,
「下载 + 写回技能目录」这个行为模式本身大概率仍被命中。@latest 固定版本 → 下载后比对 sha256 → 解压前核对包内声明。
写死哈希之前先做 User-Agent 对照实验:同一个 CDN 地址可能按平台分发,
或根本只有单一平台(本次那个 alipay-bot 制品实测四种 UA 字节完全一致、恒为 linux-amd64,
于是文档里那条「手动安装」命令在 mac/Windows 上装的是跑不起来的 Linux 二进制 ——
这种"文档里一直错着"的毛病会被审核连带审出来)。/usr/local/bin 改为 $HOME/...,系统目录只在显式 --system 时使用。curl … | tar … 这类「下载即执行」写法都会单独被点名。skillhub_publish.py check 的「平台侧预检」会跑本地市场体检,
P1 会拦住打包。本次被一个「看起来像文件路径的引用」误报过 P1
(公式:文字里出现 host/路径/文件名 就会被当成引用缺失),改成不带路径的措辞即可。写给自己用的称呼和路径,分发出去就是废信息 —— 技能是边用边写长出来的,正文里很容易
冒出「让 XX 挑」「提醒 XX」这类只对原作者成立的称呼,命令示例里也会顺手贴本机绝对路径。
自己用完全没问题,一旦上架或发给同事:称呼变成陌生人看不懂的名词,绝对路径在别人机器上
直接跑不通(--dir 传自己的路径还会把技能装到别人的盘里)。
分发前人工搜一遍这四类(本地体检器查的是凭据与路径硬编码,不查个人称呼):
① 个人昵称 / 真名;② C:\Users\<用户名> 这类带用户名的盘符路径;
③ 写死的提交邮箱、GitHub 账号;④ 只在原作者机器上存在的文件引用(某工作区的 dist/xxx.md)。
改完之后,路径统一用 ~ 或占位符,示例用 C:/Users/<用户名>/...。
--dir 显式写技能根目录的 Windows 绝对路径(见「场景 A」说明)。org-28ib33ph,
下挂 19 个 lingyi-*)—— 先搜清楚是技能还是发布方,是发布方就列清单让用户挑。skillhub;无匹配或不可用时再回退其他来源并说明。mkdir / dirname 都没有),先补一段再跑命令:
把 Git 自带的命令目录前置到 PATH 最前面即可 —— 即本机 Git 安装目录下的 usr/bin
与 mingw64/bin。只作用于当前这条命令,不改动系统环境变量,也不影响其他会话。PYTHONIOENCODING=utf-8;PowerShell 读长输出用
| Out-File "$env:TEMP\x.txt" -Encoding utf8 再用 Read 看(直接返回的 stdout 常被吞)。
⚠️ 实测(2026-09-19)光靠 Out-File -Encoding utf8 不够:Python 吐的是 UTF-8 字节,
PowerShell 默认按 GBK 解码 → 落盘的就是乱码文本。python -X utf8 也单独无效。
必须在同一次会话里先设解码侧:
[Console]::OutputEncoding = [Text.Encoding]::UTF8; $OutputEncoding = [Text.Encoding]::UTF8
再跑 python 并重定向到文件,最后用 Read 看。config 只支持 list,不能持久化默认 --dir,所以每次都要显式传。skillhub list 看不到用 --dir 装的技能(只扫默认目录);skillhub verify 对社区命名空间返回 405。git push(Empty reply from server / 502),但 gh api 通:
python ~/.workbuddy/tools/push_via_api.py <仓库目录>(验证只看 tree sha)。只留最近两版;完整历史见 references/CHANGELOG.md。
安全审计整改:删掉文档里隐藏的「审计放行」注释。 平台第三方安全审计(腾讯云 sanbu 引擎)
判出 suspicious,命中项是正文里一处 HTML 注释形式的放行标记 —— 它本是本地体检器
「按行跳过检查」用的,写进分发出去的说明文档就变成「不可见 + 让审计跳过」的隐藏指令。
export PATH="..." 的写法,改为「把 Git 自带
命令目录前置到 PATH」),从源头不再命中体检的「引用系统目录」规则 —— 根本不需要放行;api.skillhub.cn 与 api.github.com。体检 P0=0 / P1=0,且不依赖任何放行标记。
脱敏:清掉技能里残留的使用者个人标识。 这类内容自己用没感觉,分发出去就是废信息:
references/ 里的个人昵称 → 统一改为「用户」;C:\Users\...、Git 安装路径)→ 改为 ~ 或占位符写法;batch_release.py 里写死的提交邮箱 → 改为 --email 参数(兜底 GitHub noreply 地址),
docstring 里的 GitHub 账号示例 → 占位符;dist/上架填写信息.md)→ 改为通用清单。配套新增常见坑第 18 条(分发前自查清单)—— 本地体检器不查这一类,只能人工过一遍。
(v2.2.4 及更早见 references/CHANGELOG.md。)