
baoyu-electron-extract
热门从任何已安装的 Electron 应用(`.asar` 包)中提取资源和 JavaScript,当存在 `.js.map` 文件时从其中恢复原始源码,否则使用 Prettier 格式化压缩代码。当用户想要“提取 Electron 应用”、“反编译 Electron”、“获取 <app> 的源码”、“检查 app.asar”、“看 Electron 应用源码”、“提取 .asar”,或询问桌面 Electron 应用是如何构建时使用。跳过 `node_modules`,支持 macOS 和 Windows。
从任何已安装的 Electron 应用(`.asar` 包)中提取资源和 JavaScript,当存在 `.js.map` 文件时从其中恢复原始源码,否则使用 Prettier 格式化压缩代码。当用户想要“提取 Electron 应用”、“反编译 Electron”、“获取 <app> 的源码”、“检查 app.asar”、“看 Electron 应用源码”、“提取 .asar”,或询问桌面 Electron 应用是如何构建时使用。跳过 `node_modules`,支持 macOS 和 Windows。
Electron 应用提取
从已安装的 Electron 应用的 app.asar 中提取资源和代码。当存在 .js.map 时,从嵌入的 sourcesContent 中恢复原始源文件;否则使用 Prettier 格式化压缩代码。源映射路径首先相对于 .js.map 文件解析,因此像 ../../src/main.ts 这样的打包路径会恢复为可读路径如 restored/src/main.ts,而不是哈希占位符。始终跳过 node_modules。适用于 macOS 和 Windows。
用户输入工具
当此技能提示用户时,请遵循以下工具选择规则(优先级顺序):
- 优先使用当前代理运行时暴露的内置用户输入工具——例如
AskUserQuestion、request_user_input、clarify、ask_user或任何等效工具。 - 回退:如果不存在此类工具,则发出带编号的纯文本消息,并要求用户回复每个问题的编号/答案。
- 批量处理:如果工具支持单次调用多个问题,则将所有适用问题合并为一次调用;如果仅支持单个问题,则按优先级顺序逐个询问。
下面的具体 AskUserQuestion 引用仅为示例——在其他运行时中替换为本地等效工具。
脚本目录
脚本位于 scripts/ 子目录中。{baseDir} = 此 SKILL.md 的目录路径。解析 ${BUN_X} 运行时:如果安装了 bun → bun;如果 npx 可用 → npx -y bun;否则建议安装 bun。将 {baseDir} 和 ${BUN_X} 替换为实际值。
| 脚本 | 用途 |
|---|---|
scripts/main.ts |
应用发现 + asar 提取 + 源映射恢复 + Prettier 格式化 |
何时使用
当用户想要查看已安装的 Electron 应用内部或检查其打包代码时使用此技能。触发短语包括:
- "提取 Electron 应用"、"反编译这个 Electron 应用"、"解包 app.asar"
- "显示 <app> 的源码"、"查看 <app> 内部"、"<app> 是如何构建的"
- "获取 Codex / Cursor / Discord / Slack / VS Code / Notion / Obsidian / ChatGPT 桌面的源代码"
- "提取 Electron 应用"、"看 <app> 的源码"、"反编译 Electron"、"解包 app.asar"、"还原 source map"
接受应用名称(例如 Codex)和绝对路径(例如 /Applications/Codex.app、一个 .asar 文件或 Windows 安装目录)。脚本处理两个平台的发现。
工作流程
1. 确定输入。 如果用户未提供应用名称或路径,请询问。如果他们想要自定义输出目录,也请询问。
2. 运行脚本。
${BUN_X} {baseDir}/scripts/main.ts "<app>" [--output <dir>] [--asar <path>] [--force]
如果不确定发现是否能找到正确的包,请先使用 --dry-run——它会打印解析的路径并退出,不触碰文件系统。
3. 处理结果。
- 成功 → 报告输出路径以及计数(提取/恢复/格式化)。
- 多个匹配 → 脚本列出候选并退出并返回非零状态。向用户显示候选,询问使用哪一个(通过
AskUserQuestion或运行时等效工具),然后使用选择的绝对路径重新运行。 - 输出目录已存在且非空 → 脚本拒绝,除非使用
--force。询问用户是否覆盖(--force)或选择新的--output路径。 - 不支持的平台/无匹配 → 如果用户知道包的位置,建议传递
--asar /full/path/to/app.asar。
4. 将结果指向用户。 默认输出目录是 ~/Downloads/<AppName>-electron-extract/。最有趣的子目录取决于找到的内容:
restored/存在 → 原始源码树已从.js.map文件重建;这是首先阅读的内容。- 仅存在
extracted/(无映射)→extracted/中的 JS/CSS 已原地使用 Prettier 格式化;从那里读取。
源映射路径恢复
脚本应尽可能保留原始源名称和目录结构,如源映射所允许:
- 当存在
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/*条目;这些是打包器/运行时噪音,不是应用源码。
用法
# 按应用名称提取(默认输出:~/Downloads/Codex-electron-extract/)
${BUN_X} {baseDir}/scripts/main.ts Codex
# 按绝对路径提取(适用于 .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 Codex --output ~/work/codex-source
# 预览发现而不写入任何内容
${BUN_X} {baseDir}/scripts/main.ts Codex --dry-run
# 覆盖现有输出目录
${BUN_X} {baseDir}/scripts/main.ts Codex --force
# 机器可读结果(stdout 上一行 JSON)
${BUN_X} {baseDir}/scripts/main.ts Codex --json
选项
| 选项 | 简写 | 描述 | 默认 |
|---|---|---|---|
<app> |
应用名称或绝对路径。除非提供了 --asar,否则必需。 |
— | |
--output |
-o |
输出目录 | ~/Downloads/<AppName>-electron-extract |
--asar |
覆盖解析的 .asar 路径 |
自动发现 | |
--force |
-f |
允许写入非空的现有输出目录 | false |
--skip-format |
跳过 Prettier 格式化 | false | |
--skip-restore |
跳过源映射恢复 | false | |
--no-unpacked |
不复制 app.asar.unpacked/ 目录 |
false | |
--dry-run |
打印解析的路径并退出,不写入 | false | |
--json |
在 stdout 上输出一行 JSON 摘要(抑制正常输出) | false |
输出布局
~/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 重建
注意事项
- node_modules 始终被跳过——无论是源映射恢复还是 Prettier 格式化——因为在检查应用时,供应商依赖是噪音。
- 源映射恢复仅在
.js.map嵌入了sourcesContent时才有效。这是现代打包器(webpack、esbuild、Vite、rollup)的常见情况。如果映射引用了外部的.ts/.js文件而未嵌入它们,则跳过该映射,相应的.js将使用 Prettier 格式化。跳过的映射在extract-report.json的warnings下列出。 - 可读路径优先于哈希——不要将源映射路径中的
../段视为自动不安全。首先从映射位置解析它们,然后清理最终输出路径,使其仍保持在restored/下。哈希回退仅用于不可用的源名称。 - 应用发现在 macOS 上搜索
/Applications+~/Applications,在 Windows 上搜索%LOCALAPPDATA%\Programs、%PROGRAMFILES%、%PROGRAMFILES(X86)%、%APPDATA%。如果发现多个匹配,脚本退出并列出它们——使用绝对路径重新运行。在 Linux 或其他平台上,显式传递--asar /path/to/app.asar。 - 安全性——脚本拒绝写入
/、用户主目录或当前工作目录,并且拒绝在没有--force的情况下填充已存在的非空输出目录。 - 无需全局安装——
@electron/asar和prettier通过npx -y即时解析。首次运行会较慢,因为 npx 需要缓存它们。





