On March 31, 2026, Anthropic shipped version 2.1.88 of their npm package @anthropic-ai/claude-code with a 59.8 MB source map file (cli.js.map) included in the tarball. The file's sourcesContent field contained ~2,000 original TypeScript files totaling 512,000+ lines of code — the entire Claude Code codebase, unminified and readable.
The root cause was a classic packaging oversight: Bun (their bundler) generates source maps by default, and no one excluded *.map from the npm package. No .npmignore, no files field, no CI check. This guide covers what happened, what the leaked code revealed, and the four-layer build config that would have prevented it.
* This article references publicly reported information from security researchers, news outlets, and Anthropic's own statements. All sources are linked inline and listed at the end of this article.
What Happened
Claude Code is Anthropic's command-line AI coding assistant — a tool that had reportedly reached a $2.5 billion annualized run rate by early 2026. If you're new to Claude Code, our guides on writing CLAUDE.md files and shipping features in one session cover the tool in depth. It ships as an npm package (@anthropic-ai/claude-code) that developers install globally. On March 31, 2026, a routine release went out as version 2.1.88.
There was one problem: the package contained a file called cli.js.map — a 59.8 MB JavaScript source map. Source maps are debugging artifacts that map bundled code back to its original source. This particular source map contained the sourcesContent array — meaning the complete, unminified TypeScript source code of Claude Code was embedded directly in the file, available to anyone who downloaded the package.
Security researcher Chaofan Shou, an intern at Solayer Labs, discovered the exposure and posted a download link on X (formerly Twitter) at approximately 4:23 AM ET. The post accumulated over 21 million views. Within hours, the code was mirrored across GitHub and analyzed by thousands of developers.
The root cause was a classic build configuration oversight. Anthropic uses Bun (which they acquired in late 2025) as their bundler. Bun generates source maps by default during the build process. Someone on the release team failed to either disable source map generation, add *.map to .npmignore, or configure the files field in package.json to exclude debugging artifacts. Anthropic's official response was direct: “This was a release packaging issue caused by human error, not a security breach.”
Incident Timeline
Mar 31, 2026 — morning
Anthropic publishes @anthropic-ai/claude-code v2.1.88 to npm, bundled with Bun
Mar 31, 2026 — ~04:23 ET
Security researcher Chaofan Shou discovers a 59.8 MB cli.js.map file inside the package
Mar 31, 2026 — hours later
Shou posts download instructions on X (Twitter) — the post accumulates 21M+ views
Mar 31, 2026 — same day
Full TypeScript source is mirrored on GitHub; clean-room Python rewrite hits 50K stars in ~2 hours
Mar 31, 2026 — evening
Anthropic confirms: "release packaging issue caused by human error." v2.1.88 removed from npm
How Source Maps Work (and Why They're Dangerous)
A source map is a JSON file — typically ending in .map — that maps minified or bundled JavaScript back to its original source code. They exist so browser DevTools can display readable code even though the browser executes the compressed version. During development, source maps are essential. In production packages, they're a known security risk.
The critical field is sourcesContent. When present, it contains the complete original source code of every file — every comment, every internal constant, every module. No decompilation or reverse engineering needed. You just parse the JSON and read the code.
In the Claude Code leak, the cli.js.map file contained approximately 1,900 to 2,000 TypeScript source files totaling over 512,000 lines of code. The map file itself was 59.8 MB — an unusually large file for an npm package that should have raised red flags during any packaging review.
The danger is not exploitation — it's exposure
This is not a hack, not a vulnerability, not a zero-day. It is a build configuration mistake. The source map was publicly available on npm for anyone to download with npm pack @anthropic-ai/claude-code. No authentication, no exploit — just a missing line in a config file.
What the Leaked Code Revealed
The source code exposed several unreleased features and internal systems that Anthropic had not publicly disclosed. Security researchers and the open-source community quickly cataloged the key findings. Here are the most significant discoveries:
KAIROS Daemon Mode
An autonomous background agent with an "autoDream" feature — performing memory consolidation and context optimization while the user is idle.
Capybara Model Codename
Internal codename for a Claude 4.6 variant. Comments reveal Anthropic is on Capybara v8 but facing a 29-30% false claims rate (up from v4's 16.7%).
Buddy AI Pet
A Tamagotchi-style AI companion with deterministic gacha mechanics for species rarity, shiny variants, procedurally generated stats, and soul descriptions.
Anti-Distillation
An ANTI_DISTILLATION_CC flag that injects fake tool definitions into API requests — designed to pollute training data if someone records Claude Code's traffic.
Undercover Mode
An undercover.ts file implementing a mode that strips all traces of Anthropic internals when Claude Code is used in non-internal repositories.
Self-Healing Memory
A three-layer persistent memory system with automatic repair and reorganization. Designed to combat "context entropy" — AI confusion as sessions grow longer.
Competitive intelligence at scale
The leak did not expose customer data or credentials. But it exposed Anthropic's entire product roadmap, orchestration logic, and internal model performance metrics to competitors. As Penligent AI noted, the code provides “a literal blueprint for how to build high-agency, reliable, and commercially viable AI agents.”
The Community Response
The developer community's reaction was immediate and massive. The Hacker News thread alone accumulated over 1,500 comments and nearly 10 million views. Within hours, the code was being analyzed, discussed, and rewritten.
Perhaps the most remarkable development was the emergence of a clean-room Python rewrite. The power of open source was on full display as a community created a ground-up Python implementation based on Claude Code's architecture. The repository reached 50,000 GitHub stars in approximately 2 hours — what Layer5 called “likely the fastest-growing repository in GitHub history.” It eventually accumulated over 84,000 stars and 82,000 forks.
Anthropic's official response came the same day:
“Earlier today, a Claude Code release included some internal source code. No sensitive customer data or credentials were involved or exposed. This was a release packaging issue caused by human error, not a security breach.”
— Anthropic, via CNBC
Version 2.1.88 was removed from npm, and Anthropic indicated they are “rolling out measures to prevent this from happening again.” But by then, the code had been downloaded, mirrored, and analyzed by thousands. Once it's on npm, it's on the internet forever.
How to Prevent This in Your Own Packages
The Claude Code leak was preventable with any one of the following measures. The best practice is to layer all four — defense in depth means a single oversight doesn't result in exposure. If you publish npm packages — even internal ones — audit your build pipeline against this checklist. If you're looking for complementary npm security hardening, our guide on the Axios supply chain attack covers .npmrc hardening and lockfile discipline.
1Disable source maps in production builds
This is the most direct fix. If your bundler doesn't generate source maps, there's nothing to leak. Every major bundler has a flag for this — the problem is that some (like Bun) enable source maps by default, so you have to explicitly opt out.
// bun.build.ts — disable source maps for productionawait Bun.build({entrypoints: ['./src/cli.ts'],outdir: './dist',target: 'node',// This is the line Anthropic missed.// Bun generates source maps by DEFAULT.sourcemap: 'none',});// Other bundlers:// Webpack: devtool: false// Vite: build: { sourcemap: false }// esbuild: omit --sourcemap flag// Rollup: output: { sourcemap: false }
2Use the package.json files field (allowlist)
The files field in package.json acts as an allowlist — only files and directories you explicitly list are included in the published package. This is the safer approach because if you forget to add something, you ship less (a missing feature, fixable). If you forget to add something to .npmignore (a denylist), you ship more (source code, credentials — catastrophic).
// package.json — allowlist approach (recommended){"name": "@your-org/your-cli","version": "1.0.0","files": ["dist/cli.js","dist/types/","README.md","LICENSE"]}// Only these files will be included in the npm package.// Everything else — source maps, TypeScript source,// tests, configs — is excluded by default.
3Add .npmignore as a safety net
If your project structure makes the files allowlist impractical, use .npmignore to explicitly exclude dangerous file types. Note that .npmignore takes precedence over .gitignore for npm publishing. Even if you use the files field, having an .npmignore as a second layer of defense is good practice.
# .npmignore — denylist approach (use as backup)# If you can't use the "files" field, exclude explicitly.# Source maps (the cause of the Claude Code leak)*.map*.js.map# TypeScript sourcesrc/*.ts!*.d.ts# Tests and configstests/__tests__/*.test.**.spec.*.env.env.*tsconfig.jsonjest.config.*
4Add a CI/CD pre-publish check
The final safety net: run npm pack --dry-run in your CI pipeline and fail the build if any .map files are detected. This catches mistakes that slip through the other layers — including the exact mistake Anthropic made. Treat npm publish like a deployment, not just a file copy.
# GitHub Actions — pre-publish source map check- name: Verify no source maps in packagerun: |# List everything that would be publishedFILES=$(npm pack --dry-run 2>&1)echo "$FILES"# Fail if any .map files are foundif echo "$FILES" | grep -E '\.map$'; thenecho "::error::Source map files detected in package!"echo "Add *.map to .npmignore or remove from files field."exit 1fi
The core principle: allowlists over denylists
If you forget to add a file to an allowlist, you ship less — a missing feature, easy to fix with a patch release. If you forget to add a file to a denylist, you ship more — source code, credentials, internal documentation. One is a minor inconvenience. The other is the Claude Code incident.
Frequently Asked Questions
Related Resources
The Axios Supply Chain Attack
The .npmrc config, lockfile discipline, and update strategy that would have protected you from the biggest npm supply chain attack of 2026.
How to Write a CLAUDE.md File
Best practices for structuring your Claude Code context file — from single projects to monorepos.
Best Claude Code Skills & Plugins
The essential MCP servers, slash commands, and plugins for Claude Code power users.
TurboDocx for Developers
How developers integrate AI-powered document automation into their applications and workflows.
Build Secure Document Automation
TurboDocx helps engineering teams automate document generation with enterprise-grade security. API-first, SOC 2 compliant, and built by developers who understand the stakes.
