npcplay
v0.1.23
Published
CLI for CNB NPC comments and build watching.
Readme
npcplay
一个用于 CNB 平台的 Node.js CLI,可通过评论召唤 NPC,并监控一个或多个 NPC 构建状态。
当前仓库已经完成首版 CLI 骨架和核心流程实现。
当前 npm 包名与 CLI 可执行名统一使用 npcplay。
快速开始
- 准备配置文件:
cp .env.npc.example .env.npc- 填写至少这些配置:
CNB_API_ENDPOINT=https://api.cnb.cool
CNB_WEB_ENDPOINT=https://cnb.cool
CNB_REPO_SLUG=beilinmo/CNB-NightStar/qemu-cnb
CNB_TOKEN=your_cnb_token_here
CNB_NPC_NAME=@XMZZUZHI/SuperNPC(妲己)- 直接运行:
npx npcplay --help常用命令:
# 新建 issue
npx npcplay create-issue --title "构建日志接口异常" --file ./issue.md
npx npcplay ci -T "构建日志接口异常" -f ./issue.md
# 新建 issue 默认会自动召唤 NPC
npx npcplay create-issue --title "请分析这个问题" --file ./issue.md
npx npcplay ci -T "请分析这个问题" -f ./issue.md
# 如果不想召唤 NPC
npx npcplay create-issue --title "普通问题" --file ./issue.md --without-npc
npx npcplay ci -T "普通问题" -f ./issue.md -W
# 通过 --text 直接输入 issue 正文
npx npcplay ci -T "构建日志接口异常" -t "构建日志接口在 watch 期间返回 502。"
# 列出 PR / Issues
npx npcplay list-prs --state open --page 1 --page-size 20
npx npcplay list-issues --state open --page 1 --page-size 20
npx npcplay lp -s open -p 1 -n 20
npx npcplay li -s open -p 1 -n 20
# 给 PR / Issue 发评论
npx npcplay comment --pr 23 --file ./comment.md
npx npcplay comment --issue 15 --file ./issue-comment.md
npx npcplay c -p 23 -f ./comment.md
npx npcplay c -i 15 -f ./issue-comment.md
# 评论后等待 NPC 构建完成
printf '请帮我检查最近的变更' | npx npcplay comment --pr 23 --wait
printf '请帮我检查最近的变更' | npx npcplay c -p 23 -w
# 监控构建
npx npcplay watch --pr 23
npx npcplay watch --build 123456789
npx npcplay watch --pr 23 --all-running
npx npcplay w -p 23
npx npcplay w -b 123456789
npx npcplay w -p 23 -a
# 辅助调试
npx npcplay resolve-target --pr "https://cnb.cool/foo/bar/-/pulls/23"
npx npcplay builds --pr 23 --debug
npx npcplay rt -p "https://cnb.cool/foo/bar/-/pulls/23"
npx npcplay b -p 23 -d简写别名
为方便高频使用,CLI 现在同时支持命令别名和短参数:
comment->ccreate-issue->cilist-prs->lplist-issues->liwatch->wresolve-target->rtbuilds->b
常用短参数:
-e=--env-file-p=--pr或当前命令内的--page-i=--issue-b=--build-f=--file-t=--text-T=--title-r=--repo-s=--state-n=--page-size-w=--wait-a=--all-running-d=--debug-W=--without-npc-j=--json
安装与运行
已发布到 npm,可直接运行:
npx npcplay --help本地开发运行:
npm install
npm run build
npx npcplay --help辅助调试命令:
npx npcplay resolve-target --pr "https://cnb.cool/foo/bar/-/pulls/23"
npx npcplay builds --pr 23
npx npcplay builds --pr 23 --all-running
npx npcplay builds --pr 23 --debug开发态直接运行源码:
npm run dev -- --help如果后续需要兼容旧名称,再补充别名入口。
配置文件
项目支持在当前工作目录放置 .env.npc,也支持通过全局参数 --env-file 或环境变量 NPC_CFG_ENV 指定配置文件路径。
可以直接从示例文件开始:
cp .env.npc.example .env.npc当前实现按下面顺序解析配置文件,未声明的字段再回退到进程环境变量和 CNB_* 环境变量:
--env-file <path>NPC_CFG_ENV- 当前工作目录下的
.env.npc
示例:
npx npcplay --env-file ./.config/npc.dev.env comment --pr 23 --file ./comment.md
NPC_CFG_ENV=./envs/test.npc.env npx npcplay watch --pr 23示例文件:
CNB_API_ENDPOINT=https://api.cnb.cool
CNB_WEB_ENDPOINT=https://cnb.cool
CNB_REPO_SLUG=beilinmo/CNB-NightStar/qemu-cnb
CNB_TOKEN=your_cnb_token_here
CNB_NPC_NAME=@XMZZUZHI/SuperNPC(妲己)
NPC_DEFAULT_POLL_INTERVAL_MS=5000
NPC_DEFAULT_TIMEOUT_MS=1800000字段说明:
CNB_API_ENDPOINT: CNB HTTP API 地址CNB_WEB_ENDPOINT: CNB Web 地址,用于生成构建日志链接CNB_REPO_SLUG: 当前默认仓库路径,使用纯 IID 时必须依赖它解析目标CNB_TOKEN: CNB 访问令牌,用于评论、读取 comments、读取构建状态和日志CNB_NPC_NAME: 默认 NPC mention;当 comment 正文首行没有@NPC 时会自动插入NPC_DEFAULT_POLL_INTERVAL_MS:watch轮询间隔,单位毫秒NPC_DEFAULT_TIMEOUT_MS:watch总超时,单位毫秒
默认 NPC mention 为:
@XMZZUZHI/SuperNPC(妲己)预期使用方式
1. 评论交互
新建 Issue:
npx npcplay create-issue --title "构建日志接口异常" --file ./issue.md通过 --text 直接输入 Issue 正文:
npx npcplay create-issue --title "构建日志接口异常" --text "构建日志接口在 watch 期间返回 502。"创建 Issue 时默认自动召唤 NPC:
npx npcplay create-issue --title "请分析这个问题" --file ./issue.md如果不想召唤 NPC:
npx npcplay create-issue --title "普通问题" --file ./issue.md --without-npc通过 stdin 新建 Issue:
printf '构建日志接口在 watch 期间返回 502。' | npx npcplay create-issue --title "构建日志接口异常"列出仓库 PR:
npx npcplay list-prs --state open --page 1 --page-size 20列出仓库 Issues:
npx npcplay list-issues --state open --page 1 --page-size 20对 PR 评论:
npx npcplay comment --pr 23 --file ./comment.md通过 --text 直接输入评论内容:
npx npcplay comment --pr 23 --text "请帮我检查最近的变更"通过文件输入评论内容:
npx npcplay comment --pr 23 --file ./comment.md通过 stdin 输入评论内容:
printf '请帮我检查最近的变更' | npx npcplay comment --pr 23评论后等待这次触发的 NPC build 结束:
printf '请帮我检查最近的变更' | npx npcplay comment --pr 23 --wait真实验证过的 PR 评论命令:
printf '请帮我测试一下 npcplay 的评论和构建发现链路。' | npx npcplay comment --pr 27对 Issue 评论:
npx npcplay comment --issue 15 --file ./issue-comment.md通过 URL 指定目标:
npx npcplay comment --pr "https://cnb.cool/beilinmo/CNB-NightStar/qemu-cnb/-/pulls/23" --file ./comment.md2. 监控 NPC 运行状态
监控某个 PR 相关构建:
npx npcplay watch --pr 23真实验证过的 PR watch 命令:
npx npcplay watch --pr 27监控某个 Issue 触发的 NPC 构建:
npx npcplay watch --issue 15按构建号监控:
npx npcplay watch --build 123456789真实验证过的 build watch 命令:
npx npcplay watch --build cnb-4ko-1jrp7aqji监控多个构建:
npx npcplay watch --build 123 --build 456 --build 789监控某个 PR / Issue 下所有未完成 NPC 构建:
npx npcplay watch --pr 23 --all-running当前状态
以下链路已经在真实 CNB 仓库中验证通过:
.env.npc配置加载comment从stdin或--file读取正文comment支持--text、--file、stdin/ 交互输入 三种正文来源create-issue从stdin或--file读取正文- 未提供
--file且未使用管道时,可直接在控制台输入多行正文,并使用Ctrl-D结束输入 list-prs支持按状态分页列出 PRlist-issues支持按状态分页列出 Issue- 若首行未
@NPC,则自动插入CNB_NPC_NAME - PR comment 写入
- PR comments 回读
- 识别 NPC comment
- 从 comments 中提取真实 build SN
watch --build <sn>watch --pr <iid>- 构建状态摘要和最近日志摘要输出
当前已在真实环境验证通过的命令形态:
printf '请帮我测试一下 npcplay 的评论和构建发现链路。' | npx npcplay comment --pr 27
printf '请帮我测试一下 npcplay 的评论和构建发现链路。' | npx npcplay comment --pr 27 --wait
npx npcplay builds --pr 27 --debug
npx npcplay watch --pr 27
npx npcplay watch --build cnb-4ko-1jrp7aqji当前限制:
watch --pr当前主要通过 comments 中的 build SN 做关联watch --issue还未完成真实环境验证watch --pr/--issue --all-running的“列出当前目标下所有未完成构建”仍在继续适配 CNB 的真实构建列表接口- 构建列表相关 HTTP endpoint 目前未完全收紧,必要时会回退
cnbCLI
目标
项目需要支持两类核心能力:
- 在 Issue / PR 下通过评论与 NPC 交互。
- 通过刷新项目 build logs 监控一个或多个 NPC 的运行状态。
同时满足以下约束:
- 项目以 Node.js CLI 形式交付。
- 用户可直接通过
npx npcplay运行。 - 项目上下文优先从
.env.npc读取;若不存在,再回退到CNB_*环境变量。 - PR / Issue 输入既支持简单
iid,也支持完整 URL。
设计原则
- 优先使用 CNB HTTP API,不把核心流程绑定到本地
cnbCLI 安装状态。 - 将“资源解析”、“评论发送”、“构建监控”拆为独立模块,便于扩展。
- 默认输出人类可读的状态信息,同时保留后续增加
--json的空间。 - 首个版本优先支持非交互命令模式,避免过早引入 TUI 复杂度。
- 首个版本优先跑通核心流程,再考虑 webhook、daemon、复杂缓存等增强能力。
配置来源与优先级
配置加载优先级设计如下:
- 当前工作目录下的
.env.npc - 进程环境变量
- CNB 运行时内置
CNB_*环境变量 - 命令行显式参数
注意:命令行参数本身仍然应覆盖配置文件和环境变量。上面优先级表达的是“默认值来源”。
预期支持的配置项
.env.npc 中建议支持以下字段:
CNB_API_ENDPOINT=https://api.cnb.cool
CNB_WEB_ENDPOINT=https://cnb.cool
CNB_REPO_SLUG=beilinmo/CNB-NightStar/qemu-cnb
CNB_TOKEN=xxxx
NPC_DEFAULT_TARGET_TYPE=pr
NPC_DEFAULT_POLL_INTERVAL_MS=5000
NPC_DEFAULT_TIMEOUT_MS=1800000说明:
- 若
.env.npc存在,则先加载其内容。 - 若
.env.npc中缺失某项,则继续读取当前环境。 CNB_*变量继续作为底层上下文来源。
资源识别设计
CLI 需要统一解析以下输入形式:
23https://cnb.cool/<group>/<repo>/-/pulls/23https://cnb.cool/<group>/<repo>/-/issues/15
统一解析结果
内部统一归一化为:
type TargetRef = {
type: 'pull' | 'issue'
iid: number
repoSlug: string
webUrl?: string
}解析规则
- 如果输入是纯数字:
--pr视为当前仓库下的 PR IID--issue视为当前仓库下的 Issue IID
- 如果输入是 URL:
- 自动识别是 PR 还是 Issue
- 自动提取
repoSlug - 允许跨仓库目标
- 若输入既没有显式参数,也没有 URL,则可根据当前
CNB_PULL_REQUEST_IID/CNB_ISSUE_IID自动推断当前上下文。
功能设计
一、评论交互
命令暂定:
npx npcplay comment [--pr <iid|url> | --issue <iid|url>] --body <text>零、Issue 创建
命令:
npx npcplay create-issue [--repo <slug>] --title <text> [--file <path>] [--mention-npc]行为:
- 目标仓库默认使用
CNB_REPO_SLUG。 --repo可覆盖默认仓库。- Issue 正文支持
--text、--file或stdin。 - 未提供
--file时,也支持在交互式终端中直接输入正文,并使用Ctrl-D结束输入。 - 创建 issue 时会默认开启工作模式。
- 创建 issue 时默认会检查正文首行;若首行不是
@,会自动插入CNB_NPC_NAME。 - 若不希望召唤 NPC,可显式传入
--without-npc。 - 默认输出创建后的 issue 编号和 URL。
零点五、资源列表
命令:
npx npcplay list-prs [--repo <slug>] [--state <state>] [--page <number>] [--page-size <number>]
npx npcplay list-issues [--repo <slug>] [--state <state>] [--page <number>] [--page-size <number>]行为:
- 目标仓库默认使用
CNB_REPO_SLUG。 --repo可覆盖默认仓库。- 支持
--state、--page、--page-size过滤。 - 默认输出编号、标题、状态和 URL。
--json输出结构化结果。
行为
- 解析目标资源。
- 判定评论目标类型:PR 或 Issue。
- 读取评论正文。
- 拼装并调用 CNB 能力执行评论。
- 输出评论结果摘要。
评论输入来源
comment 子命令支持两种正文输入方式:
- 通过命令行参数指定文件路径,例如
--file ./comment.md - 如果未指定文件,则从
stdin读取正文,或直接在控制台中输入多行正文,并使用Ctrl-D结束输入
首版不把 --body 作为主输入方式,避免复杂转义、多行输入和 shell quoting 问题。
建议命令形态更新为:
npx npcplay comment [--pr <iid|url> | --issue <iid|url>] [--file <path>]对 issue 评论时,工作模式默认开启。
NPC mention 自动补齐
发送评论前,需要检查正文首行是否已经显式 @ 了 NPC。
规则如下:
- 如果首行已经是 NPC mention,则原样发送。
- 如果首行不是 NPC mention,则自动在正文头部插入一行 NPC mention。
- NPC mention 优先读取环境变量
CNB_NPC_NAME。 - 如果
CNB_NPC_NAME未设置,则默认使用:
@XMZZUZHI/SuperNPC(妲己)内部可将该值统一解析为一个完整的召唤前缀字符串,而不是只保存纯名称。
示例:
输入正文:
请帮我总结这个 PR 的风险自动发送为:
@XMZZUZHI/SuperNPC(妲己)
请帮我总结这个 PR 的风险实现建议
首版优先直接调用 CNB HTTP API:
- 评论发送通过 API 完成。
- 评论列表读取通过 API 完成。
- 构建详情、构建状态、构建日志摘要通过 API 完成。
可保留一个薄的 cnb CLI 适配层作为后备方案,但不作为首版主路径。
当前实现状态
已完成:
.env.npc优先加载CNB_*环境变量回退- PR / Issue 的 IID 与 URL 解析
comment子命令--file/stdin正文输入- 首行 NPC mention 自动补齐
watch --buildwatch --pr/--issue--all-running模式
当前实现说明:
- comments API 使用明确的 HTTP 路径实现。
- build 详情和日志摘要优先走 HTTP API。
- 由于公开文档中 build/log endpoint 细节不完整,当前实现会探测一组候选 endpoint。
- 若 HTTP 失败且本地安装了
cnbCLI`,会尝试用其做构建详情和日志的后备读取。
这意味着:评论流程相对稳定;构建监控流程在不同 CNB 环境里可能仍需根据真实 API 响应做微调。
输出示例
Comment posted
target: pull#23
repo: beil inmo/CNB-NightStar/qemu-cnb
comment-id: 987654上面的 repo 行只是展示格式示意,实际实现时会输出正确 slug。
二、监控 NPC 运行状态
命令暂定:
npx npcplay watch [--pr <iid|url> | --issue <iid|url> | --build <id> ...]watch 的三种入口
- 资源入口:通过 PR / Issue 识别与其相关的 NPC 构建。
- 构建入口:直接给定一个或多个构建号进行监控。
- 资源全量入口:监控某个 PR / Issue 关联的所有未完成 NPC 构建。
监控流程
- 获取初始构建列表。
- 轮询刷新构建状态。
- 输出每个构建的当前阶段、状态、开始时间、最近日志摘要。
- 当所有构建进入终态后退出。
- 如遇超时则返回非零退出码。
终态定义
- success
- failed
- canceled
- skipped
状态识别维度
每个被监控的 NPC / 构建建议输出:
- build id
- npc 名称或触发人信息
- pipeline / stage / job
- 当前状态
- 最近一次状态变化时间
- build log url
资源入口的发现策略
你已经确认:可以从 Issue / PR 的 comments 确定对应的 build id。
首版按以下顺序尝试:
- 读取目标 PR / Issue 的评论列表。
- 识别其中真正召唤 NPC 的评论。
- 从评论内容、评论回执或约定格式中提取 build id。
- 将提取出的一个或多个 build id 加入监控集合。
- 如启用“所有未完成构建”模式,则额外拉取该目标下所有未终态 NPC 构建并合并去重。
只有在 comments 无法直接提取 build id 时,才退化为基于时间窗口和 NPC 触发信息的候选匹配策略。
日志刷新策略
- 默认轮询间隔:5 秒。
- 默认总超时:30 分钟。
- 当状态发生变化时立即刷新显示。
- 在运行中状态下,可按固定频率拉取最近几行日志摘要。
输出模式
首版建议提供两种输出模式:
- 默认文本模式:适合命令行直接查看。
--json模式:适合其他系统集成。
默认文本模式示意:
[running] build#123456 npc=代码审查员 stage=analyze job=review
tail:
- cloning repository
- parsing diff
- preparing review context
log: https://cnb.cool/.../build/123456
[success] build#123457 npc=代码审查员 stage=finish job=reply
tail:
- generated final comment
- posted comment successfully
log: https://cnb.cool/.../build/123457建议的命令结构
npcplay
comment
create-issue
list-prs
list-issues
watch
resolve-target
builds子命令说明
comment: 向 PR / Issue 发送评论。create-issue: 在仓库下创建 Issue。list-prs: 列出仓库中的 PR。list-issues: 列出仓库中的 Issue。watch: 监控一个或多个 NPC 构建状态。resolve-target: 解析 iid / URL 并输出标准结果,便于调试。builds: 根据目标资源列出识别出的候选构建。
说明:
resolve-target和builds属于开发期辅助命令,便于排错,建议保留。
建议的项目结构
.
├── package.json
├── bin/
│ └── npcplay.js
├── src/
│ ├── cli.ts
│ ├── commands/
│ │ ├── comment.ts
│ │ ├── create-issue.ts
│ │ ├── list-items.ts
│ │ ├── watch.ts
│ │ ├── resolve-target.ts
│ │ └── builds.ts
│ ├── config/
│ │ ├── load-env.ts
│ │ └── resolve-context.ts
│ ├── domain/
│ │ ├── target.ts
│ │ ├── comment.ts
│ │ └── build.ts
│ ├── services/
│ │ ├── cnb-api.ts
│ │ ├── cnb-cli.ts
│ │ ├── comment-service.ts
│ │ ├── issue-service.ts
│ │ ├── list-service.ts
│ │ ├── build-discovery-service.ts
│ │ └── build-watch-service.ts
│ ├── parsers/
│ │ ├── target-parser.ts
│ │ ├── summon-parser.ts
│ │ └── comment-input-parser.ts
│ ├── ui/
│ │ ├── printer.ts
│ │ └── json-printer.ts
│ └── utils/
│ ├── time.ts
│ └── exit-code.ts
├── README.md
└── AGENTS.md技术选型建议
首版建议:
- Node.js 20+
- TypeScript
- CLI 框架:
commander - 环境加载:
dotenv - 输出着色:
picocolors - HTTP 客户端:
undici或原生fetch
为什么这样选
commander足够稳定,适合小中型 CLI。- TypeScript 对“目标解析”和“构建状态模型”更安全。
dotenv可直接处理.env.npc的首层配置加载。- 首版不建议引入复杂 TUI 库,避免 watch 场景下界面管理成本过高。
实现策略建议
阶段 1
先跑通最小闭环:
- 解析 PR / Issue IID 或 URL
- 加载
.env.npc - 从
--file或stdin读取评论内容 - 自动补齐首行 NPC mention
- 发送评论
- 通过构建号监控单个 build
- 拉取构建最近几行日志摘要
阶段 2
扩展到资源关联:
- 从 PR / Issue comments 自动发现 build id
- 支持同时监控多个 build
- 支持监控所有未完成 NPC 构建
- 改善输出格式
阶段 3
增强可用性:
--json- 更精准的 NPC 构建关联规则
- 更完整的错误码与重试机制
错误处理原则
- 参数错误返回退出码
2 - 网络或平台调用失败返回退出码
1 - 监控超时返回退出码
3 - 部分构建失败时返回退出码
4
错误输出中应包含:
- 哪个目标失败
- 使用的是哪种解析方式
- 是 HTTP API 失败还是后备
cnbCLI 失败 - 下一步建议,例如是否补充
CNB_TOKEN或CNB_REPO_SLUG
包名建议
已检查的候选包名:
npc-cli: 已被占用npccli: 当前 registry 查询未找到npcplay: 当前 registry 查询未找到
建议:
- npm 包名优先考虑
npcplay,名称更简洁。 npccli也可作为备选。- 真正发布前再做一次 registry 复核。
已确认方案
你已经确认首版按下面的边界实现:
comment只负责向目标 PR / Issue 发评论。watch --pr/--issue支持两类能力:- 通过 comments 确定对应 build id 并监控
- 监控该资源下所有未完成 NPC 构建
- 支持同一资源下多个 NPC 构建同时监控。
- 支持跨仓库 URL。
- 首版优先使用 HTTP API。
watch输出状态摘要和最近几行日志摘要。- 首版统一使用
npcplay作为包名与 CLI 名称。 comment正文来源支持--file或stdin。- 若正文首行未
@NPC,则自动插入 NPC mention。 - NPC mention 优先读取
CNB_NPC_NAME,默认值为@XMZZUZHI/SuperNPC(妲己)。
仍需在实现时核对的技术点
- comments 到 build id 的具体格式或字段来源。
- 构建日志 API 是否支持按偏移量读取末尾若干行。
- “所有未完成 NPC 构建”是否有直接 API 过滤条件可用。
下一步
如果你确认这版设计没有问题,我下一步就开始实际构建项目,优先顺序是:
- 初始化 TypeScript CLI 工程
- 建立
.env.npc与CNB_*上下文加载 - 实现 PR / Issue IID 与 URL 解析
- 实现 HTTP API 客户端与
comment - 实现
watch --build - 实现
watch --pr/--issue
