<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>安全 | Feisky</title><link>https://feisky.xyz/tags/%E5%AE%89%E5%85%A8/</link><description>极客时间专栏作者，专注于 Kubernetes、AI Infra、AI Agent 领域的深度技术分享，让 AI 成为你的第二大脑</description><generator>Hugo 0.165.0</generator><language>zh-CN</language><managingEditor>Pengfei Ni</managingEditor><webMaster>Pengfei Ni</webMaster><lastBuildDate>Fri, 14 Aug 2026 12:39:05 +0000</lastBuildDate><atom:link href="https://feisky.xyz/tags/%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>Claude Code 源码泄漏：51万行代码里藏着什么</title><link>https://feisky.xyz/posts/2026-03-31-claude-code%E6%BA%90%E7%A0%81%E6%B3%84%E6%BC%8F51%E4%B8%87%E8%A1%8C%E4%BB%A3%E7%A0%81%E9%87%8C%E8%97%8F%E7%9D%80%E4%BB%80%E4%B9%88/</link><pubDate>Tue, 31 Mar 2026 20:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI</category><category>Claude Code</category><category>源码分析</category><category>AI Agent</category><category>npm</category><category>安全</category><guid>https://feisky.xyz/posts/2026-03-31-claude-code%E6%BA%90%E7%A0%81%E6%B3%84%E6%BC%8F51%E4%B8%87%E8%A1%8C%E4%BB%A3%E7%A0%81%E9%87%8C%E8%97%8F%E7%9D%80%E4%BB%80%E4%B9%88/</guid><description>&lt;p&gt;今天下午，安全研究员 Chaofan Shou 在 X 上发了一条帖子，几个小时内阅读量冲到了将近 800 万：&lt;/p&gt;
&lt;p&gt;&lt;img
src="https://feisky.xyz/images/2026-03-31-Claude-Code51-2026-03-31-fried-rice-tweet.jpg"
alt="Chaofan Shou 的推文截图"
loading="lazy"
decoding="async"
/&gt;&lt;/p&gt;
&lt;p&gt;Claude Code 的完整源码，通过 npm 包里一个没删干净的 source map 文件，全部暴露了。截图里那个 57MB 的 &lt;code&gt;cli.js.map&lt;/code&gt; 就是罪魁祸首，下面的 &lt;code&gt;ls -alht src&lt;/code&gt; 列出的就是泄漏的完整源码目录。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>今天下午，安全研究员 Chaofan Shou 在 X 上发了一条帖子，几个小时内阅读量冲到了将近 800 万：</p><p><img src="/images/2026-03-31-Claude-Code51-2026-03-31-fried-rice-tweet.jpg" alt="Chaofan Shou 的推文截图" loading="lazy" decoding="async"/></p><p>Claude Code 的完整源码，通过 npm 包里一个没删干净的 source map 文件，全部暴露了。截图里那个 57MB 的<code>cli.js.map</code> 就是罪魁祸首，下面的<code>ls -alht src</code> 列出的就是泄漏的完整源码目录。</p><p>作为一个每天都在用 Claude Code 的人，看到这个消息第一反应是“不可能吧”，第二反应是去 GitHub 找镜像仓库。不到一小时，已经有好几个人把源码传到了 GitHub 上，其中一个 repo 到下午就涨到了 2 万星（fork 更夸张，已经 3 万多了）。</p><p>我简单翻了下这些源码。说实话，收获比预期大得多。Claude Code 远不是一个套壳 CLI，它是一个架构相当复杂的 Agent 系统，而且藏了不少还没发布的功能。</p><h2 id="怎么漏的">怎么漏的</h2><p>先说这个 source map 到底是怎么回事。</p><p>Source map 是前端开发中很常见的东西。你的 TypeScript 代码经过编译、打包、压缩后会变成一坨不可读的 JavaScript，而 source map 文件记录了压缩后的代码和原始源码之间的映射关系，方便调试时定位到原始代码。</p><p>问题在于，这个 .map 文件只应该出现在开发环境里，绝对不应该被发布到 npm 包中。但 Claude Code 的构建流程显然漏了这一步，一个大约 57MB 的 source map 文件被一起发布到了 npm registry。</p><p>更离谱的是，这个 source map 里引用的原始 TypeScript 源码，托管在 Anthropic 的 Cloudflare R2 存储桶上，公开可访问。拿到 source map 就等于拿到了完整的源码下载地址。</p><p>有人在评论里提到，2025 年初就发生过类似的事情，当时修了，现在又漏了。一个帮别人写代码的 AI 工具，自己在构建配置上反复犯同一个错误，这确实有点讽刺。</p><h2 id="这不是一个套壳工具">这不是一个套壳工具</h2><p>拿到源码后第一个感受：规模远超预期。</p><ul><li>约 1900 个 TypeScript 源文件</li><li>超过 51.2 万行代码</li><li>40 多个内置工具</li><li>50 多个 slash 命令</li></ul><p>技术栈也挺有意思：运行时用的是 Bun 而不是 Node.js，终端 UI 用了 React + Ink（没错，终端界面也是 React 组件），CLI 解析用 Commander.js，数据校验全部用 Zod v4。</p><p>目录结构大概长这样：</p><pre tabindex="0"><code>src/
├── main.tsx # CLI 入口
├── QueryEngine.ts # LLM 查询引擎（4.6万行）
├── Tool.ts # 工具类型定义（2.9万行）
├── commands.ts # 命令注册（2.5万行）
├── tools/ # 40+ 工具实现
├── commands/ # 50+ 命令实现
├── components/ # 约 140 个 Ink UI 组件
├── services/ # 外部服务集成
├── coordinator/ # 多 Agent 协调器
├── bridge/ # IDE 双向通信
├── plugins/ # 插件系统
├── skills/ # Skill 系统
├── voice/ # 语音输入
├── remote/ # 远程会话
├── memdir/ # 持久化记忆
├── buddy/ # AI 宠物（没看错）
└── ...</code></pre><p>光看目录就知道这不是一个简单的 API 包装。voice、remote、buddy、coordinator 这些目录名，已经暗示了很多还没发布的功能。</p><h2 id="核心架构拆解">核心架构拆解</h2><p>看完目录，自然想进去翻翻核心模块。</p><h3 id="queryengine46-万行的大脑">QueryEngine：4.6 万行的大脑</h3><p>QueryEngine 是整个系统最核心的模块，处理所有和 LLM API 的交互。流式响应、工具调用循环、思考模式、重试逻辑、token 计数，全在这一个文件里。4.6 万行，是整个代码库中最大的单文件。</p><p>4.6 万行塞在一个文件里，说明 Claude Code 在 API 调用这一层做了大量工程优化，远不是简单的发请求、拿响应。流式处理、错误恢复、token 预算控制、缓存策略，这些东西堆起来就是这个规模。</p><h3 id="工具系统40-个带权限门控的工具">工具系统：40+ 个带权限门控的工具</h3><p>Claude Code 的工具系统设计得很规整。每个工具都是一个独立模块，定义了输入 schema（用 Zod）、权限模型和执行逻辑。</p><pre tabindex="0"><code>BashTool → Shell 命令执行
FileReadTool → 文件读取（支持图片、PDF、Notebook）
FileEditTool → 部分文件修改（字符串替换）
GlobTool → 文件模式匹配
GrepTool → 基于 ripgrep 的内容搜索
AgentTool → 子代理生成
MCPTool → MCP 服务器工具调用
LSPTool → 语言服务器协议集成
ToolSearchTool → 延迟加载的工具发现
CronCreateTool → 定时触发器
SleepTool → 主动模式下的等待</code></pre><p>每个工具调用都经过权限系统检查。权限系统在<code>src/hooks/toolPermission/</code> 里实现，根据用户配置的权限模式（default、plan、bypassPermissions、auto 等），决定是直接放行、弹出确认还是拒绝。</p><p>不过有个细节：权限检查是在客户端做的，不是服务端。安全指令也是客户端硬编码的字符串常量，作为 system prompt 的一部分发送给 API。也就是说，安全边界本质上是一段 JavaScript 里的字符串。</p><h3 id="多-agent-编排">多 Agent 编排</h3><p>Claude Code 的多 Agent 系统比外界想象的要成熟。源码里有三层相关的基础设施：</p><p><code>AgentTool</code> 负责生成子代理，每个子代理运行在自己的上下文里，有独立的工具权限集合。<code>coordinator/</code> 目录处理多 Agent 协调，任务分配和结果汇总。<code>TeamCreateTool</code> 更进一步，支持创建代理团队进行并行工作。</p><p>还有个<code>SendMessageTool</code>，用于代理之间的消息传递。配合 UDS Inbox（Unix Domain Socket），甚至可以实现跨会话的代理间通信。</p><h3 id="七层记忆系统">七层记忆系统</h3><p>Claude Code 的记忆不只是大家熟悉的 CLAUDE.md 和 Auto Memory。翻了下源码才知道，记忆系统其实有七层：</p><pre tabindex="0"><code>Managed → 组织管理员配置的 CLAUDE.md
User → ~/.claude/CLAUDE.md
Project → {项目}/CLAUDE.md
Local → {项目}/CLAUDE.local.md
AutoMem → 自动提取的记忆
TeamMem → 团队共享记忆
Session → ~/.claude/projects/{session}/session-memory/*.md</code></pre><p>最有意思的是 Dream 机制。源码里有一段硬编码的 system prompt：“You are now acting as the memory extraction subagent”。这是一个后台记忆整理子代理，触发条件是距离上次整理超过 24 小时且至少积累了 5 个会话。触发后它会把零散的会话记忆压缩成结构化笔记。整理分四个阶段：Orient（定位）→ Gather（收集）→ Consolidate（整合）→ Prune（修剪）。</p><p>这个设计让我想到人类的睡眠记忆巩固机制，Anthropic 内部也确实把这个过程叫做“Dream”。</p><h3 id="bridgeide-通信层">Bridge：IDE 通信层</h3><p>Bridge 系统是 Claude Code 和 IDE 扩展（VS Code、JetBrains）之间的双向通信层。用 JWT 做认证，支持权限回调、会话管理和 REPL 桥接。</p><p>这意味着你在 VS Code 里用 Claude Code 的体验，底层还是跑的这个 CLI，IDE 扩展只是一个前端界面，通过 Bridge 协议和 CLI 进程通信。</p><h2 id="32-个-feature-flag-背后的秘密">32 个 Feature Flag 背后的秘密</h2><p>架构拆完了，但源码里最让人好奇的还不是这些已经上线的模块，而是 32 个编译时 Feature Flag。这些 flag 通过 Bun 的<code>bun:bundle</code> 在构建时做死代码消除。flag 关闭时，相关代码完全不会出现在最终产物中。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span><span style="color:#a6e22e">voiceCommand</span><span style="color:#f92672">=</span><span style="color:#a6e22e">feature</span>(<span style="color:#e6db74">'VOICE_MODE'</span>)</span></span><span style="display:flex;"><span><span style="color:#f92672">?</span><span style="color:#66d9ef">require</span>(<span style="color:#e6db74">'./commands/voice/index.js'</span>).<span style="color:#66d9ef">default</span></span></span><span style="display:flex;"><span><span style="color:#f92672">:</span><span style="color:#66d9ef">null</span></span></span></code></pre></div><p>这些 flag 配合 GrowthBook 的服务端特性门控（tengu_* 命名空间），Anthropic 可以对不同用户群体逐步灰度发布功能。</p><p>那么这些 flag 都对应着什么功能？我挑几个最有意思的说说。</p><h3 id="kairos一个永远在线的助手">KAIROS：一个永远在线的助手</h3><p>KAIROS 可能是所有未发布功能中野心最大的一个。它的目标是让 Claude 变成一个“持久助手”，跨会话记住所有内容，每天自动写日志，晚上“做梦”整理记忆。</p><p>日志存在<code>~/.claude/.../logs/YYYY/MM/DD.md</code>，采用 append-only 模式。Dream 过程是只读的（不会改动已有记忆），整理时间上限 15 秒，超时自动转后台。</p><p>KAIROS 还有个 proactive 模式。这个模式下 Claude 会通过定期的<code>&lt;tick&gt;</code> 提示自动触发，主动执行操作或者调用 SleepTool 等待。系统提示词里有一句话很直白：“take initiative without waiting for instructions”。</p><p>换句话说，KAIROS 要把 Claude Code 从一个被动应答的工具变成一个主动执行的助手。</p><h3 id="buddy你的-ai-宠物">BUDDY：你的 AI 宠物</h3><p>这个功能我没想到。每个用户会根据账户 ID 生成一个独一无二的虚拟宠物，出现在终端提示符旁边。有 18 个物种（鸭子、龙、章鱼、水豚、蘑菇……），6 个稀有度等级（普通到闪光），5 个属性值（调试力、耐心、混乱值、智慧、毒舌）。</p><p>宠物有待机动画、眨眼、语音气泡，你还可以用<code>/buddy pet</code> 命令撸它。看发布时间线，Teaser 阶段是 2026 年 4 月 1-7 日，正式上线可能在 5 月。</p><p>技术上这当然不复杂，但产品上挺有意思的。给一个命令行工具加情感连接，这个思路和 GitHub 的 Octocat 有异曲同工之处，但更进一步。</p><h3 id="ultraplan云端深度规划">ULTRAPLAN：云端深度规划</h3><p>面对复杂任务时，Claude 可以把规划过程甩到云端的独立实例上，用 Opus 模型跑最多 30 分钟。规划完成后你在浏览器里审批，然后选择在云端执行或者“传送”到本地终端。</p><p>这个设计挺聪明的。规划是最吃 token 和推理能力的环节，放到云端用最强模型跑，执行环节再回到本地用性价比更高的模型。</p><h3 id="daemon后台守护进程">DAEMON：后台守护进程</h3><p>让 Claude 会话在后台运行，就像系统服务一样。可以列出、查看日志、重新连接或终止。配合<code>--bg</code> 参数在 tmux 里运行。</p><p>源码里有完整的<code>daemon</code> /<code>ps</code> /<code>logs</code> /<code>attach</code> /<code>kill</code> 命令集，和 Docker 的容器管理思路很像。</p><p>这些功能串起来看，Claude Code 的产品方向就很清晰了：它不想只做一个编程助手，而是要变成一个本地运行的 AI 操作系统。KAIROS 负责记忆和主动性，DAEMON 负责后台执行，ULTRAPLAN 负责深度规划，Bridge 负责跨设备连接，Coordinator 负责多 Agent 编排。</p><h2 id="工程细节里的魔鬼">工程细节里的魔鬼</h2><p>功能层面聊得差不多了，但翻源码的过程中还发现了一些值得玩味的工程细节。</p><h3 id="启动优化">启动优化</h3><p>Claude Code 的启动做了不少优化。<code>main.tsx</code> 里在模块加载之前就并行预取了 MDM 设置和 Keychain 读取：</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">startMdmRawRead</span>()</span></span><span style="display:flex;"><span><span style="color:#a6e22e">startKeychainPrefetch</span>()</span></span></code></pre></div><p>重型模块比如 OpenTelemetry、gRPC、analytics 全部用动态<code>import()</code> 做懒加载。Feature Flag 关闭的子系统在构建时就被完全剥离，不会影响产物体积。</p><p>整个启动序列有 18 步，包括读取多层配置、加载 MCP 配置、扫描 Skill 和插件、初始化 LSP 管理器、拉取插件安全黑名单等等。这些都在你看到光标之前就跑完了。</p><h3 id="遥测系统">遥测系统</h3><p>源码里的遥测系统规模相当大。100 多种事件类型，覆盖了几乎所有操作：每次 Bash 命令、每次工具调用、每次文件编辑、每次 OAuth 流程、每次上下文压缩。</p><p>几个有意思的发现。</p><p>有一个阿谀检测器。Claude Code 会在客户端对每条模型响应做模式匹配，检测是否过度迎合。触发时会上报<code>tengu_model_response_keyword_detected</code> 事件。Anthropic 正在用客户端检测来实时监控模型的阿谀倾向。</p><p>有一个会话质量分类器。<code>tengu_session_quality_classification</code> 事件表明，你的每个会话都会被一个分类器评估质量，结果发送到 Anthropic 的 Statsig 实例。</p><p>系统提示词指纹也挺有意思。每次 API 调用前，Claude Code 会计算你系统提示词的 SHA-256 哈希和前 20 个字符，上报给 Anthropic。他们不需要读你的完整提示词内容，就能知道你改没改过、是不是用了某种已知模板。</p><h3 id="远程-kill-switch">远程 Kill Switch</h3><p>源码里有一个远程关闭开关。通过 Statsig 的<code>tengu-off-switch</code> 配置，Anthropic 可以远程让特定模型停止响应。</p><p>不过有个细节挺微妙的：通过 Claude.ai OAuth 登录的用户被明确豁免了。也就是说 API Key 用户可以被远程关闭，OAuth 订阅用户不会。同一个工具，两类用户，不同的服务保障。</p><h3 id="一条招聘启事">一条招聘启事</h3><p>在 9.5MB 压缩后的 JavaScript 代码里，前两行是唯一人类可读的注释：</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#75715e">// Want to see the unminified source? We're hiring!</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// https://job-boards.greenhouse.io/anthropic/jobs/4816199008</span></span></span></code></pre></div><p>Anthropic 在代码里藏了一条招聘广告。如果你在逆向工程他们的二进制文件，你可能正是他们想招的人。现在这条广告的意义更微妙了，源码已经不需要逆向就能看到了。</p><h2 id="写在最后">写在最后</h2><p>这次泄漏本身就是个低级错误。<code>npm pack --dry-run</code> 跑一下就能发现 .map 文件没排除，Anthropic 的 CI 里显然缺了这一步。</p><p>不过对开发者社区来说，这可能是近期最有价值的一次“意外开源”。之前只能从产品表面猜，现在源码摆在面前，架构选型、权限设计、多 Agent 编排的具体实现都看得清清楚楚。如果你也在做 AI Coding 工具或者 Agent 系统，这份源码值得翻一翻。</p><p>对普通用户来说没有安全风险，泄漏的是客户端源码，不是模型权重。如果你在意遥测范围，<code>--bare</code> 模式和<code>DISABLE_TELEMETRY</code> 环境变量可以关掉大部分上报。</p><p>Anthropic 大概率下个版本就会把 source map 删掉。不过 GitHub 上已经有好几个镜像了，想看的话趁早。</p><h2 id="相关资源">相关资源</h2><ul><li>原始推文：<a href="https://x.com/Fried_rice/status/2038894956459290963">https://x.com/Fried_rice/status/2038894956459290963</a></li><li>GitHub 镜像仓库：<a href="https://github.com/instructkr/claude-code">https://github.com/instructkr/claude-code</a></li><li>隐藏功能整理网站：<a href="https://ccleaks.com">https://ccleaks.com</a></li><li>逆向工程分析（二进制审计）：<a href="https://vijaychauhanseo.substack.com/p/i-reverse-engineered-claude-code">https://vijaychauhanseo.substack.com/p/i-reverse-engineered-claude-code</a></li><li>Claude Code 官方仓库（不含源码）：<a href="https://github.com/anthropics/claude-code">https://github.com/anthropics/claude-code</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>10 min read</dc:extent></item></channel></rss>