docs / concepts
核心概念
skillmod 的行为由几条固定规则决定:两个清单文件各司其职,声明与安装按作用域分开,版本只接受不可变形式。这一页把这些规则讲清楚;每条命令的逐字用法在命令参考。
两个文件
SKILL.mod 是人维护、提交进仓库的声明。SKILL.lock 是工具维护的安装记录,确定性生成,禁止手改。每条命令都会读取并校验这两个文件:手改出来的违规清单会被报错,而不是被应用一半。
| SKILL.mod | SKILL.lock | |
|---|---|---|
| 谁维护 | 人 | skillmod |
| 写什么 | 声明:source、可选 version、每个 skill 的 agents | 安装记录:解析出的 version、commit、dirhash |
| 手改 | 可以,改完提交 | 不行 |
锁定记录里三个值各自的分工:
version:钉住的不可变版本。SKILL.mod里没写version的条目跟随最新的不可变解析结果,由SKILL.lock钉住;写了的条目钉在那个 tag 或 commit 上,直到update运行。commit:解析出的提交。有它,伪版本在一台从未见过对应 tag 的机器上也能解析。dirhash:锁定的内容摘要。每条锁定记录必须是单个h1:开头的 SHA-256 值。
schemaversion = 1。没有 schemaversion 的旧 SKILL.lock 按版本 1 读取,并在下次 skillmod 写入清单状态时归一化;显式的 0、负数和未知版本会被拒绝。
作用域
skillmod 区分项目与全局两种作用域。默认是项目作用域:清单放在当前目录,skill 装进当前目录的 .agents/skills/。--global(-g)切到全局作用域:声明放在 ~/.agents/skillmod/global/,装进 ~/.agents/skills/。
| 作用域 | 声明与锁定 | 默认安装目录 |
|---|---|---|
| 项目(默认) | 当前目录的 SKILL.mod 和 SKILL.lock | 当前目录的 .agents/skills/ |
全局(--global) | $SKILLMOD_HOME/global/,默认 ~/.agents/skillmod/global/ | ~/.agents/skills/ |
skill 装进所选作用域的 .agents/skills/,skillmod 不管理其他目录约定。所有命令都接受 --global(-g),普通命令不会合并项目与全局两份清单。
同一个 skill 可以同时声明在两个作用域,此时两者共享同一份磁盘快照:所有作用域共用一个内容存储,项目、全局技能和 CI 运行复用同一批不可变快照,不会重复下载同一个仓库。global/ 目录只放清单,不是第二个快照缓存。
地址形式
仓库地址的形式是:
@<version> 只属于命令行,从不写进 source;source 里出现 @version 会被拒绝,版本写在 version 字段。HTTPS 传输是默认,两个文件都只记 host/owner/repo;其他传输因为改变了仓库的获取方式而显式记录。还拼着 https:// 的旧文件可以正常工作,下次 skillmod 写入时改写成短形式。
// 简写
// 后写单段时,skillmod 先试仓库根目录下的精确子目录,再回退到 skills/ 下任意位置的唯一技能名;同名多个时要求写全路径并给出候选。单 skill 仓库不需要 //:省略时,get 会发现根 SKILL.md 和 skills/ 下的每个 SKILL.md。
两份声明和两份锁定记录都会保留。安装目录等于 name 时,锁定记录省略 dir,只有别名条目才记录它。别名必须是可移植的名字,所有安装目录在 Unicode 规范化和大小写折叠后必须互不相同,同一个项目在 Linux、macOS 和 Windows 上行为一致。用不同别名重新 get 同一来源会保留旧目录,并提示 skillmod prune 可以清掉它。
SKILL.mod、SKILL.lock、裸仓库的配置或诊断信息。支持的传输是 https、http、ssh、file,以及 scp 风格的 git@host:path;git:// 因未认证、未加密被拒绝。SSH 用户名会保留,因为它标识传输方式;密码不会,secret 属于 Git credential helper、SSH agent 或环境变量。
版本
三种不可变形式会被接受,分支名一律拒绝——可变引用无法锁定。
| 形式 | 示例 | 什么时候用 |
|---|---|---|
| 语义化版本 tag | v1.2.0、code-review/v1.2.0 | 发布方给发布打 tag |
| 提交 SHA | 完整 40 字符 SHA | 需要一个确切修订 |
| 伪版本 | v1.0.96-0.20260624023612-49f948faa925 | 钉住一个提交;仓库有 tag 时 base 取最高 tag,没有 tag 时是纯 v0.0.0 |
没有 tag 的仓库生成 v0.0.0-<ts>-<hash>;有 base tag 时生成 v<base>-0.<ts>-<hash>。base tag 出现之前写下的锁定记录使用纯 v0.0.0-<ts>-<hash> 形状,继续有效;下一次 update 会把它们迁移到仓库的最新 tag。
安装模式
auto 优先把原生目录符号链接指向共享只读快照,链接不可用时回退逐字节拷贝,包括没有链接权限的 Windows。copy 总是创建独立目录。--install-mode 为单条命令覆盖机器配置。
链接指向机器上所有项目共享的快照,通过链接编辑就是编辑共享内容。要改先脱钩:
安装模式、缓存的绝对路径和作用域都被刻意排除在两个文件之外:相同的声明与版本,在任何系统、任何安装模式下都生成相同的清单。
共享存储
只有一个缓存,所有作用域共用 $SKILLMOD_HOME/pkg/mod/,默认 ~/.agents/skillmod/pkg/mod/:
快照可读且不可变。HTTPS、默认端口 SSH 和 .git URL 变体共享同一份快照,身份标识不带凭证,URL 里的 token 不可能成为缓存键的一部分。
第一次请求 repo@version 会物化整个仓库快照;之后从同一版本添加另一个 skill,会直接从本地子目录校验并安装,不调用 Git、不碰远程。显式的 @commit 同样复用该提交已有的快照。请求最新版本或运行 skillmod update 保持在线刷新语义。设置 SKILLMOD_HOME 可以搬迁整个存储。
--dry-run 不动清单和安装,但远程来源校验仍可能填充共享缓存。prune 删除过时的安装条目,不删除链接目标或快照;没有自动缓存逐出,手工删除快照之前先确认没有已安装的链接还在用它,也不要用删缓存来移除单个依赖。
分享给 agent
share 把每个 skill 的同名链接放进所选 agent 目录,例如 .claude/skills/<skill>,指向受管的 .agents/skills/<skill>。受管目录是唯一真实副本:改受管 skill 会同时透过每个链接可见,没有需要同步的东西。链接和安装一样使用 auto 回退,不支持符号链接的文件系统收到的是保字节拷贝。
agent 用一个目录段命名,从作用域根下的 .<name>/skills 读取,所以名单是开放的——workbuddy 和 claude 一样有效。分享记录只写名字,不写目录:存路径在别处无法复现,名字足以重建链接。
sync 在新机器上重建每个条目描述的链接,verify 报告缺失或漂移的链接;本机没有的 agent 目录会被跳过,因为声明表达的是团队意图,不是机器要求。名字用字母、数字、.、_ 和 -;前导点和大小写会被归一化,.Claude 和 claude 是同一个目标,不能出现在同一个列表里。不能作为一个可移植目录段的名字会在读取清单时被拒绝。没有 agents 或 agents 为空的条目,skill 只留在受管目录里。
share --remove --agent <name>(-r)是声明的出口:把点名的 agent 从命令指定的 skill 上解绑,并从这些条目的 agent 列表里删掉,放着外来内容的目标不动,链接拆完才保存声明。移除一个 skill 或把它当陈旧条目 prune 掉时,镜像其受管副本的链接一并拆掉,没有了 agent 的条目整个失去该字段。SKILL.lock 也记住创建过的目标:手工删掉一个 agent 名字只是移除分享意图,已有链接留给 remove 或 prune 之后清理。