docs / automation

自动化与 CI

给脚本、CI 任务和 agent 的读法:退出码怎么分支、--json 报告里有什么、action 词表、接进流水线的完整模式、非交互环境的约定。按任务的实操在场景指南,逐条命令的 flag 在命令参考

退出码

脚本、CI 任务或 agent 需要从一次 skillmod 运行里做判断,而不是由人读输出时,看退出码:

退出码含义什么时候出现
0所有受检条目一致检查与操作正常完成
1操作或输入错误任何命令
2检出漂移verify 发现内容与 SKILL.lock 不符
3部分完成:独立的工作已完成,一个或多个目标被安全保留getsyncupdateremove 保留目标而不是覆盖它时

getsyncupdateremove 在保留目标而不是覆盖它时返回 3。这既不是彻底失败,也不是完全成功:读报告,看保留了什么、为什么保留。

漂移单独占 2,因为它和“操作出错”是不同的结论。verify 的职责是检查一致性:内容与锁记录不符是一个确定的状态判断,该和参数错误、环境问题区分开,脚本才能分别处置。

构建门槛的读法:把任何非零退出都当失败。2 意味着检出的技能环境与声明不符,3 意味着有目标被安全保留——两者都该让流水线停下,报告留给排障。

--json

所有命令都支持 --json。命令照常打印给人看的摘要,加上 --json 后,同时在 stdout 输出一份结构化报告。

报告把“哪条命令产生了它”和“每条声明、每个安装目录的结果”分开:

字段含义action 取值
action产生报告的命令getinitlistpruneremovesharesyncupdateupgradeverifywhy
entries[].action一条声明的汇总结果conflictdriftinstallinstalledkeeplocallocal-driftmatchedmissingpartialpruneremoveskipstaleunlockedunresolvedunverifiableupdate
entries[].targetResults[].action一个安装目录的结果driftinstallinstalledkeepmissingremoveskipunlockedunverifiable

字段名和 action 标识永不翻译。脚本按命令和 action 标识分支,不要解析自然语言备注:note 是给人看的译文,跟着输出语言变。

检查类报告(listwhyverify)的远端条目还带 requestedVersion:它是 SKILL.mod 里的原值,versionSKILL.lock 记录的安装版本。requestedVersion 为空,表示这条声明跟随 latest,具体版本由 lock 钉住。

upgrade 用同一形状:action"upgrade",只有一个名为 skillmod 的条目。条目 action 为 keep 表示当前运行的就是所求版本,为 update 表示有新版本,entries[0].version 给出该版本号;可执行文件自己的 targetResults[0].action 说明文件发生了什么:installed 是被替换,install 是 dry-run 验证通过,keep 是原样未动。升级失败时报告照写,--json 总能解出一个文档。

$ skillmod upgrade --check --json
不下载,只观察有没有新版本

action 词表

命令层的取值就是十一条命令名:报告由哪条命令产生,顶层 action 就是哪个词。条目层和目录层的完整词表如下。

entries[].action(一条声明的汇总结果)

action含义
conflict目标目录里是不同内容,按冲突策略处置
drift内容与 lock 记录不符
install计划中的安装,dry-run 已验证、尚未写入
installed已写入,且与 lock 记录相符
keep已符合预期,原样保留
local本地声明,没有远端来源
local-drift本地条目被编辑过,与记录的基线不符
matchedinit 匹配到既有锁记录或已验证快照的来源
missing安装目录不存在
partial部分完成:有工作完成,也有目标被保留
pruneprune 清掉了失效的安装或锁记录
remove声明(或分享链接)被移除
skip按冲突策略跳过该目标
stale声明已不在 SKILL.mod 里,安装仍然残留,用 prune 清理
unlocked声明在 SKILL.lock 里没有对应记录
unresolved来源无法解析为 Git 仓库,作为本地条目保留
unverifiable目录读不动或内容无法校验
update已更新;upgrade 报告里表示有新版本可用

entries[].targetResults[].action(一个安装目录的结果)

