/Release/v2.0.0-analysis
由冯宝宝自动生成。
# omni-express 仓库分析报告
> **分析时间**: 2026-04-06
> **仓库**: `npc/omni-express`
> **版本**: v2.0.0
> **分析者**: 冯宝宝 🪴
---
## 一、项目概览
| 属性 | 值 |
|------|-----|
| **项目名称** | omni-express(哪都通 Agent) |
| **版本** | 2.0.0 |
| **语言** | TypeScript (ES2022 / ESNext Module) |
| **运行时** | Node.js 22+ |
| **包管理器** | npm |
| **许可证** | MIT |
| **定位** | 基于 CNB NPC CLI 的 AI Agent,在 Issue/PR 评论中 @触发自动接单执行 |
### 项目口号
> **冯宝宝一个人,就是整个哪都通。**
---
## 二、目录结构
omni-express/
├── .cnb.yml # CNB CI/CD 配置(Docker 构建 + 知识库 + NPC 触发)
├── .gitignore # Git 忽略规则
├── Dockerfile # 多阶段构建(builder → npc runtime)
├── README.md # 项目说明文档
├── npc.json # NPC Agent 配置(模型、会话、工具)
├── package.json # 项目依赖与脚本
├── tsconfig.json # TypeScript 编译配置
├── start.sh # 容器启动入口脚本
├── test.sh # 本地测试脚本(Issue/PR 双模式)
│
├── assets/
│ └── fengbaobao.png # Agent 形象图(冯宝宝)
│
├── docs/ # CNB API 参考文档(注入为知识库)
│ ├── cnb-api-reference.md # 完整 API 参考(24KB)
│ └── cnb-api-quickref.md # API 快速参考(3.5KB)
│
├── skills/ # 自定义技能
│ └── upload-release/
│ └── SKILL.md # Release 上传技能说明
│
└── src/ # 核心源码(TypeScript)
├── main.ts # 应用入口(编排层)
├── context.ts # 运行上下文收集与环境变量解析
├── prompt.ts # System Prompt 构建(双模式:对话/工作)
├── agent.ts # Agent 引擎(spawn npc CLI + 三层评论检测)
├── cnb-api.ts # CNB REST API 封装(评论发布、Issue/PR 查询)
├── tsw-preload.cjs # TSW HTTP 抓包注入脚本(diagnostics_channel)
│
└── utils/
├── logger.ts # 结构化日志模块(脱敏、截断、分级)
└── convert-link.ts # 相对链接转绝对 URL 工具
---
## 三、技术架构
### 3.1 整体架构:NPC-First 薄编排模式
┌─────────────────────────────────────────────────────┐
│ CNB 平台事件 │
│ issue.comment / pull_request.comment │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ omni-express(薄编排层) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ context │→ │ prompt │→ │ agent │ │
│ │ 上下文 │ │ Prompt │ │ spawn npc CLI │ │
│ └──────────┘ └──────────┘ └────────┬─────────┘ │
│ │ │
│ ┌──────────┐ ▼ │
│ │ cnb-api │◄────────── npc CLI JSON 输出 │
│ │ 降级代发 │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ npc CLI(Agent 引擎) │
│ LLM 推理 + 工具调用 + 会话管理 │
└─────────────────────────────────────────────────────┘
**核心设计理念**: omni-express 本身不做 AI 推理,只负责:
1. **上下文收集** — 从环境变量和 CNB API 收集运行时信息
2. **Prompt 工程** — 构建结构化的 System Prompt 和 User Message
3. **生命周期管理** — 启动 npc CLI、监控输出、降级处理
### 3.2 数据流
CNB Webhook → 环境变量注入 → main.ts 入口
↓
loadContext() → 解析所有环境变量到 OmniContext 对象
↓
preloadContext() → 通过 CNB API 预加载 Issue/PR 详情
↓
buildSystemPrompt() + buildUserMessage() → 构建完整 Prompt
↓
runAgent() → spawn("npc", ...) → LLM 执行任务
↓
extractReply() → 三层 fallback 评论检测
↓
createComment() → 降级代发评论(如 Agent 未自行发出)
### 3.3 关键设计决策
| 决策点 | 方案 | 原因 |
|--------|------|------|
| AI 引擎 | 外部 npc CLI(非内嵌) | 解耦、可独立升级引擎 |
| 评论检测 | 三层 fallback(trace → regex → summary) | 最大化可靠性 |
| 日志方案 | stderr 输出(stdout 给 JSON) | 不污染 npc JSON 输出 |
| 部署方式 | 多阶段 Docker 构建 | 最终镜像基于 npc:latest |
| Prompt 设计 | 协议层分离(system/user 独立) | 结构清晰、易于维护 |
---
## 四、核心模块详解
### 4.1 `main.ts` — 应用入口
**职责**: 编排整个请求处理流程
**关键逻辑**:
- **防循环检测**: 跳过自身发出的评论(`enginePrefix` 匹配)和外部 NPC 的回复
- **图片提取**: 从 Markdown/HTML 中提取图片 URL,支持多模态输入
- **优雅退出**: SIGINT/SIGTERM 信号处理
- **降级机制**: 当 Agent 有回复但未成功发评论时,自动代发
```typescript
// 核心流程伪代码
1. loadContext() // 加载环境变量
2. 校验 + 防循环检测 // 安全检查
3. preloadContext() // 预加载 Issue/PR 详情
4. extractImageUrls() // 提取图片
5. buildSystemPrompt() // 构建 System Prompt
6. buildUserMessage() // 构建 User Message
7. runAgent() // 启动 npc CLI
8. 降级处理 // 代发未发出的评论
context.ts — 上下文管理职责: 从环境变量构建 OmniContext 对象
OmniContext 接口:
interface OmniContext {
commentBody: string; // 用户评论内容
issueIid: string; // Issue/PR 编号
resourceType: "issue" | "pull";
repoSlug: string; // 仓库路径
isNpcTrigger: boolean; // 是否由 NPC 触发
triggerNpcSlug: string; // 触发者 NPC slug
apiEndpoint: string; // API 地址
token: string; // 认证 Token
enginePrefix: string; // 回复前缀(默认【哪都通】)
sessionId: string; // 会话 ID(格式 resource:iid)
enableWorkmode: boolean; // 是否工作模式
issueDetail?: { ... }; // 预加载的 Issue/PR 详情
}
关键函数:
loadContext() — 必需环境变量校验(缺失则抛异常)preloadContext() — 异步预加载 Issue/PR 详情(失败不阻塞)prompt.ts — Prompt 工程职责: 构建完整的 System Prompt 和 User Message
双模式设计:
| 模式 | 触发条件 | 特点 |
|---|---|---|
| 对话模式 | 默认 | 轻量交互,适合问答、总结等 |
| 工作模式 | CNB_NPC_ENABLE_WORKMODE=true | 支持代码修改、commit、创建子 issue 等 |
System Prompt 结构:
<character_settings> ← 角色设定(冯宝宝人设)
<tone_guide> ← 语调指南
<runtime_context> ← 运行时上下文(仓库、资源、用户信息)
<pr_context> ← PR 专属上下文(仅 PR 场景)
<rules> ← 工作流程规则(标准 4 步流程)
<tips> ← 操作提示(API 用法模板)
<comment_format> ← 评论格式规范
<preloaded_context> ← 预加载的 Issue/PR 详情
安全规则内置:
agent.ts — Agent 引擎职责: 通过 spawn npc CLI 执行 AI 任务
核心能力:
--images 参数传入图片 URLtsw-preload.cjs 进行 HTTP 抓包三层评论检测机制(创新设计):
第 1 层: 结构化 trace 检测(最可靠)
└─ 解析 npc trace 中的 toolCalls,匹配评论/评审 API 调用
第 2 层: stdout + stderr 正则 fallback
└─ 在组合输出中搜索评论 API URL + 成功响应特征
第 3 层: summary 关键词 fallback
└─ 在 summary 文本中搜索"评论已发布"等关键词
cnb-api.ts — API 封装职责: 封装 CNB REST API 调用
API 列表:
| 方法 | 用途 | 调用时机 |
|---|---|---|
createComment() | 发布评论 | 降级代发 |
getIssue() | 获取 Issue 详情 | 预加载上下文 |
getPullRequest() | 获取 PR 详情 | 预加载上下文 |
utils/logger.ts — 日志模块特性:
[REDACTED]utils/convert-link.ts — 链接转换功能: 将用户输入中的相对路径转换为 CNB 平台绝对 URL
智能排除:
...)内的链接不转换...)内的链接不转换支持的转换模式:
/-/xxx → {webEndpoint}/{repoSlug}/-/xxx./path 或 ../path → {webEndpoint}/{repoSlug}/-/git/raw/{branch}/pathtsw-preload.cjs — 抓包注入用途: 通过 NODE_OPTIONS="--require" 注入,实现子进程 HTTP 请求抓包
技术实现:
diagnostics_channel 监听 undici HTTP 事件.cnb.yml)main push → docker buildx build(构建并推送镜像)
→ knowledge-base(构建知识库索引 docs/*.md)
issue.comment@npc 或 pull_request.comment@npc
→ 启动 omni-express 容器(4 CPU)
→ AI_MODEL=glm-5v-turbo
→ 执行 /srv/start.sh
| 阶段 | 基础镜像 | 产出 |
|---|---|---|
| builder | node:22-slim | TypeScript 编译 + 生产依赖安装 |
| runtime | npc/npc:latest | 最终运行镜像(含 git/lfs/curl/jq 等) |
| 包名 | 版本 | 用途 |
|---|---|---|
@tswjs/tsw | ^2.6.10 | TSW(腾讯 Server Watcher)HTTP 抓包与诊断 |
| 包名 | 版本 | 用途 |
|---|---|---|
tsx | ^4.19.0 | TypeScript 直接执行(开发/测试用 |
| ... (文档过长,已截断,完整版见仓库 docs/repository-analysis.md) |