一行
npx,把.agents/里的 skills / rules / commands 投影到.cursor、.claude、.codebuddy等多个 AI 工具目录。
agentlink 让 .agents/ 成为单一可信源,再通过逐 agent 的轻量 adapter(处理 flatten、rename、include / exclude)投影到各家工具——全程 symlink,不复制。
.agents/ 正在悄悄成为 AI 工具间的事实约定——Cursor、Codex 已经支持从 .agents/skills/ 读取 SKILL.md,其他 agent 也在跟进。但在这个约定完全统一之前,同时使用两个以上 AI 编码工具的人,都得在 .cursor / .claude / .codebuddy / ... 之间手动复制同一份 skill / rule / command。而且各家工具还有自己的小约定:
- Cursor 的 commands 目录不支持嵌套(必须扁平)
- Cursor 的 rules 必须用
.mdc后缀 - Claude Code 从
.claude/skills/<name>/SKILL.md递归读取 - CodeBuddy 支持嵌套 commands
agentlink 就是为了弥合这个差距:
-
单一可信源 — 所有资产维护在一个
.agents/目录(个人用~/.agents,团队场景用项目内cwd/.agents)。 -
投影而非复制 — agentlink 在每个目标 agent 的目录下,为每个一级条目创建一个 symlink,并通过声明式 adapter 处理 agent 特有约定(flatten、
.mdc重命名、扁平 vs 嵌套)。 -
与
skills.sh互补 —skills.sh负责把 skill 包安装(下载)到源目录;agentlink负责把源目录投影到多个工具。两者解决的是同一工作流的不同环节:curl -fsSL skills.sh | sh -s install <pkg> # 安装到 ~/.agents/skills/<pkg> agentlink sync # 投影到 .cursor / .claude / ...
最朴素的实现是 ln -s .agents/skills .cursor/skills——整目录一条链接,简单。但这样做会让目标目录变成实际只读:你没法再往 .cursor/skills/scratch/ 里临时塞一个一次性的 skill 做实验,因为整个目录已经是源目录的别名。
agentlink 改为为每个一级条目单独创建一条 symlink(或当 flatten: true 时,按文件粒度)。受管的 skill 与你手写的 skill 可以并存在同一目录里,unlink 也只会移除自己创建的那些链接——你的临时实验不会被波及。
# 1. 在 ~/.agents 建脚手架(或加 --local 建在 ./.agents)
npx @cmkk/agentlink init
# 2. 把你的 skills/rules/commands 放进 ~/.agents/
# 3. 进入任何含 .cursor/、.claude/ 或 .codebuddy/ 的项目
cd ~/projects/some-app
npx @cmkk/agentlink syncagentlink init [--local | --source <path>] [--force] [--yes]
交互式创建 .agents/ 脚手架。三个简短提问:
1) 放在哪里(~/.agents vs ./.agents)
2) 启用哪些资产类型(skills/rules/commands/...)
3) 投影到哪些 AI 工具(cursor/claude/codebuddy)
--yes / -y 全部用默认值,跳过交互(CI 友好)
--local 跳过位置选择,直接用 ./.agents
--source <p> 跳过位置选择,用指定路径(自定义路径会打印持久化提示)
--force 目标非空时仍然合并(默认会拒绝)
管道 / 脚本场景(stdin 非 TTY)自动降级为默认值。
生成的 agentlink.config.json 写在"未来 sync 会从哪跑"的位置
(--local 写 cwd,否则写 ~),不在 source 内部。
agentlink sync [--source <path>] [--target <dir> | --user] [-n] [-f] [--strict]
刷新所有 symlink。source / destination 见下方解析链;也可写在
agentlink.config.json 的 source / target / user 字段里持久化。
destination root 默认是 cwd;--user / -u 改为 $HOME(把 source
投影到 ~/.cursor / ~/.claude / ...),--target <dir> 指定任意项目根。
--dry-run / -n 预览将做什么,不动文件系统
--force / -f 修复指向错误的 symlink
--strict flatten 撞名时报错退出(默认仅警告)
agentlink clean
清掉每个启用 adapter 目录下的悬空 symlink(指向已删除文件)。
agentlink unlink
移除所有指向 source 的 symlink,用于从项目中彻底卸载 agentlink。
agentlink doctor
只读健康检查:adapter 可用性、link plan 大小、撞名预警、
悬空链接、orphan 链接(之前 sync 留下、当前 plan 不再覆盖)。
-q/--quiet 与 -v/--verbose 对所有命令通用。
agentlink 把"对什么数据操作"(.agents/ source)与"怎么操作"(agentlink.config.json)大体解耦:config 主要描述投影行为,也可选地持久化 source / target 默认值。两者各有独立解析链。
配置文件是整文件生效——从 cwd 向上找到最近的一份 agentlink.config.json 后,整份用于 adapters / include 等;不会把「项目 config 的 adapters」和「全局 config 的 source」按字段合并。若项目目录里已有 config 文件,就不会再去读 ~/agentlink.config.json。
| # | 来源 | 说明 |
|---|---|---|
| 1 | --source <path> |
显式 flag |
| 2 | config.source |
来自已解析的那份 config;显式设置时优先于 ./.agents(避免仓库里只有几条运维 command 却挡住个人全局源) |
| 3 | ./.agents |
项目内完整 source(config 未写 source 时生效) |
| 4 | ~/.agents |
个人推荐默认 |
| 5 | (报错) | 提示用户跑 agentlink init |
| # | 来源 | 说明 |
|---|---|---|
| 1 | --target <dir> |
显式 flag |
| 2 | --user / -u |
投影根改为 $HOME |
| 3 | config.target / config.user |
来自已解析的那份 config;target 相对路径同样相对 config 文件目录 |
| 4 | cwd |
默认 |
config.target 与 config.user 互斥(schema 校验)。
| # | 来源 | 说明 |
|---|---|---|
| 1 | --config <path> |
显式 flag |
| 2 | 从 cwd 向上找最近的 agentlink.config.json |
cwd 在 home 内时停在 home;cwd 在 home 外时走到 fs 根 |
| 3 | ~/agentlink.config.json |
全局兜底 |
| 4 | (默认值) | 没找到 = 视为空配置 {} |
类似 git / eslint / tsconfig 的就近发现机制。
配置文件可选——每个字段都是可选的且有合理默认值。格式是 JSONC(标准 JSON + // /* */ 注释 + 尾逗号),所以 agentlink init 写出的种子文件自带注释,看一眼就能改,不必翻文档。
严格的闭世界 schema(用 zod 校验):adapter 名、asset 类型、顶层字段拼错都会被友好地拒绝。
| 名称 | rootDir | Skills | Rules | Commands | Prompts |
|---|---|---|---|---|---|
cursor |
.cursor/ |
嵌套 | 扁平,.md → .mdc |
扁平 | 跳过 |
claude |
.claude/ |
嵌套 | 嵌套 | 嵌套 | 未配置 |
codebuddy |
.codebuddy/ |
嵌套 | 嵌套 | 嵌套 | 未配置 |
agentlink 只会在 destination 下已经存在对应 rootDir 时才动它。绝不会主动帮你创建 .cursor/——要启用某个 agent,要么让 agent 自己跑一遍,要么手动 mkdir .cursor 表态。
需要新 agent?v1 仅内置上述三家;提 PR 加一个新 adapter 文件即可。
~/.agents/skills/brainstorming/SKILL.md ─┐
├─→ .cursor/skills/brainstorming/ (symlink)
├─→ .claude/skills/brainstorming/ (symlink)
└─→ .codebuddy/skills/brainstorming/ (symlink)
~/.agents/rules/coding.md ─→ .cursor/rules/coding.mdc (ext 重命名)
~/.agents/commands/git/commit.md ─→ .cursor/commands/git-commit.md (flatten)
└→ .codebuddy/commands/git/commit.md (保留嵌套)
- 所有链接都是相对路径:source 和 destination 一起搬家不会断
sync是幂等的:相同状态下重跑全部skippedunlink只移除"自己拥有"的(指向当前 source 的)链接,目录里其他手写内容不动--dry-run精确告诉你"会做什么",零写盘
- Node 18+
- 支持 symlink 的 POSIX 风格文件系统。Windows 上请在 WSL 内运行或开启开发者模式
v1:skill / rule / command 链接、JSONC 配置、三个内置 adapter。
不在 v1 范围(独立追踪):
- JS / TS 配置文件(
agentlink.config.{js,ts}) - 用户自定义 adapter(通过配置)
link <src> <dest>命令式接口- watch 模式
MIT.
{ // 可选。持久化 source / destination,省得每次带 flag。 // 相对路径相对于本文件所在目录解析。 // "source": "~/.dotfiles/agents", // "target": ".", // "user": true, // 与 target 二选一,等价于 --user // asset 类型白名单。默认:["skills", "rules", "commands"] "include": ["skills", "rules", "commands"], // asset 类型黑名单(永远压过 include) "exclude": [], // 各 adapter 的覆盖。值可以是 true / false / { layout: ... } "adapters": { "cursor": { "layout": { "commands": { "flatten": false } } }, // "cursor": { "layout": { "commands": { "flattenSep": "__" } } }, // 默认 - "claude": true, "codebuddy": false } }