汪
为编码代理的指令设计令牌。
我的提示、约定、技巧和脚本到处都是:在各个版本之间复制,藏在被忽略的文件夹中,慢慢地分散开来。每个新项目都以同样的方式开始。找出最后一个代理文件,复制它,修复几行不同之处。全部都是Markdown, Markdown不作曲。
设计系统很久以前就解决了这个问题。您不需要将十六进制代码粘贴到每个组件中。你给颜色命名一次,点一个别名 color.primary 暗模式改变了别名的含义。沃夫给你的特工指示。将每个约定、提示符或脚本作为命名令牌编写一次。令牌相互引用并构建更大的指令。每个项目只覆盖不同的部分。将代币共享或私有,在回购中或不在回购中。
你不会乱跑的。你的代理:
在一个覆盖的回购中 git.commit 对于常规提交,同样的请求也会得到您 feat(cli): add export command 代替。没有复制。同伴技能教你的代理搜索声音,使用它找到的东西,并在它改变任何东西之前与你核实。
它是如何工作的
共享默认值,项目覆盖
您的共享令牌驻留在您的家中,您的代理可以从任何项目中找到它们。项目只覆盖不同之处。其他所有内容都来自共享令牌。
shared
├─ git.commits.seven_rules "Follow the seven rules of a great commit message…"
├─ git.commits.conventional "Use Conventional Commits: type(scope): summary…"
└─ git.commit → git.commits.seven_rules
acme (project)
└─ git.commit → git.commits.conventional
globex (project)
└─ git.commit "Start every subject with the ticket ID, such as GLX-142…"
acme 将别名指向另一个共享规则。 globex 自己写。其他项目都遵守这七条规则。
说 acme 是你的团队的回购。它的基本配置存在于repo中,每个人都可以通过Git获得它。 globex 是一个你不能提交的客户端回购,所以它的配置在你的家里是私有的。Woof通过路径找到它,包括工作树。
从片段构建指令
一个令牌可以拉入其他令牌 {{…}}. 从你已经拥有的部分构建你的代理指令:
agents.instructions
# Working in this repo
- Commits: {{git.commit}}
- Testing: {{testing.policy}}
- Style: {{code.style}}
你的代理。md或CLAUDE。Md缩减为一行,同一行在每个repo中都有效:
Run `woof get agents.instructions` and follow it.
在 acme,提交行显示为常规提交。在 globex这是票务规则。你从不碰 agents.instructions.
运行令牌
令牌也可以是bash、node、tsx或bun脚本。一些脚本为您提供指示。其他人只是做一份工作。
git.branch bash git branch --show-current
checks.all bash pnpm lint && pnpm test && pnpm build
You're on {{git.branch}}. 读起来像 You're on feat/export. 当你说“检查”的时候,你的代理人就会跑 checks.all. 项目像覆盖任何其他令牌一样覆盖脚本,因此相同的请求在每个repo中都做正确的事情。
用简单的语言询问
您不需要记住令牌名称。给一个令牌一个描述和标签,你的代理就会根据它的用途找到它。搜索只读取名称、描述和标签。它从不加载每个提示符或运行脚本,因此代理只获取它需要的提示符。
同伴技能, woof-execution,教会你的代理这个循环:搜索、获取、跟踪。它还为您编写令牌,因此您不必手动编辑JSON。或减价。(对不起,减价。不是你的问题,是我的问题。
编辑、共享和回购设置的工作方式相同。你的代理人提议,你批准。
与同事分享
如果你能承诺回购,比如 acme,将其woof配置保存在那里,Git将与您的团队共享。客户回购是另一回事。您的代理指令并不总是属于其他人的代码库,但是您在该客户机上的同事仍然可以使用它们。所以还是把配置放在家里吧,比如 globex,并将其作为文件共享。
让你们的代理出口。Woof打包令牌和文件 globex 需要一个拉链:
在山姆这边,任何新东西都是直接进来的。任何与Sam已有的不同的东西都在等待Sam的选择,一次一个:
在写任何东西之前,woof保存一个备份。
对于Sam应该提供的值(如暂存凭证),请在共享令牌之前要求代理将其标记为私有。山姆得到了一个占位符。
开始
Woof运行在npx中,所以没有什么需要安装的。需要Node.js 22.13+、24或26+。
粘贴到你的代理中:
Run `npx @mnbny/woof readme` and set up woof for me.
您的代理人阅读本指南。当它第一次运行woof时,woof会提示同伴技能,并且您的代理会在安装它之前询问您。
接下来,把它加满。Woof的效果取决于您给它的标记,所以从原语开始:约定、提示、文档和您已经拥有的技能。将你的代理指向它们,它会将它们保存为一个令牌:
- “把我们的提交规则留给woof吧。” 您的代理起草令牌,向您显示它,并在您同意后保存它。
- “把文档添加进去
docs/conventions/汪。” 每个文档都变成一个令牌,其中包含代理可以搜索的名称和描述。 - “把我的代码审查技能变成一种标志。” 它的说明现在可以在每个项目中使用。
- “指示我的探员。汪汪叫。” 它将您的指令移动到令牌中,并在后面留下一行。
然后让他们工作:
- “woof有什么代码审查工具?” 它搜索名称、描述和标签,并显示适合的内容。
- “使用woof标记进行代码审查。” 它获取匹配的令牌并遵循其指示。
- “用羊毛来做这件事。” 它找到您的提交约定并遵循它。
- “为这个回购设定目标。” 它创建了repo的woof配置,提交的或私有的。你的电话。
在引擎盖下
下面的所有内容都是纯JSON,由代理为您编写。这是它们是如何组合在一起的,一次一小块。
代币在哪里
你共享的代币存放在你的窝里的一个文件里, ~/.woof/woof.config.json. 您的代理通过woof编辑它,您可以手工编辑它。
令牌
令牌是该文件中的密钥。嵌套键构建它的路径:
{
"git": {
"commits": {
"seven_rules": "Follow the seven rules of a great commit message: …"
}
}
}
这是 git.commits.seven_rules. 普通字符串是提示符。
为了帮助代理找到令牌,将字符串替换为长形式,并带有描述和标签:
{
"$type": "prompt",
"$exec": "Follow the seven rules of a great commit message: …",
"$description": "How to write commit messages",
"$tags": ["git"]
}
以开头的键 $ 属于伍夫。其他的都是你的名字。
对于长提示,将其保存在文件中。一个普通的字符串或 $exec 可以指着它:
"<root>/resources/review-checklist.md"
<root> 是你的家乡。在repo的配置中, <repo> 指向回购。
别名
只有一个引用的字符串是别名:
{
"git": {
"commit": "{{git.commits.seven_rules}}"
}
}
点 git.commit 在一个不同的令牌上,使用它的所有东西都紧随其后。
复合材料
引用在文本中的任何地方都可以使用:
{
"agents": {
"instructions": "# Working in this repo\n\n- Commits: {{git.commit}}\n- Testing: {{testing.policy}}"
}
}
Woof首先应用覆盖,然后解析引用,因此覆盖会到达每个复合。写 {{{{ 和 }}}} 对于字面双括号。丢失的记号或循环在运行之前就失败了。
脚本
集 $type 来 bash, node, tsx,或者 bun, $exec 变成脚本。这是 git.branch:
{
"$type": "bash",
"$exec": "git branch --show-current"
}
该脚本在repo根目录下运行,其输出成为该值。 $exec 也可以是文件,比如 "<root>/scripts/checks.sh"或按顺序运行并在第一次出现故障时停止的脚本列表。
私人的价值观
你可以保留 globex伍尔夫的分期付款。让你的代理在你和山姆分享之前把这个令牌标记为私有。它增加了 $private 令牌:
{
"$type": "prompt",
"$exec": "user1:pass user2:pass",
"$private": true
}
你仍然能在本地得到真正的价值。导出将其替换为 {{-woof:private-}}. Sam可以导入配置并要求其代理填写自己的值。在此之前,只要他们的代理使用令牌,woof就会发出警告。
项目
一个项目更改一个代码库的令牌。它只保存不同的内容,其他所有内容都来自您的共享令牌。一个项目存在于两个地方之一。
在你的窝里
私有项目永远不会进入repo,所以它即使在你不能提交的地方也能工作,比如 globex. 让你的代理人为回购建立一个私人的融资项目。它将项目添加到您的共享文件 $projects,以及选择它的路径:
{
"$projects": {
"globex": {
"$metadata": {
"$basePaths": ["~/code/globex"],
"$worktreePaths": ["~/code/globex-*"]
},
"git": {
"commit": "Start every subject with the ticket ID, such as GLX-142…"
}
}
}
}
汪选择 globex 在任何地方 ~/code/globex,并在每个匹配的工作树中 ~/code/globex-*.
在回购中
让你的代理人为回购设立资金。它创建了一个 woof.config.json 在回购根,或者在 .agents/ 或者 .claude/. 提交它,只要你在repo中工作,在任何克隆或工作树中,woof都会使用它,所以你的整个团队都能得到它。这是 acme’s,指向另一个别名:
{
"git": {
"commit": "{{git.commits.conventional}}"
}
}
哪个项目适用?
Woof每次运行都会选择一个项目:你命名的项目,然后是repo自己的配置,然后是路径匹配的私有项目。如果没有匹配,则单独应用共享令牌。
参考
这就是游览。从这里开始,它很快就会变得详细:完整的配置、每个规则和每个命令。你的代理人仔细阅读了这一部分。你可以略读。
配置模式
这是参观的所有资料, ~/.woof/woof.config.json:
{
"$schemaVersion": 2,
"git": {
"commits": {
"seven_rules": {
"$type": "prompt",
"$exec": "Follow the seven rules of a great commit message: …",
"$description": "How to write commit messages",
"$tags": ["git"]
},
"conventional": "Use Conventional Commits: type(scope): summary…"
},
"commit": "{{git.commits.seven_rules}}",
"branch": {
"$type": "bash",
"$exec": "git branch --show-current"
}
},
"testing": {
"policy": "Run the tests before you push."
},
"checks": {
"all": {
"$type": "bash",
"$exec": ["pnpm lint", "pnpm test", "pnpm build"]
}
},
"review": {
"checklist": "<root>/resources/review-checklist.md"
},
"agents": {
"instructions": "# Working in this repo\n\n- Commits: {{git.commit}}\n- Testing: {{testing.policy}}"
},
"$projects": {
"globex": {
"$metadata": {
"$basePaths": ["~/code/globex"],
"$worktreePaths": ["~/code/globex-*"]
},
"git": {
"commit": "Start every subject with the ticket ID, such as GLX-142…"
}
},
"initech": "<root>/projects/initech.json"
}
}
和 acme的repo配置:
{
"$schemaVersion": 2,
"git": {
"commit": "{{git.commits.conventional}}"
}
}
值
| 价值 | 例子 | 意味着 |
|---|---|---|
| 字符串 | "Run the tests before you push." | 提示 |
| 恰好是一个引用的字符串 | "{{git.commits.seven_rules}}" | 别名 |
| 内部有引用的字符串 | "Commits: {{git.commit}}" | 复合提示 |
以开头的字符串 <root>/ 或者 <repo>/ | "<root>/resources/review-checklist.md" | 提示符从文件读取 |
对象与 $type | { "$type": "bash", "$exec": "…" } | 资源:提示符或脚本 |
| 任何其他物体 | { "commits": { … } } | 名称空间 |
保留键
| 关键 | 属于 | 价值 |
|---|---|---|
$schemaVersion | 每个配置文件,在顶层 | 2 |
$type | 一个资源 | prompt, bash, node, tsx,或者 bun |
$exec | 一个资源 | 提示文本、脚本源或 <root>/ 或者 <repo>/ 文件。脚本也接受一个列表。 |
$description | 一个资源 | 可选的搜索文本 |
$tags | 一个资源 | 可选的搜索字符串列表 |
$private | 一个资源 | 可选布尔。 true 用 {{-woof:private-}} 在出口。 |
$projects | 您的共享文件 | 私有项目按名称:inline或 <root>/ 项目自己文件的路径,例如 initech |
$metadata | 私人项目 | 可选 $basePaths 和 $worktreePaths |
$basePaths | $metadata | 选择项目的路径,包括它们下面的所有内容 |
$worktreePaths | $metadata | 匹配当前目录或其父目录之一的模式 |
规则
- 令牌名称使用ASCII字母、数字、
_,-,它们是区分大小写的。点将名称连接到路径中。 - 一个未知的
$失败的关键。 - 值可以是字符串、资源或命名空间。数字、布尔值、
null,裸阵列失效。 <root>是你的家乡。<repo>是所选项目签出的根:项目路径中的当前签出,或者是项目存在的第一个基本路径。没有,<repo>文件失败。共享令牌不能使用<repo>. 文件路径不能是绝对的或空的,不能使用..,并且必须解析为其根目录中的常规文件。- 路径在
$basePaths和$worktreePaths是绝对的还是开始的~/. Woof会忽略您的机器上不存在的路径,因此队友可以列出他们自己的路径。 - 共享令牌必须在没有项目的情况下解析。它们不能引用仅用于项目的令牌或
<repo>文件。 - 重写将替换整个令牌,包括其描述和标记。项目不能用令牌替换共享的名称空间,也不能用名称空间替换令牌。
- 在任何脚本运行之前,缺少引用或循环失败。引用自身的令牌是一个循环。
{{-...-}}为内部标记保留。添加和导入产生此语法的重新映射拒绝令牌地址,例如-draft-. 写{{{{-woof:private-}}}}从字面上显示私人标记。- 一个checkout包含一个repo配置:
woof.config.json,.agents/woof.config.json,或者.claude/woof.config.json. 两个不同的文件失败。 - 每个配置文件都声明
"$schemaVersion": 2. Woof从不自己升级文件。当它请求迁移时,使用--migrate.
命令
您的代理运行这些作为 npx @mnbny/woof <command>. 添加 --help 任何命令的完整选项。
| 命令 | 它是做什么的 | 选项 |
|---|---|---|
woof readme | 打印本指南。代理首先运行它。 | - - - - - - |
woof get [query…] | 当查询是其确切路径时,打印令牌的值。否则,搜索。 | --search 总是去寻找, --project <name> |
woof add [path] | 添加令牌 | --type, --content, --description, --tag, --private,其中之一 --shared, --repo,或者 --project <name> |
woof edit [path] | 更改令牌的内容、描述、标记或隐私 | --content, --description, --tag, --private 或者 --no-private, --shared 或者 --override, --project <name> |
woof init [location] | 创建一个repo配置或一个私有项目 | --repo,或者 --name <name> 与 --base-path 和 --worktree-path |
woof projects | 显示当前目录选择的项目,并列出私有项目 | - - - - - - |
woof explain [path] | 在不运行脚本的情况下,跟踪令牌解析的方式 | --project <name> |
woof validate [path] | 检查每个令牌,或一个令牌的图形,而不运行脚本 | --project <name> |
woof export | 将私有项目打包到zip in中 ~/.woof/exports/ | --project <name> |
woof import <archive> | 询问存档中的每个冲突,然后应用它 | --decisions <file> |
每个命令还需要 --agent 和 --migrate. woof --help 和 woof --version 工作太。
选项
--content接受文本、现有文件的路径或-读取标准输入。--tag,--base-path,--worktree-path重复一遍:--tag git --tag commits.- 在
edit,一个空的--description或者--tag删除它。--shared为每个项目更改共享令牌,并且--override仅在所选项目中覆盖它。 --private在add或者edit集合$private: true.edit --no-private删除字段。其他编辑保留隐私设置。在已经公开的定义上单独禁用隐私不会产生任何变化。- 限定地址,如
'$projects.globex.git.commit',以同样的方式选择项目--project globex所做的。引用它,壳就离开了$projects独自一人。
代理模式和退出状态
- Woof从环境中的标记中检测编码代理。
--agent覆盖任何其他来电者。 - 代理模式运行相同的操作,使用纯文本,没有问题。
- 当命令需要一个决定时,它打印选择和要继续的确切命令,不写入任何内容,并以状态1退出。
get准确地打印解析后的值,这样就可以对其进行管道处理。- 退出状态为
0成功,1在失败或交接时,和130关于一个取消。
导出和导入
- 导出从所选项目的令牌开始,并在应用覆盖之后遵循它们的引用。它省略了不相关的共享令牌、覆盖的默认值和未使用的文件。空项目不导出共享令牌。
- 直接或通过另一个令牌依赖于项目覆盖的共享令牌导出为项目令牌。独立的共享依赖保持共享。
- 对于每个导出令牌
$private: true、羊毛代替$exec与{{-woof:private-}}并保留令牌的地址、类型、元数据和隐私标志。仅被省略的内容使用的文件和引用不包含在存档中。 - 隐私只适用于标记的令牌。未标记的令牌仍然可以导出相同的文件。本地值和源文件保持不变,恢复备份保留私有值。
- Import警告占位符并继续。同一层中同一地址的不同值需要冲突检查。即使新项目令牌覆盖了共享令牌,也会添加新令牌。
- 每次到达私有占位符的查找都会命名令牌,询问其值,并在错误时发出警告。将标记替换为
woof edit停止警告并保留隐私标志。
脚本
每次代理获得脚本令牌时,都会运行一个脚本令牌,它打印的内容将成为该值。
运行时
bash你的派对。node:与运行woof相同的Node.js。tsx: TypeScript通过一个固定的tsx,从npx。它不会进行类型检查。bun发夹,源自npx。
脚本所在的位置
$exec 保存脚本本身,或指向一个文件:
<root>/…你家里有个文件。<repo>/…:选中项目签出中的文件。仅限项目令牌。
笔记
- 脚本在所选项目的签出中运行,与
<repo>. 如果没有,它们将运行在当前的repo根目录中,或者在repo外部的当前目录中。 - 脚本列表按顺序运行,并在第一次出现故障时停止。
- 私有占位符返回对缺失值的请求,而不启动运行时。如果脚本列表中的任何条目是占位符,则不运行该列表。
- 第一个
tsx或者bun运行可能需要网络。 - 如果脚本失败,则查找失败。Woof不会撤销脚本已经执行的操作,也没有超时。
- 只有
get运行脚本。搜索,explain,validate永远不会做。
文件和文件夹
所有的喵星人都在你的喵星人家里生活, ~/.woof.
在你的窝里
woof.config.json:您的共享令牌和私人项目。resources/文件不会为你的令牌复制进来。exports/:来自woof export..backups/:备份woof import在写入之前保存。
在回购中
woof.config.json,.agents/woof.config.json,或者.claude/woof.config.json:回购的项目。只保留一个。
笔记
- 汪创造了它的家
woof.config.json这是它第一次需要它们。 - 伍夫保留了所有的备份。要恢复一个,把它提取出来。
限制和决定
限制
woof还没有做到的是:
- 没有重命名、移动或删除命令。手动编辑JSON,或者让代理编辑,然后运行
woof validate. - 每次运行一个项目,所以你不能在repo的配置上叠加个人覆盖。
- 脚本不接受参数。每次运行都使用编写的脚本。
- 在Windows上,取消脚本会停止脚本本身,但不会停止它所启动的进程。macOS和Linux清理一切。
- 这个
woof edit页面从CDN加载它的样式,所以它是离线的。
深思熟虑的决定
汪汪故意做什么:
- 重写将替换整个令牌。要在共享值上构建,请从覆盖中引用其部分。令牌不能引用自己。
- 与设计令牌一样,对共享令牌的更改会立即到达每个项目。没有版本固定。
- Repo配置通过Git传输。只有私人项目出口。
- 脚本输出为纯文本。伍夫从不在里面找参考资料。
- 引用脚本的组合在每次查找时都会运行脚本,因此请将具有副作用的脚本排除在组合之外。
- 脚本按您的方式运行,没有沙箱、超时或撤销。在从不熟悉的repo获取令牌之前,请检查它的配置
woof explain. - 搜索将名称、描述和标记匹配为文本。它不是语义性的,所以好的描述是有用的。
- woof借用了设计标记的想法,而不是DTCG文件格式,因此DTCG工具无法读取woof文件。
- Woof在本地运行,从不调用模型。你的代理人负责思考。
开发
git clone https://github.com/mnbny/woof.git
cd woof
pnpm install
node cli/setup.mjs # links ~/.local/bin/woof to this checkout
pnpm validate # formats, lints, typechecks, and builds
pnpm test
为贡献者和代理提供设计说明 .agents/docs/.
…为什么“汪”?
| 在这种互动之后,我将我的代理称为woof。 |