Skip to content

Add .auto content mapper and Vite plugin backed by the Claude CLI - #1

Merged
uhyo merged 1 commit into
masterfrom
claude/auto-content-mapper
Nov 1, 2026
Merged

uhyo merged 1 commit into
masterfrom
claude/auto-content-mapper

Conversation

@uhyo

@uhyo uhyo commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Summary

This adds content-mapper-auto. A .auto file contains a plain-language description of a module. Claude writes the implementation, and you import it from TypeScript like any other module.

  • TypeScript 7.1 content mapper (src/mapper/): the mapper process TypeScript launches, speaking JSON-RPC over stdio (initialize / openProject / transform / closeProject). tsc --runExternalCode and the language server see the generated module's real types.
  • Vite plugin (content-mapper-auto/vite): serves and bundles the same generated module, compiled from TypeScript with Oxc (Vite 8) or esbuild (Vite 7).
  • Shared core (src/core/): both sides call the same loadAutoModule().
    • Generation: runs claude --print with structured JSON output and read-only tools (Read/Glob/Grep).
    • Shared settings: the Vite plugin reads its options from the tsconfig contentMappers entry, following extends and references. Both tools therefore compute the same cache keys and paths.
  • Cache: src/foo.auto is cached as .auto-cache/src/foo.auto.ts, keyed by a hash of the description, file path, model and instructions.
    • Writes are atomic, and a lock across processes ensures the editor, tsc and Vite never generate the same file twice.
    • The cache is meant to be committed. With offline / CONTENT_MAPPER_AUTO_OFFLINE=1, CI fails when a description changed but its module wasn't regenerated.
  • Editor behavior: Claude is only called for content that matches the saved file. While you edit, the mapper keeps serving the last module and shows an auto2 "save to regenerate" diagnostic. Generation failures (auto1) and bad options (auto10) appear as diagnostics, and bad options point at their exact location in tsconfig.
  • Demo (examples/demo): a todo app whose store and relative-time formatting are .auto files. The generated modules are committed, so it runs without Claude.

I worked out the protocol details from microsoft/typescript-go's internal/contentmapper, as of #4712.

Testing

  • npm test runs 19 tests against a fake Claude CLI:
    • JSONC/options/tsconfig parsing;
    • cache keys and the lock;
    • the JSON-RPC exchange with the built mapper;
    • tsc 7.1.0-beta and vite build sharing the cache in both directions;
    • tsc and Vite started at the same moment, calling Claude only once;
    • offline mode and failure reporting.
  • Checked by hand with the real Claude CLI:
    • tsc --runExternalCode generated the demo modules in about 20s;
    • vite build and vite dev reused the cache with Claude disabled, and the app worked in a headless browser;
    • an edit during vite dev regenerated the module, and tsc then type-checked against the new export without calling Claude.

Limitations

  • The cache key doesn't include files Claude read while generating. If a referenced type changes, delete the affected cache entries.
  • tsc --build / incremental builds don't notice when cache entries are deleted or edited by hand.
  • An error inside generated code is reported on the .auto file, with line and column numbers from the cache file.

Generated by Claude Code

A TypeScript 7.1 content mapper turns .auto files (plain-language module
descriptions) into TypeScript generated by `claude --print`. A Vite plugin
serves the same modules. Both go through one loadAutoModule() function and
a shared, committable cache (.auto-cache/, keyed by description, path,
model and instructions), with a cross-process lock so tsc, the editor and
Vite never generate the same file twice.

Includes a demo app with committed generated modules, and tests covering
the JSON-RPC protocol and tsc/Vite cache sharing using a fake Claude CLI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KZB12ZvzrAveULf7rh79H6
@uhyo
uhyo merged commit aa4eee2 into master Nov 1, 2026
@uhyo
uhyo deleted the claude/auto-content-mapper branch November 1, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants