Anthropic built an entire system called “Undercover Mode” to stop their AI from accidentally leaking internal codenames in git commits. Then they shipped their entire codebase in a .map file to npm.
March 31, 2026. Security researcher Chaofan Shou finds it: 1,900 TypeScript files, 512,000+ lines. Every internal feature Anthropic hadn’t announced. 59.8 MB of JSON that npm served to anyone.
Not a hack. A packaging mistake.
How to Pull Source Maps from npm (Do This First)
Most writeups explain what broke. Let’s break it ourselves.
Download the package
mkdir source-map-test && cd source-map-test
npm pack @anthropic-ai/[email protected]
That’s the exact tarball npm served. Public registry. No credentials.
Unpack it
tar -xzf anthropic-ai-claude-code-2.1.88.tgz
cd package
ls -lh *.map
59.8 MB. There it is.
Extract source code
Source map = JSON. Open it, find sourcesContent. That’s the original code. Use unwebpack-sourcemap:
pip install unwebpack-sourcemap
unwebpack-sourcemap cli.js.map output/
Directory structure. File paths. Comments. Internal constants. Everything.
Anthropic pulled the package. One dev recovered it from Sublime Text’s undo history. Once published? Permanent.
What Source Maps Actually Are
You bundle JavaScript for production. Minification kicks in – variable names become single letters, whitespace vanishes. Unreadable.
Source maps: JSON files mapping that mess back to your original code. For debugging. Supposed to stay local.
Anthropic published @anthropic-ai/claude-code v2.1.88 with cli.js.map. Inside: a sourcesContent field containing the entire TypeScript codebase. Not references. The actual code.
Anyone could download it with npm pack.
Dead Code Elimination Doesn’t Strip Source Maps
The leak showed what Anthropic is building next. Features stripped from public builds but still sitting in the .map file.
Claude Code uses Bun’s feature flags for dead code elimination – removes inactive features at build time. External users never see it. Except source maps don’t care. The .map file? Still has the original source. Everything that got stripped. That’s how people found:
- BUDDY – Tamagotchi AI pet. 18 species, gacha mechanics, stats like DEBUGGING, PATIENCE, CHAOS, WISDOM, SNARK. April 1-7 teaser rollout planned (as of March 2026).
- KAIROS – Always-on Claude with nightly memory consolidation (“dreaming”).
- ULTRAPLAN – 30-min remote planning sessions in the cloud.
- Coordinator Mode – One Claude spawning multiple worker agents in parallel.
Roadmap items. Not announced.
Think about that for a second. You can strip features from your build, test it locally, see none of the internal stuff in the bundle… and still ship it all in a debug artifact.
3 Mistakes That Caused the Leak
Bun generates source maps by default
Claude Code uses Bun. Bun creates source maps unless you say no. Most bundlers (Webpack, Rollup)? Opt in. Bun? Opt out.
Add this:
// Disable source maps for production
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
sourcemap: 'none' // Not 'external', not 'inline' - none
});
Sounds obvious now. But if you’re coming from Webpack, you’re used to source maps being opt-in. Bun flips that assumption.
Trusting .npmignore
.npmignore is a blacklist. List what to exclude. Forget something? It ships.
Switch to a whitelist. Use files in package.json:
{
"files": [
"dist/**/*.js",
"README.md",
"LICENSE"
]
}
Not in the list? Doesn’t ship.
Skipping npm pack --dry-run
Run this before publish:
npm pack --dry-run
Shows exactly what files go in the tarball. See .map files? Stop.
When You Actually Want Source Maps
Don’t use them if:
- Code contains proprietary business logic
- You hardcode secrets, API endpoints, internal URLs (you shouldn’t, but people do)
- Bundle is a CLI tool on npm (like Claude Code)
- You’re on a public registry and your
.npmignoreisn’t perfect
Use them if:
- Deploying to a private server with restricted access
- Uploading to Sentry/Rollbar that keeps them private
- Debugging locally – maps never leave your machine
- Building open-source where source is already public
Source maps have exposed hardcoded Stripe API keys before (as of 2025). If it’s in the map, assume it’s public.
March 31: Two npm Failures, Same Day
Claude Code leaked. Hours later? axios got compromised. 100M weekly downloads. Stolen maintainer credentials. Two poisoned versions with a remote access trojan.
Two supply chain failures. Opposite directions. axios: malicious code injected. Claude Code: proprietary code leaked.
npm’s pipeline has gaps. axios had no gate between “someone with credentials” and “published package.” Claude Code had no verification to strip debug artifacts before publish.
Average npm project? 79 transitive dependencies (as of 2025-2026). One misconfigured package cascades through millions of apps in hours. In 2025, 454,000 malicious packages hit npm – 99% of all open source malware that year.
Check Your Packages Now
Not tomorrow. Now.
npm pack --dry-runon your latest build- Look for
.mapfiles - If you find any: add to
.npmignoreor switch tofileswhitelist inpackage.json - Bun users: set
sourcemap: 'none'explicitly - Add CI/CD check to fail builds if
.mapfiles detected in tarball
Claude Code is a tool designed to help engineers write better code and avoid mistakes. Configuration oversight brought it down – the kind it’s supposed to prevent.
Security is hard. .npmignore shouldn’t be.
Frequently Asked Questions
Can I still access the leaked Claude Code source?
Yes. Anthropic pulled the versions, but the code was archived to multiple GitHub repos within hours. The most popular had 1,100+ stars and 1,900 forks by end of day (March 31, 2026). Once on npm? Permanent.
Does this leak expose Claude’s AI model weights or training data?
No. This is the client-side CLI – code running on your machine when you install Claude Code. Shows how Anthropic built the tool (permission systems, multi-agent orchestration, IDE integrations). No model weights. No training data. No core AI logic. You’re seeing the interface, not the engine. The ~40 permission-gated tools spanning 29,000 lines of TypeScript? That’s in there. The 46,000-line query engine handling LLM API calls, streaming, caching? Also there. But the actual model that generates responses? Not in this leak.
Is Bun’s default source map generation a security flaw?
Not really. Most bundlers make you opt in (Webpack, Rollup). Bun generates them by default – optimized for dev experience during local work. The issue? Production pipelines need to disable debugging features explicitly. If you’re shipping to npm, configure every build option for production. Don’t rely on defaults. The real flaw is assuming “works locally” means “safe to publish.” This happened because Anthropic had a previous leak 5 days earlier (March 26, 2026) via CMS misconfiguration exposing Claude Mythos details – two leaks in one week suggests a process gap, not a Bun problem.