跳转至

Topic | DCE 与 Feature 旗标全景

重要性:⭐⭐⭐⭐⭐(阅读源码必备的"过滤器"知识) 出现位置:几乎所有 src/*.ts / src/*.tsx 顶部、Ant 内部代码、实验性功能 关联phase-01-entry.md 的 Bun featurephase-04-components.md 的 preview modephase-07-advanced.md 的 Ant-only 分支


1. 核心机制

Claude Code 用两种构建时死代码消除(DCE) 手段:

1.1 Bun feature('XXX') —— Bun 内置门控

import { feature } from 'bun:bundle'

if (feature('AGENT_TRIGGERS')) {
  // 整个块在外部构建里被消除
  const cronTools = [CronCreateTool, CronDeleteTool, CronListTool]
}

Bun 怎么实现的: - feature('X') 在 Bun bundle 时被静态替换false - 整个 if 块不进 dead-code-elimination 阶段(因为 if 条件恒为 false) - 结果:外部构建不包含这段代码,bundle size 不膨胀

1.2 process.env.USER_TYPE === 'ant' —— 构建时常量折叠

const REPLTool = process.env.USER_TYPE === 'ant'
  ? require('./tools/REPLTool/REPLTool.js').REPLTool
  : null

Bun 怎么处理: - 构建时把 process.env.USER_TYPE 替换为字面量("ant" 或其他) - 整个三元表达式折叠为单个分支 - 不命中的分支被消除

1.3 二者对比

维度 feature('X') process.env.USER_TYPE === 'ant'
工具支持 Bun 内置 Bun/任何 bundler
粒度 特性名(细粒度) 用户类型(粗粒度)
数量 100+ 1 个值
用途 实验功能、开关 Ant 内部专属

实战含义:看到这两种写法,整个 if 块对外部用户是死代码,可以跳过。

2. 100+ Feature 旗标全清单

按功能分类(grep 出来的所有 feature('XXX') 调用):

2.1 Agent / 多 agent 模式

旗标 用途 关联
AGENT_MEMORY_SNAPSHOT agent 内存快照 swarm 模式
AGENT_TRIGGERS 定时触发 agent ScheduleCronTool/*
AGENT_TRIGGERS_REMOTE 远程触发 agent RemoteTriggerTool
BUDDY buddy 模式(多 agent 协作) src/buddy/
COORDINATOR_MODE coordinator 主控 src/coordinator/
FORK_SUBAGENT fork 子 agent AgentTool
KAIROS KAIROS 大模型 SleepTool
KAIROS_BRIEF KAIROS brief 模式 brief 工具
KAIROS_CHANNELS KAIROS 通道 通知
KAIROS_DREAM KAIROS dream 任务 tasks/DreamTask
KAIROS_GITHUB_WEBHOOKS KAIROS GitHub webhook 集成
KAIROS_PUSH_NOTIFICATION KAIROS 推送 通知
TEAMMEM teammate 队友 swarm 模式
TORCH TORCH 模型(实验) 模型选择
VERIFICATION_AGENT 验证 agent 工具验证
ULTRAPLAN UltraPlan 模式 src/commands/plan/
ULTRATHINK UltraThink 模式 thinking 配置

2.2 上下文与压缩

旗标 用途
CACHED_MICROCOMPACT 缓存的 microCompact
COMPACTION_REMINDERS 压缩前的提醒
CONTEXT_COLLAPSE 上下文坍缩(高级压缩)
KAIROS_BRIEF brief 压缩
PROMPT_CACHE_BREAK_DETECTION prompt cache 失效检测
REACTIVE_COMPACT 反应式压缩(动态判断)
TOKEN_BUDGET token 预算管理

2.3 MCP 与外部集成

旗标 用途
MCP_RICH_OUTPUT MCP 富文本输出
MCP_SKILLS MCP 暴露为 skill
CHICAGO_MCP 芝加哥 MCP 服务(内部)
NATIVE_CLIENT_ATTESTATION 客户端原生认证
NATIVE_CLIPBOARD_IMAGE 剪贴板图像(macOS TCC)
WEB_BROWSER_TOOL 浏览器工具
UDS_INBOX Unix Domain Socket 收件箱

2.4 Bridge / IDE / 远程

旗标 用途
BRIDGE_MODE Bridge 模式
BG_SESSIONS 后台 session
CCR_AUTO_CONNECT CCR 自动连接
CCR_MIRROR CCR 镜像
CCR_REMOTE_SETUP CCR 远程设置
SSH_REMOTE SSH 远程会话
DAEMON daemon 模式
DIRECT_CONNECT 直连(src/server/
LOCAL_BRIDGE 本地 bridge
VOICE_MODE 语音模式

2.5 编辑器 / 体验

旗标 用途
HISTORY_PICKER 历史选择器
HISTORY_SNIP 历史片段
MESSAGE_ACTIONS 消息操作
QUICK_SEARCH 快速搜索
STREAMLINED_OUTPUT 精简输出
TERMINAL_PANEL 终端面板

2.6 Bash / Shell / 安全

旗标 用途
BASH_CLASSIFIER bash 分类器(智能识别)
POWERSHELL_AUTO_MODE PowerShell 自动模式
TREE_SITTER_BASH Tree-sitter bash 解析
TREE_SITTER_BASH_SHADOW Tree-sitter bash 影子模式

2.7 Skills / Plugins / 扩展

旗标 用途
BUILTIN_EXPLORE_PLAN_AGENTS 内置 explore/plan agent
EXPERIMENTAL_SKILL_SEARCH 实验性 skill 搜索
RUN_SKILL_GENERATOR 跑 skill 生成器
SKILL_IMPROVEMENT skill 改进调研
TEMPLATES 模板系统
WORKFLOW_SCRIPTS workflow 脚本

2.8 性能 / 监控 / 调试

旗标 用途
PERFETTO_TRACING Perfetto 性能追踪
SHOT_STATS 截图统计
SLOW_OPERATION_LOGGING 慢操作日志
TRANSCRIPT_CLASSIFIER 转录分类器
PROMPT_CACHE_BREAK_DETECTION prompt cache 失效检测

2.9 内存 / 持久化

旗标 用途
EXTRACT_MEMORIES 提取记忆
FILE_PERSISTENCE 文件持久化
LODESTONE LODESTONE 内存系统(实验)
MEMORY_SHAPE_TELEMETRY 内存形状遥测
COMMIT_ATTRIBUTION commit 归因

2.10 内部 / 限流 / 实验

旗标 用途
ABLATION_BASELINE ablation 实验基线
ANTI_DISTILLATION_CC 反蒸馏(防止被蒸馏训练)
AUTO_THEME 自动主题(跟随系统)
AWAY_SUMMARY 离开摘要
BREAK_CACHE_COMMAND break-cache 命令
BUILDING_CLAUDE_APPS 构建 Claude 应用(教学)
BYOC_ENVIRONMENT_RUNNER BYOC 环境运行器
COMMIT_ATTRIBUTION commit 归因
CONNECTOR_TEXT connector 文本
COWORKER_TYPE_TELEMETRY 协作者类型遥测
DISABLE_INTERLEAVED_THINKING 禁用交错思考(双重 DCE)
DOWNLOAD_USER_SETTINGS 下载用户设置
DUMP_SYSTEM_PROMPT 导出 system prompt(debug)
ENHANCED_TELEMETRY_BETA 增强遥测 beta
HARD_FAIL 硬失败(实验)
HOOK_PROMPTS hook 提示
IS_DEMO demo 模式(双 DCE)
IS_LIBC_GLIBC / IS_LIBC_MUSL libc 类型(glibc vs musl)
MONITOR_TOOL monitor 工具
NEW_INIT 新初始化流程
OVERFLOW_TEST_TOOL 溢出测试工具
REVIEW_ARTIFACT 评审产物
SELF_HOSTED_RUNNER 自托管 runner
UPLOAD_USER_SETTINGS 上传用户设置

总计:约 95 个 feature 旗标(grep 出去重后)。

3. 实战:阅读源码时怎么"跳过"这些分支

3.1 跳过整个 if 块

if (feature('CONTEXT_COLLAPSE')) {
  // 200 行 reactiveCompact 逻辑
  const reactiveCompact = (require(...) as ...)
  // ...
}

对外部读者:直接跳过整个 if 块,这些代码不存在

3.2 跳过懒加载的 null 分支

const REPLTool = process.env.USER_TYPE === 'ant'
  ? require('./tools/REPLTool/REPLTool.js').REPLTool
  : null

// 后面用:
if (REPLTool) {
  // 用 REPLTool
}

对外部读者REPLTool 永远是 null整个 if 块是死代码

3.3 跳过环境变量判断

if (process.env.USER_TYPE === 'ant') {
  return <AntModelSwitchCallout />
} else {
  return null
}

对外部读者:永远走 else 分支。

3.4 ESLint 注释的双重含义

// eslint-disable-next-line custom-rules/no-top-level-side-effects
process.env[k] ??= '1'

含义: - 启用了项目自定义规则 no-top-level-side-effects - 这条规则禁止顶层 import 副作用 - 但DCE 优化是合法例外(因为整块最终被消除)

4. Feature 旗标的"设计模式"

4.1 三种应用模式

模式 例子 效果
包裹整个 if 块 if (feature('X')) { ... } 整块 DCE 掉
三元运算符 feature('X') ? require(...) : null 单值 DCE
条件数组 feature('X') ? [a, b, c] : [] 数组项 DCE

4.2 与 process.env 配合

// cli.tsx 顶部
if (feature('ABLATION_BASELINE') && process.env.CLAUDE_CODE_ABLATION_BASELINE) {
  // 双层门:feature 门 + env 门
  // 仅在 Ant 内部构建 且 用户设了 env 时启用
}

意义build-time 决定可能性,runtime 决定激活
feature 是编译时决策(是否能用),env 是运行时决策(是否启用)。

4.3 Ant-only 的 4 个分支形式

// 形式 1:直接 if
if (process.env.USER_TYPE === 'ant') { ... }

// 形式 2:三元
const x = process.env.USER_TYPE === 'ant' ? A : null

// 形式 3:条件 spread
{...(process.env.USER_TYPE === 'ant' ? { prop: A } : {})}

// 形式 4:条件数组
const arr = [...common, ...(process.env.USER_TYPE === 'ant' ? [AntThing] : [])]

实战:4 种形式都会让 Bun 做常量折叠。看到任何一种都意味着 Ant 专属

5. 如何判断当前看的是不是"死代码"

5.1 三步判断法

  1. feature('X') 包裹? → 是死代码
  2. process.env.USER_TYPE === 'ant' → 是死代码
  3. process.env.CLAUDE_CODE_*(带下划线前缀)?不是死代码,是用户可配置开关

5.2 危险:用户可配置的 env vars 不是 DCE

// ❌ 不是 DCE(用户可配)
if (process.env.CLAUDE_CODE_DISABLE_TELEMETRY) {
  telemetry.disable()
}

// ✅ 是 DCE(编译时消除)
if (feature('DUMP_SYSTEM_PROMPT')) {
  // ...
}

关键:用户设了 env var 才会执行,不设就跳过。但代码本身在 bundle 里。

5.3 Bun 怎么识别

Bun 在 build 时分析: - feature('X')静态 false(外部构建) - process.env.USER_TYPE === 'ant' → 假设 USER_TYPE 是个编译时常量(Ant 构建时是 "ant",外部构建是其他值) - process.env.CLAUDE_CODE_X编译时不可知,保留整个 if

6. 对学习的实际影响

6.1 估算"有效代码量"

  • 1902 个文件 / 512,664 行
  • 估算 30~40% 的代码在 DCE 分支里(基于 100+ 旗标 + Ant-only 的密度)
  • 实际"运行时有效" 大约 30~35 万行

6.2 阅读优先级

  • 高优先:业务核心(state、query、REPL、tools)
  • 🟡 中优先:服务端 / API client
  • 🔴 低优先:DCE 死代码(但要识别它是 DCE,跳过不看)

6.3 不要被文件大小迷惑

文件 行数 DCE 内容占比
src/main.tsx 4683 行 中(~20% 启动 prefetch 块)
src/screens/REPL.tsx 5005 行 中(Ant-only 组件 ~10%)
src/services/api/claude.ts 3419 行
src/utils/hooks.ts 5022 行 (hooks 触发条件多是 feature-gated)
src/utils/messages.ts 5512 行

7. 关键洞察

7.1 DCE 是"代码组织"工具

DCE 不仅仅是"节省 bundle size" —— 它让多个产品线共用一个代码库。Ant 内部版、外部公开版、demo 版都能用同一份代码,通过 feature 旗标区分。

7.2 阅读源码必须会"跳过"

不识别 DCE 会被 100+ 旗标绕晕。判断分支死活是第一课

7.3 命名约定

  • feature('AGENT_XXX') —— 大写、snake_case、模块名
  • 命名 = 团队/模块归属(AGENT、MCP、KAIROS、BRIDGE...)

7.4 与 React 的 Server Components 对比

Next.js 的 'use client' 指令也是 DCE(客户端不要的代码不进 bundle)。Claude Code 的 feature() 是同一思想在不同时代的实现

8. 阅读清单

  1. src/entrypoints/cli.tsx:1-30 —— 头部多种 DCE 形式
  2. src/tools.ts:30-50 —— require + feature 模式
  3. src/query.ts:1-50 —— 头部 feature + reactiveCompact
  4. 📌 src/services/compact/ —— 多个压缩策略的 DCE 门控
  5. 📌 src/bridge/bridgeMain.ts:2999 行 —— 大量 feature 门控

9. 练习任务

  1. 数一遍 grep -rhE "feature\('[A-Z_][A-Z_0-9]*'\)" src/ vendor/ | sort -u | wc -l 验证旗标总数
  2. 挑 3 个 DCE 分支 找到它们对应的功能实现,对比"如果启用会多大、不启用多大"
  3. 写一个 demo:手写一个 .ts 文件用 feature('MY_FEATURE'),用 bun build 验证 DCE 生效
  4. 思考:DCE 在 Web 项目里通常怎么实现?Webpack 的 DefinePlugin、Next.js 的 process.env.NODE_ENV、Vite 的 import.meta.env 各有什么优劣?Bun feature() 的优势是什么?