sourcemap-explode
Decode every .js.map under targets/<name>/raw/ and write the original source tree under targets/<name>/sources/. Run after js-harvest when raw/ contains .js.map files and sources/ is missing. Preserve
SKILL.md.claude/skills/sourcemap-explode/SKILL.md
GitHubsourcemap-explode
Purpose
Restore the original (pre-minified, pre-bundled) source tree from sourcemaps so the static analyzer reads humanly meaningful code instead of minified blobs.
Inputs
targets/<name>/raw/**.js.mapfiles (output ofjs-harvest).
Steps
- For each
*.js.map, parse JSON. Extractsources[]andsourcesContent[]. IfsourcesContentis absent, log and skip — we cannot recover content from URLs alone (and we don't fetch them because they may be off-scope CDNs). - For each
(src_path, src_content)pair:- Normalize
src_path(stripwebpack:///,webpack-internal:///, query strings, leading./). - Write
targets/<name>/sources/<normalized_path>. Create dirs as needed. Skip if the destination already exists with identical content (idempotent).
- Normalize
- For every
.jsinraw/that has no.js.mapsibling AND was not referenced as a chunk of a mapped bundle, copy it totargets/<name>/sources/_nomap/<host>/<path>.js. These get analyzed too — just at lower confidence. - Write
targets/<name>/sources/_manifest.jsondescribing each mapping origin (which.js.mapproduced which source files).
Outputs
targets/<name>/sources/**(original tree)targets/<name>/sources/_nomap/**(chunks without maps)targets/<name>/sources/_manifest.json
Failure modes
- Malformed sourcemap JSON → skip that file; log to
status.json.explode.malformed_maps[]. - Path collision (two maps want to write the same
sources/foo.jswith different content) → keep the longer one; log conflict. sourcesContentmissing → log; the file remains analyzable as a_nomapchunk.
Result block
"phases": { "explode": { "status": "done", "ts": "<iso>",
"original_files": N, "nomap_files": M, "conflicts": K } }