baoyu-electron-extract

baoyu-electron-extract

热门

从任何已安装的 Electron 应用(`.asar` 包)中提取资源和 JavaScript,当存在 `.js.map` 文件时从其中恢复原始源码,否则使用 Prettier 格式化压缩代码。当用户想要“提取 Electron 应用”、“反编译 Electron”、“获取 <app> 的源码”、“检查 app.asar”、“看 Electron 应用源码”、“提取 .asar”,或询问桌面 Electron 应用是如何构建时使用。跳过 `node_modules`,支持 macOS 和 Windows。

2.4万Star
2670Fork
更新于 2026/7/4
SKILL.md
readonly只读
name
baoyu-electron-extract
description

从任何已安装的 Electron 应用(`.asar` 包)中提取资源和 JavaScript,当存在 `.js.map` 文件时从其中恢复原始源码,否则使用 Prettier 格式化压缩代码。当用户想要“提取 Electron 应用”、“反编译 Electron”、“获取 <app> 的源码”、“检查 app.asar”、“看 Electron 应用源码”、“提取 .asar”,或询问桌面 Electron 应用是如何构建时使用。跳过 `node_modules`,支持 macOS 和 Windows。

version
1.119.0

Electron 应用提取

从已安装的 Electron 应用的 app.asar 中提取资源和代码。当存在 .js.map 时,从嵌入的 sourcesContent 中恢复原始源文件;否则使用 Prettier 格式化压缩代码。源映射路径首先相对于 .js.map 文件解析,因此像 ../../src/main.ts 这样的打包路径会恢复为可读路径如 restored/src/main.ts,而不是哈希占位符。始终跳过 node_modules。适用于 macOS 和 Windows。

用户输入工具

当此技能提示用户时,请遵循以下工具选择规则(优先级顺序):

  1. 优先使用当前代理运行时暴露的内置用户输入工具——例如 AskUserQuestionrequest_user_inputclarifyask_user 或任何等效工具。
  2. 回退:如果不存在此类工具,则发出带编号的纯文本消息,并要求用户回复每个问题的编号/答案。
  3. 批量处理:如果工具支持单次调用多个问题,则将所有适用问题合并为一次调用;如果仅支持单个问题,则按优先级顺序逐个询问。

下面的具体 AskUserQuestion 引用仅为示例——在其他运行时中替换为本地等效工具。

脚本目录

脚本位于 scripts/ 子目录中。{baseDir} = 此 SKILL.md 的目录路径。解析 ${BUN_X} 运行时:如果安装了 bunbun;如果 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_moduleswebpack/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.jsonwarnings 下列出。
  • 可读路径优先于哈希——不要将源映射路径中的 ../ 段视为自动不安全。首先从映射位置解析它们,然后清理最终输出路径,使其仍保持在 restored/ 下。哈希回退仅用于不可用的源名称。
  • 应用发现在 macOS 上搜索 /Applications + ~/Applications,在 Windows 上搜索 %LOCALAPPDATA%\Programs%PROGRAMFILES%%PROGRAMFILES(X86)%%APPDATA%。如果发现多个匹配,脚本退出并列出它们——使用绝对路径重新运行。在 Linux 或其他平台上,显式传递 --asar /path/to/app.asar
  • 安全性——脚本拒绝写入 /、用户主目录或当前工作目录,并且拒绝在没有 --force 的情况下填充已存在的非空输出目录。
  • 无需全局安装——@electron/asarprettier 通过 npx -y 即时解析。首次运行会较慢,因为 npx 需要缓存它们。