Source Map Exposure in an AI Coding CLI: Release Pipeline Risks and Engineering Defenses

    A recent source code exposure involving an AI coding CLI shows how publishing Source Map files can unintentionally disclose an entire codebase. This article explains why `sourcesContent` turns `.map` files into a direct source disclosure channel, reviews the engineering patterns visible in the exposed package, and outlines release-pipeline controls that can prevent similar incidents.

    1. Incident Overview: An Unintentional Self-Disclosure

    A security researcher recently reported on social media that the latest release of a well-known AI coding CLI included complete Source Map files in its public package distribution. As a result, the tool’s source code could be reconstructed directly. The report quickly gained attention, and reconstructed source files were soon organized into a public repository that received thousands of stars and more than ten thousand forks.

    This was not the result of a sophisticated attack. There was no vulnerability exploit and no social engineering involved. The cause was straightforward: the build and release process packaged debugging artifacts that should have remained in the development environment into a production release artifact.

    The package size of the latest version increased from roughly 17 MB to 31 MB. The additional content was a .map file larger than 50 MB. Notably, the preceding release did not contain this file. A similar incident had also occurred when the tool was first released a year earlier. It was fixed at the time, but resurfaced after a later build-configuration change.

    2. Source Maps: From Debugging Tool to Disclosure Channel

    2.1 What a Source Map Is

    Source Maps are widely used for debugging in front-end, Node.js, and Bun ecosystems. After code is bundled, minified, or transpiled—for example, when TypeScript is compiled into JavaScript—the relationship between the deployed code and the original source files is no longer obvious.

    A Source Map records this mapping in JSON form. Its key fields commonly include:

    1. {
    2. "sources": ["src/tools/bash.ts", "src/tools/file-read.ts"],
    3. "sourcesContent": ["export class BashTool { ... }", "..."]
    4. }
    • sources: A list of paths to the original source files.
    • sourcesContent: The complete source text corresponding to each indexed path.

    2.2 Why This Is Effectively Plaintext Source Disclosure

    The critical field is sourcesContent. It does not contain decompiled or inferred code—it can contain the literal original source code. No reverse engineering or deobfuscation is required. Anyone can parse the JSON file and retrieve all TypeScript files.

    A short script can extract the source tree in bulk:

    1. const map = JSON.parse(fs.readFileSync('cli.js.map', 'utf8'));
    2. map.sources.forEach((path, i) => {
    3. fs.mkdirSync(pathlib.dirname(path), { recursive: true });
    4. fs.writeFileSync(path, map.sourcesContent[i]);
    5. });

    As a result, publishing a .map file with embedded source content is effectively equivalent to publishing a working snapshot of the source repository.

    3. What the Exposed Source Code Revealed

    The exposed codebase reportedly included more than 1,900 TypeScript files and approximately 510,000 lines of code, covering the CLI implementation in full. For the technical community, it provided an unusual production-grade reference sample and revealed several noteworthy engineering choices.

    3.1 Technology Stack Observations

    • Bun rather than Node.js as the runtime: This suggests that newer JavaScript runtimes are being adopted in large production tools, primarily for faster startup and built-in bundling capabilities.
    • React + Ink for the terminal UI: This applies declarative UI concepts to command-line interfaces. Interactive terminal components are effectively rendered as React components, representing a relatively modern approach.
    • Commander.js for command parsing, Zod for input validation, bundled ripgrep for faster code search, MCP for extensible tool capabilities, OpenTelemetry for observability, and a feature-flag system for controlled rollouts: Together, these components reflect a mainstream engineering stack for modern CLI development.

    3.2 Architecture: Tool Registration as the Core Model

    The tool’s core is a tool-registration system. Its directory structure implements nearly 40 tools, including command execution, file reading, writing and editing, pattern-based search, sub-agent orchestration, web fetching and search, and external protocol integrations.

    The source also exposes complete implementations of permission controls, input validation, and error handling for each tool. In addition, more than 50 slash commands cover operational capabilities such as diagnostics, diff comparisons, cost reporting, and environment checks.

    This architecture is valuable for teams building agent-style products: modeling capabilities as tool units behind a unified interface, then layering permissions and validation on top, provides a strong balance between extensibility and security control.

    4. Why These Incidents Keep Reoccurring

    This was the second Source Map-related source disclosure involving the same tool, while the immediately preceding version was clean. The pattern is representative of a broader issue: configuration drift in release pipelines.

    1. Build configuration lacks hard controls.
      Whether Source Maps are generated and included in a package may depend on a single build flag. A dependency update or configuration refactor can silently reverse that setting.

    2. Package size is not monitored.
      The release artifact grew from 17 MB to 31 MB. A size-baseline alert could have identified and blocked the anomaly before publication.

    3. The previous fix relied on people rather than process.
      The earlier incident was manually corrected, but the correction was not converted into an automated pre-release control. As a result, recurrence was likely.

    5. A General Prevention Checklist

    Any team publishing code through a public package registry can apply the following safeguards:

    • Automatically scan release artifacts before publishing.
      In CI, unpack the package intended for release and check for sensitive or unintended artifacts such as .map files, .ts source files, .env files, and test data.

    • Set package-size baseline alerts.
      Define acceptable size thresholds for release artifacts and block publication when unexpected growth is detected.

    • Separate environments.
      Generate Source Maps only when they are uploaded to private monitoring or error-tracking systems. Remove them from all publicly distributed artifacts, using build environment variables to distinguish the two paths.

    • Use a two-step approval process.
      Treat changes to release configuration as code-review items rather than incidental adjustments.

    • Audit previously published versions regularly.
      Use scripts to inspect a sample of recently released versions and verify that previous fixes have not regressed.

    6. Conclusion

    The technical mechanism behind this incident is simple. The real lesson is about engineering governance: the boundary between debugging artifacts and release artifacts must be enforced by automated pipelines, not by human memory.

    The exposed content did not include model weights or user data, so it did not create a direct security risk for end users. However, it is a low-cost, high-value warning for engineering teams: inspect your release artifacts today and make sure they do not include unnecessary .map files.