Skip to main content

deobfuscate-javascript

Reverse-engineer minified, obfuscated, packed, or bundled JavaScript into readable or typed TS/TSX, including Codex.app `./ref/webview/assets` restoration. Use for .min.js, dist bundles, Vite/Rollup/Webpack chunks, obfuscated snippets, or requests to humanify, deobfuscate, deminify, unpack, decode, make readable, rename variables, reverse engineer, 完整还原, 深度还原, 反混淆, 美化代码, 看懂这段 JS, 重命名变量, 反编译. Whole-tree restores (index.html + assets, "restore the code/whole tree") default to deep: deobfuscate if needed, smart-rename, polish, resolve npm imports, typed semantic TSX rewrite, acceptance review, import graph/ledger, and full-target quality gate draining every reachable project-local chunk. Quick/readable/快速 or lone snippets use readable naming-quality restore. Vendor data/packages become npm leaves or re-export shims, not restored package bodies.

来源信息

仓库
JimLiu/decode-codex
最近来源活动
2026年7月12日 18:56
检测到的 SKILL.md 语言
英语
星标
132
分支
52

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
100 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
deobfuscate-javascript
description
Reverse-engineer minified, obfuscated, packed, or bundled JavaScript into readable or typed TS/TSX, including Codex.app `./ref/webview/assets` restoration. Use for .min.js, dist bundles, Vite/Rollup/Webpack chunks, obfuscated snippets, or requests to humanify, deobfuscate, deminify, unpack, decode, make readable, rename variables, reverse engineer, 完整还原, 深度还原, 反混淆, 美化代码, 看懂这段 JS, 重命名变量, 反编译. Whole-tree restores (index.html + assets, "restore the code/whole tree") default to deep: deobfuscate if needed, smart-rename, polish, resolve npm imports, typed semantic TSX rewrite, acceptance review, import graph/ledger, and full-target quality gate draining every reachable project-local chunk. Quick/readable/快速 or lone snippets use readable naming-quality restore. Vendor data/packages become npm leaves or re-export shims, not restored package bodies.
# Deobfuscate JavaScript Reverse-engineer minified/obfuscated JavaScript back to readable code. Three stages: **Stage 1** (only if obfuscated) and **Stage 2** (rename + polish) do the readable restore; **Stage 3** adds the typed rewrite + acceptance review and is the deep-tier add-on. - **Stage 1 — Deobfuscation:** unwind obfuscation transforms (Packer/AAEncode unpack, Obfuscator.IO string arrays, hex/unicode/base64 escapes, dead code, opaque predicates). Pure Babel passes, no LLM. Run only on obfuscated input. Detail: [stage-1-deobfuscate.md](stages/stage-1-deobfuscate.md). - **Stage 2 — Restore to readable** (two phases). **(a) Rename** cryptic identifiers (`a`, `e`, `t`, `_0x4f3`, …) to meaningful names — a TS+Bun port of [humanify](https://github.com/jehna/humanify) where _you_ play the renamer, running `smart-rename.ts` **first** so you only hand-name the residue. **(b) Polish** undoes bundler/compiler transforms — the **reading-aid subset** (`--fast`: React Compiler `cache[N]` strip, `(0, fn)(...)` unwrap, backtick → string, JSX-runtime → JSX, destructure defaults, aliased exports) is the default; the **import-resolution tail** (npm/shim/dead-shim elimination) is **deep mode only**. Detail: [stage-2-restore.md](stages/stage-2-restore.md). - **Stage 3 — Finalize (deep mode only)** (two phases). **(a) Semantic rewrite** turns the mechanical checkpoint into idiomatic _typed_ TypeScript — semantic filenames, provenance header, import map, types/`.tsx` recipes, directory splits, import repair. **(b) Acceptance review** — the host reads every delivered file end-to-end against the four-category quality bar and iterates until each passes; no sub-agent and no authorization required (an independent reviewer sub-agent is optional). The default tier ships the Stage 2 readable file without Stage 3. Detail: [stage-3-finalize.md](stages/stage-3-finalize.md). ## Default scope and depth Two independent axes: **scope** (one file vs the whole import tree) and **depth** (readable vs deep). Pick scope from the input shape. **For a whole-tree restore the default depth is deep** ("restore the code" means complete + typed); a lone snippet defaults to readable. Drop a whole tree to readable only on an explicit "quick"/"readable"/"快速" request. - **Default scope — whole tree from `index.html`.** For an app (`index.html` + sibling-chunk asset tree), read `index.html`, **auto-discover the entry** (`check-entry.ts --discover --root <assets-dir>`, or omit the positional to `build-import-graph.ts`), then **recursively restore every reachable project-local chunk**. Per-chunk pipeline: Stage 1 (if obfuscated) → **wakaru pre-pass** (`wakaru-normalize.ts`; recovers ES6 classes, async/await, optional chaining, destructuring, TS enums, …; default-on, **auto-skips** if `@wakaru/cli` absent) → Stage 2 rename (`smart-rename` first, then hand-name residue) → reading-aid polish (`polish.ts --fast`) → format → **organize in staging, then promote** into shared `restored/` (semantic subfolders, kebab filenames, provenance headers, one `restored/IMPORT_MAP.json`); script/batch output never goes straight into `restored/`. **Bundled vendor data (Shiki grammars + themes, data libs like 3Dmol) is detected by content and treated as `npm-leaf` — NOT restored; consumers import the bare specifier (`@shikijs/langs/<id>`, `@shikijs/themes/<id>`), so `restored/` holds app code only.** Readable depth's hard bar is naming quality; deep depth adds complete types + every reachable chunk promoted. - **Fallback scope — single file.** When the input is a lone pasted snippet, or there is no `index.html` / asset tree, restore just that one file — [workflows/small-minified.md](workflows/small-minified.md). Same per-file pipeline, no import graph. - **Depth — deep (default for whole tree) vs readable (quick opt-out).** **Deep** = meaningful names **plus** Stage 3 (typed `.tsx` + acceptance review), full npm-import resolution (Stage 2's deep polish tail), and import-graph/ledger orchestration draining every reachable chunk to `promoted`; also triggered on **"deep"/"full"/"完整"/"深度"/"production"/"typed"/"restore the whole tree"**. **Readable** = meaningful names, reading-aid polish, untyped — only on "quick"/"readable"/"快速"/"粗略" or a lone snippet. Both **organize and promote**; `promote-organized.ts` defaults `--tier deep` (enforces `Props`/param types), `--tier readable` relaxes the typing gate. Deep is a completion bar, not an upsell: a whole-tree restore is "done" only when every reachable project-local chunk reaches `stages.promoted` and `quality-gate.ts <target>` passes ([Restoration contract](#restoration-contract)). Readable is a downgrade the user asks for, not the resting state. ## Output conventions - **`restored/` is a clean-only deliverable zone — the canonical staging → organize → promote rule (referenced everywhere below).** Anything a _batch or script_ restore emits (`auto-restore-full.ts` checkpoints, a swept `polish.ts`, `--write-target-checkpoints` files, any hash-basename `.tsx`) is a **mechanical checkpoint, not a deliverable**; it goes into the gitignored staging tree under `restored/.deobfuscate-javascript/` (`_full/checkpoints/<basename>.tsx` for the batch executor, per-chunk `$WS/` otherwise), **never** straight into `restored/`. Promote only after the host organizes it. The promotion bar, in **every tier**: **good readability** (semantic names, no mechanical fallbacks like `buttonValue3` / `contextParam14`), **friendly kebab filenames**, **clear semantic-domain structure**, and **prettier-formatted** (`promote-organized.ts` runs `format.ts` on every deliverable, so `restored/` is never raw `@babel/generator` output) — **plus complete types** (`Props` interfaces on exported components, param/return types where they help) whenever the restore is **deep/full** (where all `auto-restore-full.ts` output lives). Only genuinely hand-restored single **readable-tier** deliverables may promote untyped, and even those draft in `$WS`, get organized, then land — never raw script output. For a whole-tree batch restore this is driven, not eyeballed: `plan-organize.ts` proposes a domain + kebab path per chunk; `promote-organized.ts` drains the promote frontier (typed deliverable → quality gate → copy into `restored/<domain>/` → IMPORT_MAP update → import rewrite). Complete only when every reachable chunk reaches `stages.promoted` and `quality-gate.ts <target-dir>` passes — see [full-restoration.md → Step 4](workflows/full-restoration.md). - **One shared restore root — `restored/`** — mirrors the source assets dir (e.g. `ref/webview/assets`). Every entry restores into it; **no per-entry folder** (no `restored/app-main/`). - **Semantic-domain subfolders** group output (`app-shell/`, `composer/`, `utils/`, `icons/`, …); original chunk identity lives in each file's provenance header, not the layout. - **One shared import map — `restored/IMPORT_MAP.json`** — reused regardless of entry. Never per-chunk/per-session/per-entry maps (no `APP_MAIN_IMPORT_MAP.json`). - **kebab-case file and directory names** (`button.tsx`, `download-icon.tsx`, `app-shell/`), but **React component + type names stay PascalCase** (JSX requires it) — `button.tsx` exports `Button`, `download-icon.tsx` exports `DownloadIcon`. `quality-gate.ts` enforces this (`non-kebab-filename`). While restoring, if you hit a script bug, a step worth automating, or an unrecognized npm package, update the skill itself and commit it separately — see [Maintaining this skill](#maintaining-this-skill-self-improvement-protocol). ## Vendor/npm hard stop Any task that will create or edit `restored/vendor/*` (including nested `compat-*`, `stable-exports/*`, or runtime barrels) is gated. **Before the first edit, read [reference/vendor-npm.md](reference/vendor-npm.md) in full** and run the directory audit: ```bash bun .agents/skills/deobfuscate-javascript/scripts/vendor-npm-preflight.ts restored/vendor ``` The non-negotiable core: public vendor files are **npm-first** — the default deliverable is a thin npm-backed re-export shim, never a hand-written "compatible subset" of a stock package. A missing dependency means add it to the nearest `package.json`, not evidence for a local body. The intent gate (`vendor-npm-preflight.ts <target> --decision --intent npm-shim|local-body`) must exit 0 before writing code; public vendor files fail closed to `npm-shim` unless recorded Codex-fork or app/runtime-wrapper proof exists. The full evidence order, touch protocol, aggregator-barrel rules, and shim recipe live in [reference/vendor-npm.md](reference/vendor-npm.md). ## Restoration contract ### Default tier (readable restore) 0. **Find the entry (whole tree is the default).** With an `index.html` + asset tree, auto-discover: `bun scripts/check-entry.ts --discover --root <assets-dir>` (or omit the positional to `build-import-graph.ts`). Restore **every reachable project-local chunk** (per-chunk steps run across the tree, orchestrated by [full-restoration.md](workflows/full-restoration.md)). No `index.html`/tree (a lone snippet) → single-file flow, [small-minified.md](workflows/small-minified.md). 1. **Analyze first.** Always run `sourcemap-check`; use `detect` / `extract` per chunk. 2. **Restore to readable.** Stage 1 if obfuscated → **wakaru-normalize** (`bun scripts/wakaru-normalize.ts "$WS/original.js" -o "$WS/normalized.js"`; auto-skips when absent, always leaves a `normalized.js`) → Stage 2 rename (`smart-rename` first, then hand-name residue until single-letter density is low) → reading-aid polish (`polish.ts --rename --fast`) → `format`. One-shot: `polish.ts "$WS/normalized.js" --rename --fast --source <original-path> --out draft.tsx --format` (file operand is the normalized output; `--source` points at the **original** for the provenance header); then hand-name what `smart-rename` left. 3. **Stage, organize, then promote** (canonical rule: [Output conventions](#output-conventions)). The one-shot writes its draft into `$WS/`; promote into `restored/` (semantic subfolders, kebab filenames, `// Restored from <path>` header, shared `restored/IMPORT_MAP.json`) only after organizing — never copy a mechanical checkpoint in. The hard bar at readable depth is naming quality — meaningful identifiers, no generated fallback names (`buttonValue3`, `contextParam14`); types, npm-import resolution, and the reviewer loop stay optional (an optional naming-only self-review is available for extra confidence). ### Deep / production mode only When the user asks for deep/full/typed/production output, continue past the readable draft: 1. **Build the graph (full mode).** Build `manifest.json` + `ledger.json` with `build-import-graph.ts` and `build-symbol-ledger.ts` so renaming is resumable and parallel-safe across the chunk tree. 2. **Create a mechanical checkpoint.** Stage 2 scripts or `auto-restore-full.ts` produce a broad readable checkpoint (may keep hash basenames + fallback names; never the final deliverable). wakaru-normalize may run **per chunk body** here too, with two guards: never `--unpack` an already-split tree (it re-derives module boundaries, forking the restore root), and treat wakaru's import/export specifiers as untrusted — `build-import-graph.ts` must rebuild the manifest from on-disk files **after** wakaru, and `resolve-npm-imports.ts` + `CHUNK_NAME_REGISTRY` stay the authoritative rewriter (wakaru's `un_esm` doesn't substitute). 3. **Rewrite semantically as the host agent.** Read the checkpoint with the original source, graph/ledger, producer/consumer imports, and project conventions; rewrite into maintainable code — meaningful filenames/identifiers, typed props, semantic exports, resolved npm imports, clear structure. 4. **Pre-filter only.** Run prettier and `quality-gate.ts` for cheap failures. Passing does not mean done. 5. **Acceptance-review LOOP.** The host agent reads every delivered file end-to-end against the four-category quality bar in `scripts/acceptance-checklist.md`, rewrites each `NEEDS_FIX`, and re-reads until all pass — **no sub-agent and no authorization required**. An independent reviewer sub-agent is optional (extra eyes only, never a blocker, never fabricate verdicts or skim). Complete only after every file passes. 6. **Full-target completion audit.** For whole-tree restores, run `quality-gate.ts <target-dir>` after the loop. It checks the manifest + shared import map and fails if any reachable local/oversized-local app-feature chunk is still missing, mechanical, `@ts-nocheck`, empty placeholder, typed facade, or lacks Stage 3 acceptance evidence. Not a `boundaries/` grep or `IMPORT_MAP.status === "done"` scan. **Dual-track output (deep mode):** hidden checkpoints preserve original hash basenames; public files use semantic names, with chunk identity in provenance headers and the one shared `restored/IMPORT_MAP.json` (reuse + append; see [Output conventions](#output-conventions)). **Full restoration mode** is not a new stage — it's an orchestration layer on top of Stages 1–3 coordinating the per-file pipeline across a connected component of the import graph (entry chunk + every sibling it pulls in, transitively to the leaves). It adds `manifest.json` (file-level dependency graph + stage status) and `ledger.json` (per-file symbol checklist + cross-file binding table) so renaming is resumable and parallelizable at file granularity. "deep"/"full"/"完整"/"深度"/"restore referenced chunks" ⇒ every reachable project-local sibling is in scope by default. Detail: [workflows/full-restoration.md](workflows/full-restoration.md). ### Delta / boundary replacement inside an existing restore When the target restore root already has a shared `IMPORT_MAP.json` and `.deobfuscate-javascript/_full/manifest.json`, first check whether the requested chunk already maps to a public file or typed boundary facade. If it does, treat the task as a **delta restore** unless the user explicitly asks to rebuild the whole reachable graph. Delta restore contract: 1. Reuse the existing target, manifest, ledger, and import map; no parallel restore root. 2. Restore the requested chunk in its existing `_full/files/<basename>/` workspace. Restore additional chunks only when missing from the import map or explicitly requested. 3. Rewrite imports through the shared `IMPORT_MAP.json`: finalized local deps → semantic public paths; npm deps → bare specifiers; unresolved runtime/vendor deps → documented boundary facade paths. 4. Replace the mapped boundary/public file with the semantic candidate; update the import-map entry (`restored`, `exports`, `status`, drop `boundary` when it's no longer a facade). 5. Validate: format, `quality-gate.ts` on changed public path(s), the target TypeScript check when the root has a `tsconfig.json`, and Stage 3 acceptance on changed public files only. All-tree acceptance only when the whole public tree changed or the user asked. ### Vendor/npm preflight — before restoring `restored/vendor/*` Blocking preflight; the full protocol (evidence order, intent gates, aggregator-barrel resolution, the npm-shim deliverable recipe) is in [reference/vendor-npm.md](reference/vendor-npm.md) — read it before any `restored/vendor/*` edit. See [Vendor/npm hard stop](#vendornpm-hard-stop) above for the audit command. ### Boundaries and terminal nodes Full-restoration mode records `npm-leaf`, `oversized-local`, `external`, and `faced-boundary` chunks as _terminal nodes_ — referenced by consumers but never renamed or given a workspace. `restored/boundaries/*.ts` has exactly three terminal states — **known npm package → bare re-export shim (done)**, **genuine app/host runtime → typed facade or opt-in passthrough (an open boundary, never done)**, **restore + promote out of `boundaries/` (the only completion for runtime facades)** — a permanent `any`-facade is never acceptable, and project/feature chunks are **never** faced ("big" or "imported by many" is not a facing reason). Deep/full mode recurses the **entire** reachable project-local graph to the leaves; final proof is `quality-gate.ts <target-dir>` over the whole public target. The terminal-node trigger table, boundary lifecycle detail, and `build-import-graph.ts` depth flags (`--max-lines`, `--include`) are in [reference/boundaries.md](reference/boundaries.md) — read it when classifying a chunk as a boundary or resolving one. Run Stage 1 _before_ Stage 2 on obfuscated input — `extract.ts` byte offsets are invalidated by Stage 1 rewrites. On purely minified (not obfuscated) input, skip Stage 1. ## Current project profile — `codex-app-code` `./ref` When the workspace contains `ref/package.json` with `name: "openai-codex-electron"` or the user asks to restore `./ref`, load [reference/codex-ref.md](reference/codex-ref.md) before choosing a workflow. Default assumptions for this repo:
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看