action含义
drift目录内容与 lock 记录不符
installdry-run 验证过的计划安装
installed已写入,且与 lock 记录相符
keep目录已符合预期,未改动
missing目录不存在,或分享链接缺失
remove该目录(或分享链接)被移除
skip按冲突策略跳过
unlocked目录没有锁记录可对照
unverifiable目录读不动或内容无法校验

报告形状的稳定性约定:

  • 分支只依赖命令标识和各级 action 取值:它们稳定、永不翻译;note 是译文,不拿它分支。
  • entries[].action 是聚合值,把该条目各目标的结果汇总成最可行动的状态;某个目录比整条声明更重要时,读 targetResults
  • 每目录的事实只出现在 targetResults:冲突或读不动的目录在其中保持可见,命令其余部分照样成功。
  • requestedVersion 只出现在检查类报告的远端条目上,为空表示跟随 latest。
  • upgrade--json 即使升级失败也写报告,总能解出一个文档。

接进 CI

完整模式是四步:checkout、安装 skillmod、syncverifyverify 是构建门槛,退出码非零就让构建失败。

$ git clone https://github.com/acme/project.git && cd project
checkout:SKILL.mod 和 SKILL.lock 随仓库一起到位
$ go install github.com/huija/skillmod@latest
安装 skillmod;镜像里没有 Go 工具链时,用 GitHub releases 的预编译包
$ skillmod sync
按 lock 安装或对齐声明的 skill
$ skillmod verify
构建门槛:退出码 2 即失败

verify 的退出码显式接进流水线:

$ skillmod sync
$ skillmod verify --json > verify.json
$ code=$?
$ [ $code -eq 0 ] || { cat verify.json; exit 1; }
退出码 2(漂移)或 3(部分完成)都让构建失败,报告留给排障
  • sync 幂等,按 SKILL.lock 安装或对齐内容,不会静默覆盖本地修改;verify 检查的是对齐之后的结果。
  • 要机器可读的结论就加 --json,按命令和 action 标识分支,并把报告存进构建产物方便排障。
  • CI 里没有 TTY,可能进入选择的命令要先给定选择,见下一节。
  • 想在流水线里观察 skillmod 自身的新版本而不下载:skillmod upgrade --check --json
网络:已经物化的不可变快照可以离线工作,latest 版本解析需要远程引用。干净环境里第一次 sync 通常要能访问仓库。

非交互环境约定

CI 和脚本里没有 TTY,可能弹出选择的命令要预先把选择给定。--all--yes 分工明确:--all 决定选择本身——get 取全部已发现的 skill,remove 取全部已声明条目,share 取全部已安装 skill;--yes 只回答选择之后的确认,从不决定选什么。

多 skill 仓库的非交互运行必须说 --all,否则卡在选择这一步。在终端上 --yes 仍由用户挑选 skill,只跳过后续确认;shareremove 同理。

$ skillmod get github.com/acme/agent-skills//review --all --yes
--all 过选择,--yes 过确认,两步都不弹
$ skillmod remove --all --yes
$ skillmod share --all --agent claude --yes

--dry-run 的用途是写入前先看报告:initsync --relinkremovepruneshareupgrade 都支持。upgrade --dry-run 下载并校验,但不替换可执行文件;--check 在下载之前停下。dry-run 不写状态、不建链接,适合先确认再执行。

语言与环境

命令帮助、摘要、提示和错误跟随 SKILLMOD_LANG;未设置时读系统 locale,依次 LC_ALLLC_MESSAGESLANG,取不到或不支持时回退英文。

JSON 字段名和 action 标识不受影响:脚本设不设 SKILLMOD_LANG 都能按标识分支。设它是为了让人读的输出稳定在一种语言上——CI 日志尤其值得固定,免得换台 runner 提示就变样。

$ SKILLMOD_LANG=zh_CN skillmod verify
人读的输出固定为中文,退出码不变
$ SKILLMOD_LANG=en skillmod verify --json
--json 的报告与语言无关
延伸阅读:逐条命令的 flag 词表见命令参考;按任务的实操见场景指南;报错与状态异常见故障排查