@kanyun-ai-infra/agenthub-cli
v0.5.1
Published
AgentHub CLI — define, validate and release file-defined agents from any git repo.
Readme
@kanyun-ai-infra/agenthub-cli
在任意已有的 git 仓库里定义、校验并发布 AgentHub agent。
git 是唯一事实源:agent 定义就是仓库里的文件,push 之后发布流水线把变更带上平台。 CLI 不上传定义——那会变成第二条写通道。
npm i -g @kanyun-ai-infra/agenthub-cli三条动线
1. 接入一个已有的业务仓库
agenthub auth login # 粘贴门户签发的 platform token
cd ~/code/my-service
agenthub init --project-id <项目id> # 注入 agenthub/ 骨架 + 绑定仓库(id 从门户项目页复制)
agenthub agent new trend-scout # 生成一个 agent
$EDITOR agenthub/agents/trend-scout/CLAUDE.md # agent 的指令写这里
agenthub agent check # 本地校验
git add agenthub && git commit && git pushinit 只加不改:已存在的文件一律保持原样并列出来,绝不覆盖。
从门户「新建项目 + 新建仓库」生成的仓库不用传任何参数:仓库里
agenthub/.meta/project.yaml已写着项目 id,裸跑agenthub init就会按它绑定。
绑定仓库的 scope 已含在
agent_development预设里(project:repo-bind,独立于project:settings的更细权限,只授"绑 repo 这一个动作")。签发 token 时选这个预设,init --project-id就能用,无需额外勾选,详见文末「挂进 CI」。
--project-id只收项目 id(uuid),不收 slug(#1635):slug 只是展示名, 不能当身份用。项目 id 在门户项目页复制。
2. 日常改一个 agent
agenthub agent list # 有哪些 agent,各自校验状态如何
agenthub agent dev trend-scout # 本地开发:隔离环境里拉起原生 claude
agenthub agent dev trend-scout --project-id <id> # 同上,且让声明的 MCP / 凭据引用生效
agenthub agent check trend-scout # 只校验一个
agenthub pipeline plan --project-id <id> # push 前预演:这次改动影响哪些 agent开发 agent 请用
agenthub agent dev拉起本地会话,而不是直接在业务仓库跑claude。dev会做信息隔离(软链农场挡住仓库根的项目级配置,.claude/settings.json不进会话)和 MCP / 凭据注入(托管 MCP 换票走 gateway、secretRef解析进子进程 env);裸跑 claude 这两样都没有——本地看到的工具集和 凭据跟线上不一致,验证过的行为一上线就变。本地开发不用 push:check和dev只对工作区生效,改 → check → dev 随便循环,commit + push 留到真想发布时。
agent dev 做了什么
在临时目录里把 agent 目录的每一项软链进去,以那里为工作目录拉起你本机的
claude(用你自己的登录态和模型配置)。agent 的指令入口是目录里的 CLAUDE.md,
claude 原生就会读它,dev 对它零参数;只有声明了待退场旧字段
(systemPromptFile/内联 systemPrompt)的存量 agent 才由 dev 兜底注入。
之所以不直接在 agent 目录里跑:agent 目录躺在业务仓库里,而 Claude Code 的项目
配置是从当前目录往上找的——直接跑会把仓库根的 CLAUDE.md 和 .claude/commands
一起读进上下文,还排在这个 agent 自己的声明前面。平台上没有这些,本地调好的
行为上线就变了。
它是启动器,不是平台模拟器。两件事要知道:
- 临时目录只用来跑,不是工作区。 在里面改文件会落回真实 agent 目录(软链),
但新建顶层文件不会——所以装 skill、刷
skills.lock请在真实 agent 目录里做 (那两个文件必须进 git)。 - 模型端点和凭据本地就该与线上不同:本地是你自己的 Claude Code 配置,线上由 平台按触发会话的人注入。这一处对不齐是预期的。
MCP 与凭据引用怎么在本地生效
声明了 mcpServers 或 env 里的 secretRef 时,dev 需要项目上下文:登录
(agenthub auth login)+ 项目 id。项目 id 优先取 --project-id,缺省读仓库自己的
agenthub/.meta/project.yaml:
agenthub agent dev trend-scout --project-id <项目id>拿到之后它做两件事:
- MCP:把这个 agent 声明的托管 MCP 渲染成运行目录里的
.mcp.json。两种形态都 支持:remote换一张短期开发票据指向平台 gateway(与线上沙箱同一条代理路径, 真凭据不下发到你机器上,票退出即撤销);stdio直接在本机拉起子进程, 它的凭据经下面那条通道注入进程 env。渲染只包含这个 agent 声明过的那几个,disabled: true的不启用——本地多出线上没有的工具同样是分叉。 - 凭据引用:
env里的sec_*、以及 stdio 形态 MCP 自己的凭据,都去平台解析, 明文只进子进程 env、不落盘(.mcp.json里始终只有${...}占位符)。平台上 取不到值就拒绝启动——带着缺值跑的话,Claude Code 不会报错,它把占位符原样传 下去,最后报出来的错会指向上游而不是这里。
需要的 scope:MCP 换票要 mcp:dev-ticket;解析凭据要 secrets:resolve(它刻意不在
任何预设里,去门户用"自定义"勾选)。这两样失败都不会挡住整个会话:换不到票就是这次
没有 remote MCP,解不出 stdio 凭据就是那几个 stdio MCP 这次不启用(dev 会说是哪
几个,不静默少给你一批工具)。只有 env: 里的 sec_* 解不出来才拒绝启动——那个键
会被你 shell 里恰好同名的值悄悄顶上,是看不见的分叉。
-- 之后的参数原样转给 claude:agenthub agent dev trend-scout -- --debug。
启动前会先跑一次 check,有 error 就不启动——一个定义有错的 agent 在本地能不能跑起来
是偶然的,让它跑起来只会把错误推迟到发布期。--skip-check 是给「我正在修的就是这个
错」用的;代价是:如果错在 agent.yaml 本身(解析不了或结构不合法),dev 就拿不到
定义,model、env、旧字段的 system prompt 都不会注入。
3. 触发与观察一次发布
agenthub pipeline run --project-id <id>
agenthub pipeline status <runId> --watchpipeline run 是幂等的:同一个 commit 已有进行中的 run 时会复用它,不会重复发布。
⚠️ 这里的 “run” 指发布流水线,不是 agent 对话。平台上这个词有两义, 所以两者用的是不同的 token scope(
pipeline:*vsruns:*)。
agent check 校验哪些东西
| 层 | 内容 |
|---|---|
| ① | agent.yaml 结构(fail-closed:未知字段、未解锁的保留字段都会报错,且带完整字段路径) |
| ② | 声明的文件与磁盘双向一致:setupScriptFile、旧字段 systemPromptFile(指向的文件缺失或只有空白 = error,发布时会被判定为未解析),以及 CLAUDE.md 本身——空白 = warn(线上会当它不存在跳过、回落到平台默认 prompt,配了等于没配),超过 32768 字符 = error(线上装包硬失败,这个 revision 每次会话都起不来);memory/*.md 记忆文档预检(非 .md / 非法 UTF-8 / 空文件 / 控制字符 / 合计超 12,000 字符 = error,与发布流水线同一个函数,本地过=发布过);channels: 与 modelService 配对(声明了渠道必须声明模型服务,= error) |
| ③ | skills.json × skills.lock 一致性与钉死完备性(git 源必须钉 commit,注册表源必须钉精确版本) |
| ④ | 包内 .claude/settings.json 与 agent.yaml 的 env 里会在本地劫持会话的进程/模型路由键(BASH_ENV/LD_PRELOAD/ANTHROPIC_* 这类);.mcp.json 用法提示;待退场旧字段(systemPromptFile/内联 systemPrompt)的迁移提示 |
| ⑤ | 疑似明文凭据:env 里的(改成 secretRef 引用)。mcpServers 已经没有 per-agent config——托管 MCP 的凭据挂在平台那条记录上,yaml 里写不进凭据 |
| ⑥ | 平台引用存在性(--refs,需要网络;连不上时降级为本地各层(①–⑤、⑧,以及在 git 仓库内照跑的 ⑦)并明确告知):environment、modelService、env 里的 secretRef、channels[].wecom.secretRef |
| ⑦ | 发布面审计(对 agent 目录跑真 git check-ignore):会随发布上线却被 git ignore 的文件 = error——本地一切正常、线上静默少装的那类事故(#1934)。不在 git 仓库里时响亮跳过(exit 0 + 打印原因) |
| ⑧ | evals/*.yaml(一层,不递归)每份必须能解析并过 EvalSuiteSchema——否则发布期 discover 到它会把结论判成 errored(比「未评测」更糟)。--json 里 layer: 8 |
层 ④ 只 warn、永远不 error。它报的是包内 .claude/settings.json 的 env 里那些
进程/模型路由控制键(ANTHROPIC_*、CLAUDE_CODE_USE_BEDROCK、NODE_OPTIONS 等):
平台不读这个文件,写在这里的键线上一律不生效;值得单独提醒是因为你直接 cd 进
agent 目录跑 claude 时它们在本地会被应用,可能把这次会话的请求或进程劫走(本地测
的就不是真端点了)。要约束线上行为请用 agent.yaml 的 agentOptions。
outputStyle / permissions 这类纯本地体验字段不报——那正是本地开发面。
退出码
| 情况 | 默认 | --require-remote |
|---|---|---|
| 定义有错(①–⑤、⑦、⑧,或 ⑥ 查出引用不存在) | 1 | 1 |
| 全部通过 | 0 | 0 |
| ⑥ 连不上平台(离线 / 5xx / 401·403) | 0,但显著告知跳过了哪层 | 2 |
⑥ 连不上平台默认不算失败——否则平台一抖,全公司 repo 的 CI 一起红,而没有任何
agent 定义变坏。要让它成为硬失败就加 --require-remote,它用独立的 2 与「定义坏了」
的 1 区分开,CI 可以分别处理(前者叫作者改,后者重试)。
--json 输出带 remoteCheck(ok/skipped/failed)与 skipReason,无需解析人类文本。
挂进 CI
.gitlab-ci.yml:
agenthub-check:
image: node:22
script:
- npm i -g @kanyun-ai-infra/agenthub-cli
- agenthub agent check
rules:
- changes: [agenthub/**/*]CI 里用环境变量注入凭据,不要写文件:
AGENTHUB_TOKEN=<platform token>
AGENTHUB_BASE_URL=https://agenthub-plane.zhenguanyu.com签发 token 时选 agent_development 预设即可一次配齐日常命令所需 scope
(project:read / agents:read / agents:write / pipeline:read / pipeline:trigger /
project:repo-bind),init --project-id 绑定仓库也包含在内,无需额外勾选。
凭据存哪
~/.agenthub/config.json,0600。环境变量优先于文件——agenthub auth status
会告诉你当前用的是哪一个来源。
让编码 agent 代跑
不想自己敲这些命令,可以装 agent skill,让手边的 Claude Code 照着做。skill 已发布 到 rush registry,装到全局(所有仓库的 agent 都能用):
npx rush-ai skill install @kanyun/agenthub-cli -g只想在某个仓库 / 项目里用,不带 -g(默认就是项目级,装到当前目录),或用
--base-dir 指定项目根:
npx rush-ai skill install @kanyun/agenthub-cli --base-dir <项目根>也可以装完 CLI 后从包目录拷(skill 文件随 npm 包发布):
npm i -g @kanyun-ai-infra/agenthub-cli && \
mkdir -p ~/.claude/skills && \
cp -R "$(npm root -g)/@kanyun-ai-infra/agenthub-cli/skills/agenthub-cli" ~/.claude/skills/然后在仓库目录里说「帮我初始化 agenthub,项目是 <slug>」即可。skill 里写明了
scope 要求、参数依赖和退出码语义这些 --help 读不出来的约束,源文件是
skills/agenthub-cli/SKILL.md。
拷文件那条的
mkdir -p不能省 —— 目标目录不存在时cp -R会把源目录重命名, SKILL.md 会落在~/.claude/skills/SKILL.md而被扫不到。
