baoyu-electron-extract
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseElectron App Extract
Electron应用提取
Extracts resources and code from an installed Electron app's . When a is present, restores the original source files from the embedded ; otherwise formats the minified code with Prettier. Source-map paths are resolved relative to the file first, so bundled paths like restore to readable paths such as instead of hashed placeholders. Always skips . Works on macOS and Windows.
app.asar.js.mapsourcesContent.js.map../../src/main.tsrestored/src/main.tsnode_modules可从已安装的Electron应用的文件中提取资源与代码。当存在文件时,会从其嵌入的中还原原始源文件;否则使用Prettier格式化压缩后的代码。首先相对于文件的目录解析源映射路径,因此像这样的打包路径会被还原为这类可读路径,而非哈希占位符。始终会跳过目录,支持macOS和Windows系统。
app.asar.js.mapsourcesContent.js.map../../src/main.tsrestored/src/main.tsnode_modulesUser 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, or any equivalent.ask_user - 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 references below are examples — substitute the local equivalent in other runtimes.
AskUserQuestion当该技能需要提示用户时,请遵循以下工具选择规则(优先级顺序):
- 优先使用当前Agent运行时提供的内置用户输入工具——例如、
AskUserQuestion、request_user_input、clarify或任何等效工具。ask_user - 备选方案:如果没有此类工具,则输出编号的纯文本消息,要求用户回复所选编号/答案来回答每个问题。
- 批量处理:如果工具支持单次调用处理多个问题,则将所有相关问题合并为一次调用;如果仅支持单个问题,则按优先级顺序逐个询问。
以下具体的引用仅为示例——在其他运行时中请替换为本地等效工具。
AskUserQuestionScript Directory
脚本目录
Scripts in subdirectory. = this SKILL.md's directory path. Resolve runtime: if installed → ; if available → ; else suggest installing bun. Replace and with actual values.
scripts/{baseDir}${BUN_X}bunbunnpxnpx -y bun{baseDir}${BUN_X}| Script | Purpose |
|---|---|
| App discovery + asar extraction + source-map restoration + Prettier formatting |
脚本位于子目录中。 = 本SKILL.md文件所在的目录路径。解析运行时:若已安装则使用;若可用则使用;否则建议安装bun。将和替换为实际值。
scripts/{baseDir}${BUN_X}bunbunnpxnpx -y bun{baseDir}${BUN_X}| 脚本 | 用途 |
|---|---|
| 应用发现 + asar提取 + 源映射还原 + Prettier格式化 |
When to use
使用场景
Use this skill whenever the user wants to look inside an installed Electron application or inspect its bundled code. Trigger phrases include:
- "extract Electron app", "decompile this Electron app", "unpack app.asar"
- "show me the source of <app>", "look inside <app>", "how is <app> built"
- "get the source code of Codex / Cursor / Discord / Slack / VS Code / Notion / Obsidian / ChatGPT desktop"
- "提取 Electron 应用", "看 <app> 的源码", "反编译 Electron", "解包 app.asar", "还原 source map"
Both app name (e.g., ) and absolute path (e.g., , a file, or a Windows install dir) are accepted. The script handles discovery for both platforms.
Codex/Applications/Codex.app.asar当用户想要查看已安装Electron应用的内部结构或检查其打包代码时,即可使用本技能。触发语句包括:
- "提取Electron应用"、"反编译该Electron应用"、"解包app.asar"
- "查看<应用>的源码"、"查看<应用>内部结构"、"<应用>是如何构建的"
- "获取Codex/Cursor/Discord/Slack/VS Code/Notion/Obsidian/ChatGPT桌面版的源代码"
- "提取 Electron 应用"、"看 <app> 的源码"、"反编译 Electron"、"解包 app.asar"、"还原 source map"
支持输入应用名称(例如)和绝对路径(例如、文件或Windows安装目录)。脚本会处理两个平台的应用发现逻辑。
Codex/Applications/Codex.app.asarWorkflow
工作流程
1. Determine the input. Ask the user for the app name or path if they haven't given one. If they want a custom output directory, ask for that too.
2. Run the script.
bash
${BUN_X} {baseDir}/scripts/main.ts "<app>" [--output <dir>] [--asar <path>] [--force]Start with first if you're unsure whether discovery will find the right bundle — it prints the resolved paths and exits without touching the filesystem.
--dry-run3. Handle the result.
- Success → report the output paths and the counts (extracted / restored / formatted).
- Multiple matches → the script lists candidates and exits non-zero. Show the user the candidates, ask which one to use (via or the runtime equivalent), then re-run with the chosen absolute path.
AskUserQuestion - Existing non-empty output dir → the script refuses without . Ask the user whether to overwrite (
--force) or pick a new--forcepath.--output - Unsupported platform / no match → suggest passing if the user knows where the bundle lives.
--asar /full/path/to/app.asar
4. Point the user at the result. The default output dir is . The most interesting subdirectory depends on what was found:
~/Downloads/<AppName>-electron-extract/- exists → the original source tree was reconstructed from
restored/files; this is what to read first..js.map - Only exists (no maps) → the JS/CSS in
extracted/was Prettier-formatted in place; read from there.extracted/
1. 确定输入信息。如果用户未提供应用名称或路径,请询问用户。如果用户需要自定义输出目录,也请询问该目录路径。
2. 运行脚本
bash
${BUN_X} {baseDir}/scripts/main.ts "<app>" [--output <dir>] [--asar <path>] [--force]如果不确定应用发现能否找到正确的包,可先使用参数——它会打印解析后的路径,且不会修改文件系统。
--dry-run3. 处理结果
- 成功 → 报告输出路径以及统计数据(提取/还原/格式化的文件数量)。
- 多个匹配结果 → 脚本会列出候选项并以非零状态退出。向用户展示候选项,询问要使用哪一个(通过或运行时等效工具),然后使用所选的绝对路径重新运行脚本。
AskUserQuestion - 输出目录已存在且非空 → 脚本在未使用参数时会拒绝执行。询问用户是否要覆盖(使用
--force)或选择新的--force路径。--output - 不支持的平台/无匹配结果 → 如果用户知道包的位置,建议使用参数指定路径。
--asar /full/path/to/app.asar
4. 引导用户查看结果。默认输出目录为。最值得关注的子目录取决于找到的内容:
~/Downloads/<AppName>-electron-extract/- 若存在目录 → 说明已从
restored/文件中重建了原始源码树;优先查看该目录。.js.map - 仅存在目录(无映射文件) →
extracted/中的JS/CSS已通过Prettier格式化;查看该目录即可。extracted/
Source-map path restoration
源映射路径还原
The script should preserve original source names and directory structure as much as the source map allows:
- Resolve each entry with
sources[]when present, then relative to thesourceRootfile's directory inside.js.map.extracted/ - Collapse normal bundler-relative paths into the restored project tree. For example, +
.vite/main/index.js.mapbecomes../../src/main.ts.restored/src/main.ts - If a source path climbs above , keep the readable remaining path under
extracted/instead of hashing it. For example,restored/+.vite/main/index.js.mapbecomes../../../shared/src/lib/foo.ts.restored/shared/src/lib/foo.ts - Strip URL/query decorations from source names, including common ,
webpack://, andfile://suffixes.?loader - Use only when the source name is empty or cannot be reduced to a safe file path.
restored/__unknown/<hash>.<ext> - Continue skipping and
node_modulesentries; these are bundler/runtime noise, not app sources.webpack/runtime/*
脚本应尽可能保留源映射允许的原始源文件名称和目录结构:
- 当存在时,先结合它解析每个
sourceRoot条目,再相对于sources[]目录中extracted/文件所在的路径进行解析。.js.map - 将打包工具生成的相对路径合并到还原后的项目树中。例如,+
.vite/main/index.js.map会变为../../src/main.ts。restored/src/main.ts - 如果源路径超出目录范围,将可读的剩余路径保留在
extracted/目录下,而非使用哈希值。例如,restored/+.vite/main/index.js.map会变为../../../shared/src/lib/foo.ts。restored/shared/src/lib/foo.ts - 移除源名称中的URL/查询参数装饰,包括常见的、
webpack://和file://后缀。?loader - 仅当源名称为空或无法转换为安全文件路径时,才使用格式。
restored/__unknown/<hash>.<ext> - 继续跳过和
node_modules条目;这些是打包工具/运行时的冗余内容,而非应用源码。webpack/runtime/*
Usage
使用示例
bash
undefinedbash
undefinedExtract by app name (default output: ~/Downloads/Codex-electron-extract/)
通过应用名称提取(默认输出目录:~/Downloads/Codex-electron-extract/)
${BUN_X} {baseDir}/scripts/main.ts Codex
${BUN_X} {baseDir}/scripts/main.ts Codex
Extract by absolute path (works for .app bundles, install dirs, or .asar files)
通过绝对路径提取(适用于.app包、安装目录或.asar文件)
${BUN_X} {baseDir}/scripts/main.ts "/Applications/Visual Studio Code.app"
${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 "/Applications/Visual Studio Code.app"
${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
Custom output
自定义输出目录
${BUN_X} {baseDir}/scripts/main.ts Codex --output ~/work/codex-source
${BUN_X} {baseDir}/scripts/main.ts Codex --output ~/work/codex-source
Preview discovery without writing anything
预览应用发现结果(不写入任何内容)
${BUN_X} {baseDir}/scripts/main.ts Codex --dry-run
${BUN_X} {baseDir}/scripts/main.ts Codex --dry-run
Overwrite an existing output dir
覆盖已存在的输出目录
${BUN_X} {baseDir}/scripts/main.ts Codex --force
${BUN_X} {baseDir}/scripts/main.ts Codex --force
Machine-readable result (one JSON line on stdout)
机器可读结果(标准输出为一行JSON)
${BUN_X} {baseDir}/scripts/main.ts Codex --json
undefined${BUN_X} {baseDir}/scripts/main.ts Codex --json
undefinedOptions
选项说明
| Option | Short | Description | Default |
|---|---|---|---|
| App name or absolute path. Required unless | — | |
| | Output directory | |
| Override the resolved | auto-discovered | |
| | Allow writing into a non-empty existing output dir | false |
| Skip Prettier formatting | false | |
| Skip source-map restoration | false | |
| Don't copy | false | |
| Print resolved paths and exit without writing | false | |
| Emit one JSON-line summary on stdout (suppresses normal output) | false |
| 选项 | 缩写 | 描述 | 默认值 |
|---|---|---|---|
| 应用名称或绝对路径。除非指定 | — | |
| | 输出目录 | |
| 覆盖自动解析的 | 自动发现 | |
| | 允许写入已存在且非空的输出目录 | false |
| 跳过Prettier格式化 | false | |
| 跳过源映射还原 | false | |
| 不复制 | false | |
| 打印解析后的路径并退出,不修改文件系统 | false | |
| 在标准输出中输出一行JSON格式的摘要(抑制常规输出) | 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~/Downloads/<AppName>-electron-extract/
├── extract-report.json # JSON格式的摘要:统计数据、警告信息、解析后的路径
├── extracted/ # 原始asar内容(无映射文件时,JS/CSS已通过Prettier格式化)
│ └── ... # node_modules目录保持原样(跳过格式化)
├── extracted.unpacked/ # 从<asar>.unpacked/复制而来(若存在)
│ └── ... # 原生模块(.node)、大型资源文件
└── restored/ # 仅当至少有一个.js.map文件可用时才存在
└── <original/source/tree> # 从每个.js.map的sourcesContent中重建的目录Notes
注意事项
- node_modules is always skipped — both for source-map restoration and Prettier formatting — because vendored dependencies are noise when inspecting an app.
- Source-map restoration only works when the embeds
.js.map. This is the common case for modern bundlers (webpack, esbuild, Vite, rollup). If a map references externalsourcesContent/.tsfiles without embedding them, that map is skipped and the corresponding.jsis Prettier-formatted instead. Skipped maps are listed in.jsunderextract-report.json.warnings - Readable paths over hashes — don't treat segments in source-map paths as automatically unsafe. First resolve them from the map location and then sanitize the final output path so it still stays under
../. Hash fallback is only for unusable source names.restored/ - App discovery searches +
/Applicationson macOS, and~/Applications,%LOCALAPPDATA%\Programs,%PROGRAMFILES%,%PROGRAMFILES(X86)%on Windows. If discovery finds multiple matches, the script exits and lists them — re-run with an absolute path. On Linux or other platforms, pass%APPDATA%explicitly.--asar /path/to/app.asar - Safety — the script 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 — and
@electron/asarare resolved on-the-fly viaprettier. First run will be slower while npx caches them.npx -y
- node_modules目录始终会被跳过——无论是源映射还原还是Prettier格式化都会忽略该目录,因为第三方依赖在检查应用时属于冗余内容。
- 源映射还原仅在文件嵌入
.js.map时有效。这是现代打包工具(webpack、esbuild、Vite、rollup)的常见情况。如果映射文件引用外部sourcesContent/.ts文件但未嵌入内容,则会跳过该映射文件,并对对应的.js文件进行Prettier格式化。被跳过的映射文件会在.js的extract-report.json字段中列出。warnings - 优先使用可读路径而非哈希值——不要将源映射路径中的片段视为自动不安全。先从映射文件所在位置解析路径,然后清理最终输出路径,确保其仍在
../目录下。仅当源名称无法使用时才回退到哈希值。restored/ - 应用发现在macOS上会搜索和
/Applications目录,在Windows上会搜索~/Applications、%LOCALAPPDATA%\Programs、%PROGRAMFILES%、%PROGRAMFILES(X86)%目录。如果发现多个匹配结果,脚本会退出并列出这些结果——请使用绝对路径重新运行脚本。在Linux或其他平台上,请显式使用%APPDATA%参数指定路径。--asar /path/to/app.asar - 安全性——脚本拒绝写入目录、用户主目录或当前工作目录,且在未使用
/参数时拒绝写入已存在且非空的输出目录。--force - 无需全局安装——和
@electron/asar会通过prettier动态解析。首次运行时会较慢,因为npx会缓存这些依赖。npx -y