About baoyu-electron-extract
A skill for extracting files from Electron apps and recovering readable source code, aimed at developers inspecting application bundles. It can rebuild files from source maps and format extracted JavaScript and CSS.
Key features
- 01Discover apps and extract asar contents
- 02Restore source files from source maps
- 03Format JS and CSS with Prettier
- 04Copy app.asar.unpacked contents
- 05Provide dry-run and JSON summaries
Use cases
- 01Inspect packaged Electron application contents
- 02Recover source embedded in source maps
- 03Format extracted JavaScript and CSS
- 04Preview resolved paths without writing files
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ guanyang/ open-agent-hub --skill baoyu-electron-extractAfter installing, type/baoyu-electron-extractin Claude Code to confirm it loaded.
Bundled filesscripts/main.test.tsscripts/main.ts
Details
From the project READMEElectron App Extract
User Input Tools
When this skill prompts the user, follow this tool-selection rule (priority order):
- Prefer built-in user-input tools exposed by the current agent runtime — e.g.,
AskUserQuestion,request_user_input,clarify,ask_user, or any equivalent. - Fallback: if no such tool exists, emit a numbered plain-text message and ask the user to reply with the chosen number/answer for each question.
- Batching: if the tool supports multiple questions per call, combine all applicable questions into a single call; if only single-question, ask them one at a time in priority order.
Concrete AskUserQuestion references below are examples — substitute the local equivalent in other runtimes.
Script Directory
{baseDir} = this SKILL.md's directory. Resolve ${BUN_X}: bun if installed; else npx -y bun; else suggest installing bun. Replace {baseDir} and ${BUN_X} with actual values.
| Script | Purpose |
|---|---|
scripts/main.ts | App discovery + asar extraction + source-map restoration + Prettier formatting |
Workflow
1. Determine the input. Accepts an app name (e.g., Codex) or absolute path (/Applications/Codex.app, a .asar file, or a Windows install dir). Ask for it if not given; ask for a custom output directory if they want one.
2. Run the script.
${BUN_X} {baseDir}/scripts/main.ts "<app>" [--output <dir>] [--asar <path>] [--force]
If unsure discovery will find the right bundle, run with --dry-run first (prints resolved paths, writes nothing).
3. Handle the result.
- Success → report output paths and counts (extracted / restored / formatted).
- Multiple matches → script lists candidates and exits non-zero. Ask the user which one (via
AskUserQuestionor the runtime equivalent), then re-run with the chosen absolute path. - Existing non-empty output dir → script refuses without
--force. Ask whether to overwrite (--force) or pick a new--output. - Unsupported platform / no match → suggest
--asar /full/path/to/app.asarif the user knows where the bundle lives.
4. Point the user at the result (default ~/Downloads/<AppName>-electron-extract/):
restored/exists → original source tree reconstructed from.js.mapfiles; read this first.- Only
extracted/(no maps) → JS/CSS inextracted/was Prettier-formatted in place; read from there.
Usage
${BUN_X} {baseDir}/scripts/main.ts Codex # → ~/Downloads/Codex-electron-extract/
${BUN_X} {baseDir}/scripts/main.ts "/Applications/Visual Studio Code.app" # .app bundle, install dir, or .asar
${BUN_X} {baseDir}/scripts/main.ts "C:\Users\you\AppData\Local\Programs\codex"
${BUN_X} {baseDir}/scripts/main.ts --asar /Applications/Codex.app/Contents/Resources/app.asar Codex
${BUN_X} {baseDir}/scripts/main.ts Codex --output ~/work/codex-source
${BUN_X} {baseDir}/scripts/main.ts Codex --json # one JSON line on stdout
Options
| Option | Short | Description | Default |
|---|---|---|---|
<app> | App name or absolute path. Required unless --asar is given. | — | |
--output | -o | Output directory | ~/Downloads/<AppName>-electron-extract |
--asar | Override the resolved .asar path | auto-discovered | |
--force | -f | Allow writing into a non-empty existing output dir | false |
--skip-format | Skip Prettier formatting | false | |
--skip-restore | Skip source-map restoration | false | |
--no-unpacked | Don't copy app.asar.unpacked/ alongside | false | |
--dry-run | Print resolved paths and exit without writing | false | |
--json | Emit one JSON-line summary on stdout (suppresses normal output) | false |
Output layout
~/Downloads/<AppName>-electron-extract/
├── extract-report.json # JSON summary: counts, warnings, resolved paths
├── extracted/ # raw asar contents (JS/CSS Prettier-formatted when no map)
│ └── ... # node_modules left untouched (skipped from format)
├── extracted.unpacked/ # copied from <asar>.unpacked/ if present
│ └── ... # native modules (.node), large assets
└── restored/ # only present if at least one .js.map was usable
└── <original/source/tree> # rebuilt from sourcesContent in each .js.map
Source-Map Path Restoration
Original source names and directory structure are preserved as far as the map allows:
- Each
sources[]entry resolves withsourceRootwhen present, then relative to the.js.mapfile's directory insideextracted/— e.g..vite/main/index.js.map+../../src/main.ts→restored/src/main.ts. ../segments are not treated as automatically unsafe: resolve from the map location first, then sanitize the final path so it stays underrestored/. A path climbing aboveextracted/keeps its readable remainder —.vite/main/index.js.map+../../../shared/src/lib/foo.ts→restored/shared/src/lib/foo.ts.- URL/query decorations are stripped (
webpack://,file://,?loadersuffixes). restored/__unknown/<hash>.<ext>only when the source name is empty or can't be reduced to a safe file path.node_modulesandwebpack/runtime/*entries are skipped (bundler/runtime noise).
Notes
- node_modules is always skipped, for both source-map restoration and Prettier formatting.
- Restoration needs embedded
sourcesContent(common for webpack, esbuild, Vite, rollup). Maps referencing external files without embedding them are skipped and the.jsis Prettier-formatted instead; skipped maps appear inextract-report.jsonunderwarnings. - App discovery: macOS
/Applications+~/Applications; Windows%LOCALAPPDATA%\Programs,%PROGRAMFILES%,%PROGRAMFILES(X86)%,%APPDATA%. Multiple matches → script exits and lists them; re-run with an absolute path. Linux/other: pass--asar /path/to/app.asar. - Safety: refuses to write to
/, the user home directly, or the current working directory, and refuses to populate an existing non-empty output dir without--force. - No global installs:
@electron/asarandprettierresolve on-the-fly vianpx -y; first run is slower while npx caches them.