构建系统与功能标记架构
1. 构建管道
构建入口位于 scripts/build.ts,基于 Bun 的原生打包工具 bun build。整个构建流程由 package.json 中的 npm scripts 驱动。
1.1 构建模式
| 命令 | 对应脚本参数 | 输出格式 | 说明 |
|---|---|---|---|
bun run build |
无 | 源码产物 (./cli) |
默认构建,不编译为二进制 |
bun run build:dev |
--dev |
源码产物 (./Codev) |
开发版本,自动附加 git SHA 和构建时间作为开发版本号 |
bun run build:dev:full |
--dev --feature-set=dev-full |
源码产物 (./Codev) |
开发版本,启用全部实验性功能标记 |
bun run compile |
--compile |
二进制可执行文件 (./dist/cli) |
生产构建,编译为 Bun 原生二进制 |
bun run dev |
— | 直接运行 | 通过 bun run ./src/entrypoints/cli.tsx 直接执行,跳过构建步骤 |
1.2 构建流程步骤
- Friend 前端构建检查:检查
src/components/friend/frontend/dist/index.html是否存在,若不存在则调用npm run build构建 VRM 头像前端(该前端基于 Vite + React + Three.js,位于src/components/friend/frontend/)。 - 版本号计算:
- 开发模式(
--dev):使用git rev-parse --short=8 HEAD获取当前 commit SHA,生成格式为{baseVersion}-dev.{YYYYMMDD}.t{HHmmss}.sha{commit}的版本号。 - 生产模式:直接使用
package.json中的版本字段2.1.0。 - 同时获取最近的 20 条 git log 作为 changelog(仅开发模式)。
- 开发模式(
- 编译时宏定义注入:通过
--define注入MACRO.*常量(见下文 2.1 节)。 - Bun 打包:调用
bun build,以./src/entrypoints/cli.tsx为入口,使用以下关键参数:--compile:仅在compile模式下启用--target bun:目标运行时为 Bun--format esm:输出 ESM 格式--minify:启用代码压缩--bytecode:启用字节码缓存--packages bundle:将所有依赖打包进产物--conditions bun:使用 Bun 条件导出
- vendors 复制:非编译模式下,将
vendor/目录(包含audio-capture、opus-encdec等原生二进制库)复制到输出目录的vendor/子目录下。 - 权限设置:产物文件设置
0o755可执行权限。
1.3 Friend VRM 前端构建集成
Friend 是桌面宠物 VRM 伴侣功能,其前端是一个独立的 Vite + React + Three.js 应用,位于 src/components/friend/frontend/。构建系统在主构建前检查其 dist/ 目录是否已存在:
- 若已存在(如之前构建过),跳过前端构建步骤。
- 若不存在,自动执行
npm run build(调用 Vite 进行生产构建)。 - 构建产出包含 VRM 模型文件(
.vrm)、FBX 动画文件、WASM 运行时(onnxruntime-web)、VAD 模型(silero_vad)和音效文件等静态资源。
此步骤是构建流程的前置必要条件——若 Friend 前端构建失败,整个构建过程退出并返回错误码 1。
1.4 外部依赖排除
以下 native 模块在构建时被声明为 --external,不会打包进最终产物,需在运行时由 Bun 动态解析:
@ant/*(Anthropic 内部包)audio-capture-napiimage-processor-napimodifiers-napiurl-handler-napi
这些模块通过 workspace 管理或直接从 vendor 目录加载。
2. Feature Flag 系统
2.1 bun:bundle 编译时 Feature 标记
系统使用 Bun 内置的 import { feature } from 'bun:bundle' 实现编译时条件编译。feature('NAME') 是一个编译时布尔常量,在 bun build 阶段根据 --feature=NAME 参数确定值:
- 如果
NAME在传递给bun build的 feature 集合中,feature('NAME')求值为true - 否则求值为
false - Bun 的打包器会对
feature('NAME')条件分支进行死代码消除(Dead Code Elimination, DCE)
代码中典型的使用模式:
import { feature } from 'bun:bundle'
// 编译时条件导入——false 分支在产物中完全不存在
const bridge = feature('BRIDGE_MODE')
? require('./commands/bridge/index.js').default
: null
// 编译时条件执行
if (feature('VOICE_MODE')) {
// 启用语音模式的代码
}
2.2 Feature 传递机制
Feature 标记通过三种方式传递给构建系统:
- 编译参数:
bun run ./scripts/build.ts --feature=NAME - 批量设置:
--feature-set=dev-full启用fullExperimentalFeatures数组中的所有标记 - 默认集合:
defaultFeatures = ['VOICE_MODE']始终包含在构建中
构建脚本中的优先级逻辑:
const defaultFeatures = ['VOICE_MODE']
const featureSet = new Set(defaultFeatures)
// 解析 --feature-set=dev-full
// 解析 --feature NAME
// 解析 --feature=NAME
最终所有选中的 feature 通过 --feature=${feature} 逐条传递给 bun build 命令。
2.3 编译时宏注入
除 feature() 系统外,构建脚本还通过 --define 注入一系列编译时常量(MACRO.*)。这些常量在 TypeScript 环境中通过 env.d.ts 声明类型:
| 宏 | 含义 | 值来源 |
|---|---|---|
MACRO.VERSION |
当前版本号 | package.json version 或开发版 git 版本 |
MACRO.BUILD_TIME |
构建时间 | new Date().toISOString() |
MACRO.PACKAGE_URL |
包 URL | package.json name |
MACRO.NATIVE_PACKAGE_URL |
原生包 URL | 始终为 undefined(外部构建) |
MACRO.FEEDBACK_CHANNEL |
反馈渠道 | 固定为 'github' |
MACRO.ISSUES_EXPLAINER |
Issue 说明文本 | 固定字符串 |
MACRO.VERSION_CHANGELOG |
版本变更日志 | 开发模式取 git log;生产模式固定 URL |
除 MACRO.* 外,以下 process.env 变量也在构建时注入:
| 变量 | 值 | 说明 |
|---|---|---|
process.env.USER_TYPE |
'external' |
标记为外部构建(非 Anthropic 内部) |
process.env.CLAUDE_CODE_FORCE_FULL_LOGO |
'true' |
强制显示完整 logo |
process.env.NODE_ENV |
'development'(仅 dev 模式) |
运行时环境标识 |
process.env.CLAUDE_CODE_EXPERIMENTAL_BUILD |
'true'(仅 dev 模式) |
标记为实验性构建 |
process.env.CLAUDE_CODE_VERIFY_PLAN |
'false' |
禁用计划验证 |
process.env.CCR_FORCE_BUNDLE |
'true' |
强制打包 CCR 相关代码 |
2.4 运行时环境变量动态配置
开发环境中,preload.ts 在运行时会覆盖 MACRO 的值,使用环境变量进行本地开发配置:
const version = process.env.CLAUDE_CODE_LOCAL_VERSION ?? '999.0.0-local'
// ...
Object.assign(globalThis, {
MACRO: {
VERSION: version,
PACKAGE_URL: packageUrl,
NATIVE_PACKAGE_URL: packageUrl,
BUILD_TIME: buildTime,
FEEDBACK_CHANNEL: 'local',
// ...
},
})
2.5 Feature 死代码消除机制详解
feature() 的死代码消除分为两种形态:
形态 A — 条件导入(模块级 DCE):
const remoteControlServerCommand =
feature('DAEMON') && feature('BRIDGE_MODE')
? require('./commands/remoteControlServer/index.js').default
: null
当 DAEMON 或 BRIDGE_MODE 未启用时,require() 调用和整个依赖图(包括被导入模块的所有递归依赖)均被消除。这是最有效的 DCE 形式,可大幅减小产物体积。
形态 B — 条件执行(语句级 DCE):
if (feature('VOICE_MODE')) {
// 语音相关逻辑
}
当 VOICE_MODE 未启用时,整个 if 块被消除。但被调用的模块如果已在前面的代码中被无条件导入,则仍会保留在产物中。
2.6 完整 Feature Flag 列表
以下是从代码库中提取的所有 feature('NAME') 调用,按类别分组:
语音与输入
| Feature | 用途 | 涉及文件数 |
|---|---|---|
VOICE_MODE |
语音模式:语音录制、流式 STT(语音转文字)、语音状态指示器、VAD(语音活动检测);默认启用 | ~60+ 处调用 |
NATIVE_CLIPBOARD_IMAGE |
原生剪贴板图片支持 | 1 |
助手/Kairos 会话模式
| Feature | 用途 | 涉及文件数 |
|---|---|---|
KAIROS |
Kairos 助手模式:会话管理、--session-id、--continue 参数、assistant 命令/模块、团队上下文、消息队列管理、daily-log 提示词 | ~100+ 处调用(最广泛) |
KAIROS_BRIEF |
Brief 摘要模式:简化版助手界面、brief 命令、SendUserMessage 替代 | ~25 处调用 |
KAIROS_CHANNELS |
Kairos 频道/通道系统:消息通道路由 | ~8 处调用 |
KAIROS_PUSH_NOTIFICATION |
推送通知功能 | ~4 处调用 |
KAIROS_GITHUB_WEBHOOKS |
GitHub Webhook 订阅功能(subscribe-pr 命令) | ~3 处调用 |
KAIROS_BRIEF |
同上(独立用途) | — |
桥接/远程控制
| Feature | 用途 | 涉及文件数 |
|---|---|---|
BRIDGE_MODE |
桥接模式:CLI 与 mobile/web 客户端通信、remote-control 子命令 | ~30 处调用 |
CCR_AUTO_CONNECT |
CCR(Claude Code Remote)自动连接 | 2 |
CCR_MIRROR |
CCR 镜像模式 | ~5 处调用 |
CCR_REMOTE_SETUP |
远程设置向导(web 命令) | 2 |
DAEMON |
守护进程模式:daemon worker、后台长期运行 | 4 |
DIRECT_CONNECT |
直接连接模式(URL/二维码直接连接) | ~8 处调用 |
SSH_REMOTE |
SSH 远程模式:通过 SSH 连接远程会话 | ~6 处调用 |
UDS_INBOX |
Unix Domain Socket 收件箱:对等节点发现、跨进程消息传递 | ~30 处调用 |
协作与团队
| Feature | 用途 | 涉及文件数 |
|---|---|---|
COORDINATOR_MODE |
协调者模式:多 agent 协作、任务分配、worker 管理 | ~20 处调用 |
TEAMMEM |
团队记忆系统:共享记忆文件、团队上下文读取/搜索/写入 | ~25 处调用 |
BUDDY |
桌面宠物伴侣:CompanionSprite 渲染、提示词注入、通知 | ~15 处调用 |
FORK_SUBAGENT |
子 agent 分支:fork 命令、agent 分支执行 | ~3 处调用 |
AGENT_TRIGGERS |
Agent 触发器:cron 定时任务(Create/Delete/List) | ~8 处调用 |
AGENT_TRIGGERS_REMOTE |
远程触发器 | ~3 处调用 |
AGENT_MEMORY_SNAPSHOT |
Agent 记忆快照:自定义 agent 记忆持久化 | 2 |
COWORKER_TYPE_TELEMETRY |
同事类型遥测 | 1 |
权限与安全
| Feature | 用途 | 涉及文件数 |
|---|---|---|
TRANSCRIPT_CLASSIFIER |
转录分类器:自动模式(auto mode)、权限模式扩展、YOLO 分类器 | ~60 处调用 |
BASH_CLASSIFIER |
Bash 命令分类器:对 bash 命令进行安全分类、自动批准 | ~20 处调用 |
POWERSHELL_AUTO_MODE |
PowerShell 自动模式 | ~3 处调用 |
PROACTIVE |
主动模式:模型主动发起交互、背景任务提示 | ~25 处调用 |
BYOC_ENVIRONMENT_RUNNER |
BYOC 环境运行器 | 1 |
SELF_HOSTED_RUNNER |
自托管运行器 | 1 |
上下文管理
| Feature | 用途 | 涉及文件数 |
|---|---|---|
CONTEXT_COLLAPSE |
上下文折叠:长上下文管理、413 错误处理 | ~15 处调用 |
CACHED_MICROCOMPACT |
缓存微压缩:在对话流中增量压缩上下文 | ~15 处调用 |
COMPACTION_REMINDERS |
压缩提醒 | 1 |
HISTORY_SNIP |
历史摘要截取:SnipTool、会话上下文裁剪 | ~10 处调用 |
HISTORY_PICKER |
历史选择器:对话历史浏览 | ~5 处调用 |
REACTIVE_COMPACT |
响应式压缩 | 3 |
PROMPT_CACHE_BREAK_DETECTION |
提示缓存断裂检测 | 3 |
BREAK_CACHE_COMMAND |
缓存断裂命令 | 2 |
EXTRACT_MEMORIES |
记忆提取:会话结束时的自动记忆提取 | ~10 处调用 |
MEMORY_SHAPE_TELEMETRY |
记忆形状遥测 | 4 |
工具
| Feature | 用途 | 涉及文件数 |
|---|---|---|
WORKFLOW_SCRIPTS |
工作流脚本:WorkflowTool、workflows 命令、后台工作流任务 | ~15 处调用 |
MONITOR_TOOL |
监控工具:MonitorMcpTask、后台监控 | ~8 处调用 |
WEB_BROWSER_TOOL |
Web 浏览器工具:基于 Bun WebView 的浏览器 | ~4 处调用 |
OVERFLOW_TEST_TOOL |
溢出测试工具 | 3 |
TERMINAL_PANEL |
终端面板工具 | 2 |
TORCH |
Torch 命令 | 2 |
ULTRAPLAN |
超计划模式:增强规划能力 | ~10 处调用 |
ULTRATHINK |
超思考模式 | 1 |
VERIFICATION_AGENT |
验证 agent | 2 |
EXPERIMENTAL_SKILL_SEARCH |
实验性技能搜索 | ~10 处调用 |
SKILL_IMPROVEMENT |
技能改进反馈 | 1 |
TEMPLATES |
模板系统:new/list/reply 命令 | ~6 处调用 |
构建与发布
| Feature | 用途 | 涉及文件数 |
|---|---|---|
ABLATION_BASELINE |
消融实验基线:设置多个环境变量 | 1 |
ALLOW_TEST_VERSIONS |
允许测试版本(99.99.x) | 2 |
DUMP_SYSTEM_PROMPT |
导出系统提示词(--dump-system-prompt) |
1 |
NEW_INIT |
新的初始化流程 | 2 |
用户界面
| Feature | 用途 | 涉及文件数 |
|---|---|---|
MESSAGE_ACTIONS |
消息操作:消息级交互操作 | ~4 处调用 |
QUICK_SEARCH |
快速搜索:PromptInput 内联搜索 | ~5 处调用 |
MCP_RICH_OUTPUT |
MCP 富文本输出 | 3 |
AUTO_THEME |
自动主题:跟随终端主题变化 | 1 |
BUDDY |
同上(见协作与团队分组) | — |
内部与实验性
| Feature | 用途 | 涉及文件数 |
|---|---|---|
ANTI_DISTILLATION_CC |
反蒸馏保护 | 1 |
BG_SESSIONS |
后台会话:ps/logs/attach/kill 命令 | ~8 处调用 |
BUILDING_CLAUDE_APPS |
构建 Claude Apps 技能 | 1 |
BUILTIN_EXPLORE_PLAN_AGENTS |
内置探索/计划 agent | 1 |
CHICAGO_MCP |
Chicago MCP 协议:MCP 配置、computer-use-mcp 入口 | ~10 处调用 |
COMMIT_ATTRIBUTION |
提交归属追踪 | ~4 处调用 |
CONNECTOR_TEXT |
Connector 文本块处理 | ~6 处调用 |
DOWNLOAD_USER_SETTINGS |
下载用户设置 | 1 |
FILE_PERSISTENCE |
文件持久化(public API / sessions) | 1 |
HARD_FAIL |
硬失败模式 | 1 |
HOOK_PROMPTS |
Hook 提示词注入 | 1 |
IS_LIBC_GLIBC |
检测是否使用 glibc | 1 |
IS_LIBC_MUSL |
检测是否使用 musl libc | 1 |
LODESTONE |
LODESTONE 协议注册 | ~6 处调用 |
MCP_SKILLS |
MCP 技能 | 2 |
NATIVE_CLIENT_ATTESTATION |
原生客户端认证 | 1 |
PERFETTO_TRACING |
Perfetto 性能追踪 | 1 |
REVIEW_ARTIFACT |
审查构件技能 | 1 |
RUN_SKILL_GENERATOR |
运行技能生成器 | 1 |
SHOT_STATS |
射击统计(对话轮次分布) | 3 |
SLOW_OPERATION_LOGGING |
慢操作日志 | 1 |
TOKEN_BUDGET |
Token 预算跟踪 | ~10 处调用 |
TREE_SITTER_BASH |
Tree-sitter Bash 解析器 | 1 |
TREE_SITTER_BASH_SHADOW |
Tree-sitter Bash 影子解析 | 1 |
UNATTENDED_RETRY |
无人值守重试 | 1 |
UPLOAD_USER_SETTINGS |
上传用户设置 | 1 |
2.7 实验性功能全集(fullExperimentalFeatures)
在 scripts/build.ts 中定义了一个fullExperimentalFeatures 常量数组,通过 --feature-set=dev-full 批量启用。完整列表:
AGENT_MEMORY_SNAPSHOT, AGENT_TRIGGERS, AGENT_TRIGGERS_REMOTE,
AWAY_SUMMARY, BASH_CLASSIFIER, BUDDY, BRIDGE_MODE,
BUILTIN_EXPLORE_PLAN_AGENTS, CACHED_MICROCOMPACT,
CCR_AUTO_CONNECT, CCR_MIRROR, CCR_REMOTE_SETUP,
COMPACTION_REMINDERS, CONNECTOR_TEXT, EXTRACT_MEMORIES,
HISTORY_PICKER, HOOK_PROMPTS, KAIROS_BRIEF, KAIROS_CHANNELS,
LODESTONE, MCP_RICH_OUTPUT, MESSAGE_ACTIONS, NATIVE_CLIPBOARD_IMAGE,
NEW_INIT, POWERSHELL_AUTO_MODE, PROMPT_CACHE_BREAK_DETECTION,
QUICK_SEARCH, SHOT_STATS, TEAMMEM, TOKEN_BUDGET, TREE_SITTER_BASH,
TREE_SITTER_BASH_SHADOW, TRANSCRIPT_CLASSIFIER, ULTRAPLAN, ULTRATHINK,
UNATTENDED_RETRY, VERIFICATION_AGENT, VOICE_MODE
注意:VOICE_MODE 同时出现在默认集合 defaultFeatures 和实验性集合中,此重复不会造成问题(Set 去重)。
3. 命令可用性门控
3.1 availability 声明
每个命令可以通过 availability 字段声明其适用的认证/供应商环境。src/types/command.ts 中定义了 CommandAvailability 类型:
export type CommandAvailability =
| 'claude-ai' // claude.ai OAuth 订阅用户(Pro/Max/Team/Enterprise)
| 'console' // Console API key 用户(直接使用 api.anthropic.com)
可用性声明的命令示例:
// src/commands/usage/index.ts
{ name: 'usage', availability: ['claude-ai'], ... }
// src/commands/fast/index.ts
{ name: 'fast', availability: ['claude-ai', 'console'], ... }
availability 与 isEnabled() 的职责分离:
availability= 谁能使用(基于认证/供应商的静态检查)isEnabled()= 当前是否开启(基于 feature flags、GrowthBook、环境变量等动态条件)
不存在 availability 字段的命令被视为通用命令,在所有环境中可用。
3.2 meetsAvailabilityRequirement() 检查链
src/commands.ts 中实现了 meetsAvailabilityRequirement() 函数,负责检查命令是否满足可用性要求:
export function meetsAvailabilityRequirement(cmd: Command): boolean {
if (!cmd.availability) return true // 无限制
for (const a of cmd.availability) {
switch (a) {
case 'claude-ai':
if (isClaudeAISubscriber()) return true
break
case 'console':
if (!isClaudeAISubscriber() && !isUsing3PServices() && isFirstPartyAnthropicBaseUrl())
return true
break
}
}
return false
}
检查逻辑:
- **
claude-ai**:用户通过 claude.ai OAuth 认证且为订阅用户(Pro/Max/Team/Enterprise) - **
console**:用户非 claude.ai 订阅用户、不使用第三方服务(Bedrock/Vertex/Foundry)、且使用官方 Anthropic API base URL
该检查在命令列表构建时执行,且不缓存——因为认证状态可在会话中变化(例如通过 /login 命令)。
3.3 getCommands() 中的过滤链
命令的最终可用性由 getCommands() 函数(src/commands.ts)计算,过滤链如下:
const allCommands = await loadAllCommands(cwd)
const baseCommands = allCommands.filter(
_ => meetsAvailabilityRequirement(_) && isCommandEnabled(_),
)
每个命令需同时满足:
meetsAvailabilityRequirement()— 认证/供应商匹配isCommandEnabled()— 命令级启用检查(可关连 feature flag 或动态条件)
3.4 命令级 isEnabled() / isHidden() 控制
除了全局的 feature flag 和 availability 机制,每个命令还可以单独定义 isEnabled() 和 isHidden:
isEnabled() 使用示例:
// src/commands/voice/index.ts
{ isEnabled: () => isVoiceGrowthBookEnabled() }
// src/commands/review.ts
{ isEnabled: () => isUltrareviewEnabled() }
// src/commands/session/index.ts
{ isEnabled: () => getIsRemoteMode() }
// src/commands/extra-usage/index.ts
{ isEnabled: () => isExtraUsageAllowed() && !getIsNonInteractiveSession() }
isHidden 使用模式:
// 内部命令(外部构建中完全隐藏——这些命令的 stub 文件导出此配置)
// src/commands/share/index.js
export default { isEnabled: () => false, isHidden: true, name: 'stub' }
// 条件隐藏
// src/commands/cost/index.ts
{ get isHidden() { /* 动态条件 */ } }
// 始终隐藏
// src/commands/heapdump/index.ts
{ isHidden: true }
isCommandEnabled() 的默认值为 true(未定义时),isHidden 默认值为 false。
3.5 USER_TYPE 环境变量
构建时通过 process.env.USER_TYPE 控制内部/外部构建的差异:
- 外部构建:
USER_TYPE = 'external'(当前版本如此设置) - 内部构建:
USER_TYPE = 'ant'(Anthropic 内部)
USER_TYPE 控制以下差异:
- 内部命令注册:
INTERNAL_ONLY_COMMANDS数组(包含backfillSessions、breakCache、bughunter、initVerifiers等 ~30 个内部命令)仅在USER_TYPE === 'ant'时注册。 - 工具可用性:
ConfigTool、TungstenTool、REPLTool仅在内部构建中可用。 - YOLO 分类器:内部构建使用更详细的权限分类模板。
4. 工具过滤
4.1 filterToolsByDenyRules()
src/tools.ts 中的 filterToolsByDenyRules() 函数根据权限上下文中的拒绝规则过滤工具:
export function filterToolsByDenyRules<T extends { name: string; mcpInfo?: ... }>(
tools: readonly T[],
permissionContext: ToolPermissionContext,
): T[] {
return tools.filter(tool => !getDenyRuleForTool(permissionContext, tool))
}
此过滤在工具列表最终组装前执行,确保被拒绝的工具(包括按 MCP 服务器前缀拒绝的)在模型看到之前就已移除。
4.2 完整工具组装流程
getTools() 函数(src/tools.ts)的组装流程:
- Simple 模式(
CLAUDE_CODE_SIMPLE=1):仅返回BashTool、FileReadTool、FileEditTool(或 REPL 模式下的REPLTool),加上协调者模式所需的AgentTool+TaskStopTool。 - 完整模式:通过
getAllBaseTools()获取所有工具,移除特殊工具(ListMcpResourcesTool、ReadMcpResourceTool、SYNTHETIC_OUTPUT_TOOL_NAME)。 - 应用拒绝规则:
filterToolsByDenyRules()。 - REPL 模式屏蔽:当 REPL 启用时,隐藏
REPL_ONLY_TOOLS集合中的原始工具。 - **应用
isEnabled()**:每个工具自身的isEnabled()检查。
4.3 条件工具(feature() 门控导入)
src/tools.ts 中使用 feature() 进行条件导入的工具清单:
| Feature | 工具类 | 说明 |
|---|---|---|
PROACTIVE / KAIROS |
SleepTool |
计划休眠工具 |
AGENT_TRIGGERS |
CronCreateTool, CronDeleteTool, CronListTool |
定时任务管理 |
AGENT_TRIGGERS_REMOTE |
RemoteTriggerTool |
远程触发器 |
MONITOR_TOOL |
MonitorTool |
监控工具 |
KAIROS |
SendUserFileTool |
发送用户文件 |
KAIROS / KAIROS_PUSH_NOTIFICATION |
PushNotificationTool |
推送通知 |
KAIROS_GITHUB_WEBHOOKS |
SubscribePRTool |
PR 订阅 |
OVERFLOW_TEST_TOOL |
OverflowTestTool |
溢出测试 |
CONTEXT_COLLAPSE |
CtxInspectTool |
上下文检查 |
TERMINAL_PANEL |
TerminalCaptureTool |
终端捕获 |
WEB_BROWSER_TOOL |
WebBrowserTool |
浏览器工具 |
HISTORY_SNIP |
SnipTool |
历史摘要 |
UDS_INBOX |
ListPeersTool |
对等节点列表 |
WORKFLOW_SCRIPTS |
WorkflowTool |
工作流执行 |
内部构建特有的工具(不受 feature() 控制,受 USER_TYPE === 'ant' 控制):
REPLTool:REPL 交互式开发环境SuggestBackgroundPRTool:PR 建议工具ConfigTool、TungstenTool:内部配置工具
4.4 MCP 工具合并
assembleToolPool() 函数(src/tools.ts)合并内置工具和 MCP 工具:
- 通过
getTools()获取内置工具 - 通过
filterToolsByDenyRules()过滤 MCP 工具 - 使用
uniqBy()按名称去重(内置工具优先) - 按名称排序以保证提示缓存稳定性
5. 构建产物
5.1 输出目录结构
构建产物的 dist/ 目录结构:
dist/
├── cli # 生产二进制(`--compile` 模式,~192MB)
├── cli.js # 生产源码产物(非编译模式,~20MB)
├── Codev # 开发二进制(`--dev --compile` 模式,~202MB)
└── vendor/ # 原生二进制库(仅非编译模式)
├── audio-capture/ # 音频捕获原生模块
├── audio-capture-src/ # 音频捕获源码
└── opus-encdec/ # Opus 编码/解码
5.2 各模式产物对比
| 构建模式 | 入口文件 | 产物路径 | 大小 | 类型 |
|---|---|---|---|---|
build(默认) |
scripts/build.ts |
./cli |
~0(源码引用) | 源码(Bun bundle) |
build:dev |
scripts/build.ts --dev |
./Codev |
~0(源码引用) | 源码 |
compile |
scripts/build.ts --compile |
./dist/cli |
~192MB | Bun 编译二进制 |
compile + dev |
scripts/build.ts --compile --dev |
./dist/Codev |
~202MB | Bun 编译二进制(调试) |
5.3 预加载脚本
preload.ts 是开发模式下的运行时预加载脚本,在执行入口文件前:
- 设置
MACRO全局变量 - 设置
CLAUDE_CODE_LOCAL_SKIP_REMOTE_PREFETCH=1跳过远程预取 - 切换到调用目录(
process.chdir(CALLER_DIR))
5.4 Friend 前端静态资源
Friend VRM 前端构建产出包含大量静态资源(位于 src/components/friend/frontend/dist/):
- VRM 模型:5 个
.vrm文件(11MB-48MB 不等) - FBX 动画:约 10 个动画文件(
angry.fbx、happy.fbx、greeting.fbx等) - VMD/VRMA 动作:
jile.vmd、idle_loop.vrma、playFingers.vrma等 - WASM 文件:onnxruntime-web 运行时的多个 WASM 二进制(
ort-wasm-simd-threaded.wasm等,合计约 80MB) - VAD 模型:
silero_vad_legacy.onnx(1.8MB)、silero_vad_v5.onnx(2.3MB) - 音效:
jile.mp3(4.2MB)、love.mp3(11MB) - 音频工作集:
vad.worklet.bundle.min.js(2.5KB) - HTML 入口:
index.html
5.5 WASM 与原生库
项目依赖多个 WASM 和原生库:
- onnxruntime-web:用于语音活动检测(VAD)的推理引擎
- audio-capture-napi(workspace):原生音频捕获库,通过 workspace
packages/audio-capture-napi管理 - doubaoime-asr:字节跳动豆包语音识别引擎(workspace symlink)
6. 开发工作流
6.1 开发模式启动
# 直接运行(无需构建,适合快速迭代)
bun run dev
# 等价于:bun run ./src/entrypoints/cli.tsx
# 开发构建 + 运行
bun run build:dev
./Codev
# 开发构建(全部实验特性)+ 运行
bun run build:dev:full
./Codev
6.2 生产构建
# 生产编译
bun run compile
# 输出:./dist/cli(~192MB 二进制)
# 测试构建
bun run build:dev:compile # 注意:此命令需要额外添加 --compile 参数
6.3 包管理
项目使用 Bun workspaces 管理 monorepo:
{
"workspaces": ["packages/*"],
"packageManager": "bun@1.3.11",
"engines": { "bun": ">=1.3.11" }
}
workspace 包:
packages/audio-capture-napi/:音频捕获原生 N-API 模块packages/doubaoime-asr/:豆包语音识别(symlink 到 .bun 缓存)
TypeScript 配置(tsconfig.json):
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"jsx": "react-jsx",
"types": ["bun"],
"moduleResolution": "bundler",
"noEmit": true,
"strict": false,
"skipLibCheck": true
},
"include": ["src", "scripts", "env.d.ts"]
}
6.4 依赖特性说明
- 运行时 UI:基于 Ink(React for CLI)和 JSX 构建交互式终端界面
- 语音处理:使用
@ericedouard/vad-node-realtime(VAD)、node-edge-tts(TTS) - AI 服务:多供应商支持(Anthropic SDK、AWS Bedrock、Azure、Google Vertex、Groq)
- MCP 协议:
@modelcontextprotocol/sdk和@anthropic-ai/mcpb - 功能标记运行时:
@growthbook/growthbook用于运行时功能开关(与编译时feature()互补) - WebView:通过 Bun 内置的
WebView支持 Web 浏览器工具 - Feishu/Lark:
@larksuiteoapi/node-sdk集成飞书机器人 - Telegram:telegram 命令集成
6.5 构建脚本快速参考
| 命令 | 完整脚本 |
|---|---|
bun run dev |
bun run ./src/entrypoints/cli.tsx |
bun run build |
bun run ./scripts/build.ts |
bun run build:dev |
bun run ./scripts/build.ts --dev |
bun run build:dev:full |
bun run ./scripts/build.ts --dev --feature-set=dev-full |
bun run compile |
bun run ./scripts/build.ts --compile |
自定义构建示例:
# 带自定义 feature 的开发构建
bun run ./scripts/build.ts --dev --feature=KAIROS --feature=BUDDY
# 编译 + 特定 feature
bun run ./scripts/build.ts --compile --feature=TRANSCRIPT_CLASSIFIER