ml-agent-config 发布 Agent Config Standard v1 与 Claude Code 插件
Agent-config&Claude Code mods
Max-Levitskiy 发布 ml-agent-config 插件,实现 Agent Config Standard(ACS v1),提供分层设置、不含密钥的凭据引用和可重复执行的上手流程,并附带零依赖 TypeScript loader。
Agent Config Standard (ACS v1) —— 分层设置、无密钥的凭据引用,以及可重复运行的上手流程 —— 打包为一个 skill 加一个零依赖的 TypeScript 加载器。orchestrate 和 herdr 直接引入 v1 库,而不是各自维护一份副本,而 fellow 通过 v2 agent-config CLI 读取其配置;完整规范见 standards/agent-config.md。
/plugin install ml-agent-config@max-skills
适用对象
你的 skill 现在就需要一个设置或凭据。问 Claude。它会调用 /ml-agent-config:setup,引导你确定每个值属于哪一层、凭据存放在哪里,写入文件,并用一次真实调用进行验证。
你正在构建一个需要配置的 skill 或 subagent。阅读该标准并引入 lib/config.ts 和 lib/credentials.ts —— 参见 Vendoring —— 而不是从零编写加载器、合并函数和五个凭据解析器。
它为你提供什么
设置分为三层,按顺序深度合并 —— 全局 → 仓库 → 本地。对象按键逐个合并;数组和标量整体替换;显式的 null 会删除继承的键。
| 层 | 路径 | 是否提交? | 存放内容 |
|---|---|---|---|
| 全局 | ~/.agents/config/<name>/config.json |
不适用 | 你在所有项目中的默认值 |
| 仓库 | <repo>/.agents/config/<name>/config.json |
是 | 整个团队共享的设置 |
| 本地 | <repo>/.agents/config/<name>/config.local.json |
否 —— 已 gitignore | 每次检出的覆盖项、个人路径 |
配置文件从不包含密钥,只包含对密钥所在位置的引用 —— 仓库层会被提交,因此一个可能存放密钥的配置文件最终会泄露密钥:
| 来源 | 解析方式 |
|---|---|
1password |
op read <ref> |
env |
一个环境变量 |
dotenv |
一个 KEY=value 文件(其本身必须被 gitignore) |
keychain |
macOS Keychain,通过 security find-generic-password |
command |
任意 shell 命令 —— 用于 Bitwarden、pass、Vault 等的逃生通道 |
任何引用还可以携带 "cacheVar": "MY_API_KEY"。当该环境变量持有非空值时,解析器会使用它,并且绝不触碰来源 —— 每个 shell 会话只需一次 Touch ID 提示,而不是每条命令一次,因为每次 CLI 调用都是一个新进程。不会缓存到磁盘:该变量随 shell 消亡,这正是其安全之处。
留在 v1 路径 .agents/skill-config/<name>/ 的配置不会丢失。当其层还没有 .agents/config/ 文件时,agent-config start 会在上手流程之前规划一个 agent-config:adopt 步骤,而 agent-config adopt <name> 通过 write 复制该文件,后者会检查其中是否有内联密钥、打上标记并记录日志。旧文件保持原位。当两个文件都存在时,只读取新文件,start 会报告旧文件,而不是合并它们。
在 Claude Code 上
该插件还附带一个 hooks 模块 claude-code/register.ts,Claude Code 会加载它,而其他 harness 不会。Codex 读取自己的清单 .codex-plugin/plugin.json,其中未指定任何 hooks,因此它像以前一样使用 CLI 和 skill。在 Claude Code 上,该模块增加了:
- 启动步骤,已为 skill 完成。当 v2 组件的 skill 展开时,该模块会运行
agent-config start并将输出放在 skill 文本之前,这样模型就不必查找二进制文件或运行该步骤。 - 每个会话只需批准一次 1Password。对于已就绪的组件,模块会为其
1password个引用运行一次load,因此你只需批准一次。它把密钥保存在 Claude Code 进程的AGENT_CONFIG_SECRETS环境变量中,之后每次load都从那里读取,而不是调用op。它们绝不会写入磁盘或放入对话中。带有cacheVar的引用会留给该变量,不在此处缓存。如果你拒绝,模块在下一个 skill 时不会再次询问,除非某个引用自那以后发生了变化;在批准之后新增或更改的引用会在下一个 skill 时被询问。/agent-config unlock <name>会再次询问,/agent-config forget会清除缓存,会话结束也会清除缓存。当密钥被缓存时,提示符上方会有一条横幅说明这一点。Forget 会丢弃缓存,× 会在本次会话中关闭该横幅,而 Don't show again 会把notices.cacheBanner: false保存在 agent-config 自己的全局层中(~/.agents/config/agent-config/config.json,在claude-code/agent-config.json中声明),因此该横幅在之后的会话中会保持隐藏。可在 agent-config 下的/agent-config窗格中重新开启。 - 无需输入即可重新加载。该工具
mcp__ml-agent-config__reload_plugins会在安装后运行/reload-plugins并恢复工作。 - A settings pane.
/agent-configwith no name opens a pane of short screens, one at a time, each with ‹ Back:- 组件:每个已安装且带有声明的组件,外加 agent-config 自身,以及各自是否已就绪。
- 设置:每个已声明的键、其值,以及它来自的层级(
beta · This checkout, overrides acme)。路径旁的 Show: Effective › 会打开一个简短界面,将各行切换为某一层级自身的值。每个键,包括开关类的键,按下时都会打开其编辑界面,并在那里保存。需要设置的组件会有 Set up with Claude,它会请求模型运行其引导流程。Files 列出每个层级的保存位置。 - Edit:一层一个键。它写入的层级位于标题行右侧(Project ›):按下会打开层级列表,其中比较各层级设置的内容,标记当前生效的层级,选择即可将编辑移至该层级。标题下方仅在有更多内容时显示一行:
Holds acme, but This checkout overrides it.文件位于 Files 和 Save to…。切换会保留你输入的内容,因此值可以放到它所属的位置。在值下方,Override it 列出当前生效层级之上的空层级:For the team in this repo、Just for me in this repo、In this checkout only。按下会将编辑移至该处,从当前值开始,标题下方的行会说明保存的效果:Saving here overrides Everywhere (acme) for the whole team in this repo.这些层级就是 CLI 的层:Everywhere(全局)、Project, shared(仓库)、Project, just me(用户-仓库)和 This checkout(本地);在仓库之外只有 Everywhere 存在,因此它不带按钮显示,并有一行说明原因。Save here 写入该值,Save to… 将其写入你选择的另一层级并保持此层级不变,Remove here (back to acme) 将其从该层级移除,以便较低层级显现,而 Block inherited 在此处写入 null,使其下的层级不再适用。开/关键在此处选择 on 或 off,像任何值一样保存。文件落后于其组件 schema 的层级不会被保存,因此它应得的迁移不会丢失:Set up with Claude 会先迁移它。值以纯文本读取和输入(on、a, b, c),按键的类型:数字、开或关、逗号分隔列表或文本。a, b, c无法承载的列表(数字、对象、空列表[]、含逗号或空白的项)以及对象,以 JSON 输入,以便在保存后保留。每个层级作为其自身的值进行编辑:开/关覆盖下的文本仍按文本输入。 - Source:凭据按机密所在的位置(1Password、环境变量、.env 文件、Keychain、命令)及该来源的字段进行编辑,绝不按 JSON,也绝不编辑机密本身。
- Pick from 1Password:每个账户的每个项目,每个会话每个账户通过一次
op调用列出(↻ 再次列出)。对标题、保管库和账户进行模糊搜索,优先匹配单词开头(ghact可找到 GitHub Actions),而 Account、Vault 和 Type 各自打开一个选项屏幕。项目会打开其字段;字段会填入其op://引用,当有多个账户时包含账户,编辑会等待 Save here。列表通过agent-config 1password进行,它只打印名称和引用,绝不打印字段的值。选中的引用按保管库和项目名称存储(当 1Password 接受名称时),否则按 id 存储。所有列出的保管库和项目的名称都保存在插件的存储中,跨会话保留,因此仅含 id 的引用仍可按名称读取(op://Private/GitHub Actions/username),而无需解锁 1Password。
/agent-config <name>显示组件是否就绪、缺少什么以及缓存了什么。
会话启动的任何程序都可以读取该环境变量中缓存的机密,包括模型的 shell 命令。你导出的 cacheVar 具有相同的暴露风险。
Vendoring
该库会被逐字复制到每个使用它的插件中,而不是跨插件导入。插件之间的运行时依赖会在用户只安装其中一个而未安装另一个时立刻失效;而复制则始终可用。通过将 vendored 文件的主体与规范版本进行 diff 来发现漂移——而不是用提交哈希,因为后者在每次同步时都会变动,即使没有任何更改,并且会漏掉实际发生的情况:有人编辑了副本。
plugins/ml-agent-config/skills/setup/scripts/vendor.sh sync # refresh every vendored copy plugins/ml-agent-config/skills/setup/scripts/vendor.sh check # fail if any copy has drifted
包含内容
ml-agent-config/
├── .claude-plugin/plugin.json name, description, keywords; names the Claude Code hooks module
├── .codex-plugin/plugin.json the same manifest without hooks, so Codex never reads the module
├── claude-code/ the hooks module and its tests (Claude Code only)
│ ├── screens/ the pane's screens, one file each
│ └── ui/ Screen, PickList, fuzzy search, the levels
├── types/index.d.ts the session state the hooks module keeps
├── skills/setup/
│ ├── SKILL.md the onboarding flow — detect missing config, ask, write, gitignore, verify
│ ├── lib/
│ │ ├── config.ts layer paths, deep merge, gitignore handling, credential validation
│ │ └── credentials.ts lazy resolution for all five sources, plus the cacheVar session cache; never logs a resolved secret or writes one to disk
│ └── scripts/vendor.sh sync/check the copies vendored into herdr and orchestrate
└── LICENSE
测试
claude plugin test plugins/ml-agent-config # the hooks module and its pane, in the engine's own runner bun test plugins/ml-agent-config/src # the CLI's 1Password listing and session cache
许可证
来源:Hacker News · github.com