# Orchestration scripts reference

> Full-restoration CLI reference: check-entry exit codes, build-import-graph flags, ledger subcommands, auto-restore-full, plan-organize, promote-organized, quality-gate checks, and semantic-finalize recipes.

- Repository: JimLiu/decode-codex
- GitHub: https://github.com/JimLiu/decode-codex
- Human docs: https://grok-wiki.com/public/docs/jimliu-decode-codex-1a3a0c425b33
- Complete Markdown: https://grok-wiki.com/public/docs/jimliu-decode-codex-1a3a0c425b33/llms-full.txt

## Source Files

- `.agents/skills/deobfuscate-javascript/workflows/full-restoration.md`
- `.agents/skills/deobfuscate-javascript/scripts/check-entry.ts`
- `.agents/skills/deobfuscate-javascript/scripts/build-import-graph.ts`
- `.agents/skills/deobfuscate-javascript/scripts/ledger.ts`
- `.agents/skills/deobfuscate-javascript/scripts/auto-restore-full.ts`
- `.agents/skills/deobfuscate-javascript/scripts/quality-gate.ts`
- `.agents/skills/deobfuscate-javascript/scripts/semantic-finalize.ts`
- `.agents/skills/deobfuscate-javascript/scripts/acceptance-checklist.md`

---

---
title: "Orchestration scripts reference"
description: "Full-restoration CLI reference: check-entry exit codes, build-import-graph flags, ledger subcommands, auto-restore-full, plan-organize, promote-organized, quality-gate checks, and semantic-finalize recipes."
---

The deobfuscate-javascript skill coordinates whole-tree restoration through Bun scripts under `.agents/skills/deobfuscate-javascript/scripts/`. They maintain `manifest.json` (file-level import graph) and `ledger.json` (symbol-level checklist) under `<target>/.deobfuscate-javascript/_full/`, then drain mechanical checkpoints into semantic deliverables under `restored/`. All scripts share BSD-style exit codes: `0` success, `1` I/O or parse failure, `64` usage error, `75` lock held (`ledger.ts claim`).

```text
check-entry → build-import-graph → build-symbol-ledger
     │              │                      │
     └──────────────┴──────────────────────┘
                         │
              ledger.ts (iterate: claim → rename → mark-done)
                         │
              auto-restore-full (batch checkpoints)
                         │
         plan-organize → promote-organized → quality-gate
                         │
              semantic-finalize (icon/button recipes at promote time)
```

<Info>
Run scripts from the skill directory with `bun <skill-dir>/scripts/<script>.ts`. Set `TARGET=restored` and `FULL="$TARGET/.deobfuscate-javascript/_full"` for the examples below.
</Info>

## Shared paths and artifacts

| Path | Role |
|------|------|
| `<target>/.deobfuscate-javascript/_full/manifest.json` | Import graph, per-chunk `kind`, `stages`, `organization` |
| `<target>/.deobfuscate-javascript/_full/ledger.json` | Symbol statuses, `crossFileBindings` |
| `<target>/.deobfuscate-javascript/_full/files/<basename>/` | Per-chunk workspace (`original.js`, `renames.json`, `candidate.tsx`) |
| `<target>/.deobfuscate-javascript/_full/checkpoints/` | Flat `.tsx` checkpoints from `auto-restore-full.ts` |
| `<target>/.deobfuscate-javascript/_full/organize-plan.json` | Proposed domain + semantic paths from `plan-organize.ts` |
| `<target>/IMPORT_MAP.json` | Public chunk registry updated by `promote-organized.ts` |

## check-entry.ts

Sanity-checks the restoration entry before graph construction. Prevents restoring from a transitive vendor leaf (high in-degree, low out-degree) and declaring a tiny subtree complete.

<CodeGroup>

```bash title="Check a specific entry"
bun scripts/check-entry.ts ref/webview/assets/app-shell-JLpboL12.js \
  --root ref/webview/assets
```

```bash title="Auto-discover from index.html"
ENTRY=$(bun scripts/check-entry.ts --discover --root ref/webview/assets)
```

</CodeGroup>

### Signals

| Signal | Meaning |
|--------|---------|
| `isRoot` | Entry referenced by `index.html` `<script>` or `modulepreload` |
| `localOutDegree` | Count of local sibling imports (high for real app entries) |
| `inDegree` | How many siblings import this chunk (high for vendor leaves) |
| `looksVendored` | Basename or content matches known vendor patterns |
| `suspicious` | Not in `index.html`, `inDegree ≥ 5`, `localOutDegree ≤ 8` |

### Exit codes

| Code | Meaning |
|------|---------|
| `0` | Entry looks reasonable |
| `3` | Suspicious — likely transitive dependency, not app entry |
| `1` | I/O error or discovery found no resolvable entry |
| `64` | Usage error |

<ParamField body="--root" type="string" required>
Assets directory containing sibling chunks. Required for `--discover`.
</ParamField>

<ParamField body="--index" type="string">
Override path to `index.html` when auto-discovery should not use default candidates.
</ParamField>

<ParamField body="--discover" type="boolean">
Read `index.html`, score script/preload roots, print chosen entry path to stdout.
</ParamField>

<ParamField body="--out" type="string">
Write JSON report (`EntryReport` or `DiscoverEntryResult`) to file.
</ParamField>

<Warning>
`build-import-graph.ts` runs the same advisory check but does not block. Run `check-entry.ts` first, or heed its warning, before sinking effort into the wrong subtree. Exit `3` means switch to the `index.html` script root or a high-fan-out `app-main-*` chunk.
</Warning>

## build-import-graph.ts

BFS-walks the entry's ESM import graph, classifies each chunk, copies `local` sources into `_full/files/<basename>/original.js`, and writes `manifest.json`.

<CodeGroup>

```bash title="Deep/full restore (default)"
bun scripts/build-import-graph.ts \
  --target "$TARGET" \
  --root ref/webview/assets \
  --out "$FULL/manifest.json"
```

```bash title="Pin explicit entry"
bun scripts/build-import-graph.ts "$ENTRY" \
  --target "$TARGET" --root ref/webview/assets
```

```bash title="Quick/targeted (skip huge siblings)"
bun scripts/build-import-graph.ts "$ENTRY" \
  --target "$TARGET" --root ref/webview/assets --max-lines 5000
```

</CodeGroup>

### Chunk kinds

| Kind | Behavior |
|------|----------|
| `local` | Restorable project chunk; BFS continues, workspace staged |
| `oversized-local` | Recorded boundary only when `--max-lines N > 0` exceeded; not restored |
| `npm-leaf` | Terminal node from `CHUNK_NAME_REGISTRY` or bundled vendor data; `stages.skipped` |
| `external` | Bare specifier like `"react"`; terminal |

### Flags

<ParamField body="--target" type="string" required>
Restore root; manifest lands under `<target>/.deobfuscate-javascript/_full/`.
</ParamField>

<ParamField body="--root" type="string">
Sibling-chunk directory. When positional entry is omitted, enables auto-discovery from `index.html`.
</ParamField>

<ParamField body="--out" type="string">
Manifest output path (default: `_full/manifest.json`).
</ParamField>

<ParamField body="--max-lines" type="number" default="0">
`0` disables line cap (deep default). Positive value enables quick mode: files exceeding cap become `oversized-local`. Entry is always exempt.
</ParamField>

<ParamField body="--include" type="string">
Comma-separated basenames to force-restore even when exceeding `--max-lines`.
</ParamField>

<ParamField body="--treat-as-npm" type="string">
Comma-separated basenames to classify as `npm-leaf` regardless of registry.
</ParamField>

<ParamField body="--rebuild" type="boolean" default="false">
Discard prior manifest `stages`/`owner` and start fresh.
</ParamField>

<ParamField body="--discover" type="boolean" default="false">
Auto-discover entry from `index.html` (requires `--root`).
</ParamField>

<ParamField body="--no-entry-check" type="boolean" default="false">
Silence the suspicious-entry advisory when a positional entry is provided.
</ParamField>

<ParamField body="--index" type="string">
Override `index.html` path for discovery and entry check.
</ParamField>

### Console summary

After the run, stderr reports `X local · Y oversized-local (skipped) · Z npm-leaf · E edges`. In a deep/full task, `Y` must be `0`; rebuild with `--max-lines 0` if non-zero.

Re-running is idempotent: existing `kind`, `npmPackage`, and `stages` are preserved; only `imports`/`exports` refresh.

## build-symbol-ledger.ts

Initializes `ledger.json` and per-file `symbols.json` for every `kind: local` chunk. Run once after graph build, before the rename loop or `auto-restore-full.ts`.

```bash
bun scripts/build-symbol-ledger.ts \
  --target "$TARGET" \
  --manifest "$FULL/manifest.json" \
  --out "$FULL/ledger.json"
```

<ParamField body="--rebuild" type="boolean" default="false">
Regenerate all symbols. Without `--rebuild`, only `pending` symbols refresh.
</ParamField>

<ParamField body="--only" type="string">
Comma-separated basenames to restrict extraction to.
</ParamField>

## ledger.ts

Coordinates parallel-safe, resumable work across the import tree. Lockfiles live at `_full/locks/<basename>.<stage>.lock` with `O_EXCL` create semantics.

### Stages

| Stage | Manifest field | Typical work |
|-------|----------------|--------------|
| `extract` | `extracted` | Symbol extraction (usually via `build-symbol-ledger.ts`) |
| `rename` | `renamed` | `apply.ts` + `renames.json` |
| `polish` | `polished` | `polish.ts` |
| `finalize` | `finalized` | Hand-cleaned deliverable |
| `organize` | `organized` | Domain + semantic path decided |
| `promote` | `promoted` | Public file written to `restored/` |

### Subcommands

| Subcommand | Purpose |
|------------|---------|
| `status` | One-line summary plus completion overview (`promoted/total`, blocked list) |
| `next [--stage rename] [--skip list]` | Single best `(basename, stage)` suggestion |
| `frontier [--stage rename] [--skip list]` | All restorable files now, deepest first |
| `claim <basename> <stage> --owner <id>` | Acquire lock; exit `75` if held |
| `release <basename> <stage>` | Release lock (required only on cancellation) |
| `mark-done <basename> <stage> [--renames file]` | Flip stage; apply renames to ledger; auto-release lock |
| `mark-faced <basename> [--force]` | Mark vendor boundary as satisfied via facade |
| `set-organization <basename> --domain <d> --semantic-path <p>` | Override one chunk's public path |
| `propagate-cross-file [--from <basename>] [--auto-fill]` | Push producer names to consumer bindings |
| `reset <basename> [--stage rename]` | Roll stage back to pending |

<RequestExample>

```bash
# Fan-out batch: list every file ready to rename
bun scripts/ledger.ts frontier --stage rename --target "$TARGET"

# Claim and work one file
bun scripts/ledger.ts claim AnimatePresence-BMR_rf2Q rename \
  --target "$TARGET" --owner agent-1

# After apply.ts + polish.ts
bun scripts/ledger.ts mark-done AnimatePresence-BMR_rf2Q rename \
  --target "$TARGET" --renames "$FULL/files/AnimatePresence-BMR_rf2Q/renames.json"

bun scripts/ledger.ts propagate-cross-file --target "$TARGET" \
  --from AnimatePresence-BMR_rf2Q
```

</RequestExample>

### Locking rules

- One lock per `(basename, stage)`; `claim` uses `O_EXCL` — second claim exits `75`.
- `mark-done` deletes the lockfile automatically.
- Stale locks older than 30 minutes can be reclaimed with `claim --steal`.
- Different stages of the same file can be in flight, but in practice rename → polish → finalize is sequential per file.

### mark-faced

Marks a vendor/runtime boundary chunk as `stages.faced` so consumers treat it as a satisfied dependency. Refuses app/feature basenames (`app-shell-*`, `app-main-*`, pages, panels) unless `--force`. A facade is an open boundary — the deep restore remains incomplete until reported in README/IMPORT_MAP.

## auto-restore-full.ts

Batch checkpoint executor for large trees. After `build-symbol-ledger.ts`, runs extract → smart-rename → apply → polish for every `kind: local` file and writes flat `.tsx` checkpoints to `_full/checkpoints/`.

```bash
bun scripts/auto-restore-full.ts --target "$TARGET" --format
```

### Flags

<ParamField body="--target" type="string" required>
Restore root.
</ParamField>

<ParamField body="--manifest" type="string">
Override manifest path (default: `_full/manifest.json`).
</ParamField>

<ParamField body="--ledger" type="string">
Override ledger path (default: `_full/ledger.json`).
</ParamField>

<ParamField body="--checkpoint-dir" type="string">
Checkpoint output directory (default: `_full/checkpoints/`).
</ParamField>

<ParamField body="--resume" type="boolean" default="false">
Skip chunks whose `auto-polished.tsx` and checkpoint already exist.
</ParamField>

<ParamField body="--format" type="boolean" default="false">
Run Prettier on the target after checkpoints are written.
</ParamField>

<ParamField body="--write-target-checkpoints" type="boolean" default="false">
Legacy/debug: also write checkpoints directly under `<target>/`. These are not deliverables.
</ParamField>

### Per-chunk outputs

For each local chunk, the script writes under `_full/files/<basename>/`:

- `auto-renames.json` — rename map
- `auto-renamed.js` — applied renames
- `auto-polished.tsx` — polished checkpoint

Plus `_full/checkpoints/<basename>.tsx` and `_full/auto-restore-report.json` with per-file `fallbackRenameRatio` and `needsAgentRewrite: true`.

<Warning>
Checkpoints are accelerators, not deliverables. The host agent must rewrite into semantic public files, pass `quality-gate.ts`, and complete Stage 3 acceptance before declaring done.
</Warning>

## plan-organize.ts

Proposes a semantic domain and public path for every local chunk, writing an editable `_full/organize-plan.json`.

```bash
# Generate plan
bun scripts/plan-organize.ts --target "$TARGET"

# After review, write approved entries into manifest
bun scripts/plan-organize.ts --target "$TARGET" --apply
```

### Plan entry fields

| Field | Values |
|-------|--------|
| `domain` | First path segment (`icons`, `utils`, `boundaries`, `composer`, …) |
| `semanticPath` | Public deliverable relative to target (`icons/download-icon.tsx`) |
| `recipe` | `icon`, `button`, `split`, `manual` |
| `classification` | `app-feature`, `icon`, `single-util`, `vendor-runtime`, `boundary`, … |
| `status` | `approved`, `needs-review` |
| `fallbackRenameRatio` | Surfaces checkpoints with heavy mechanical fallback names |

Heuristics auto-approve shape-known chunks (icons, buttons, single-utils). `app-feature` chunks default to `needs-review` with no domain — the planner cannot know your domain layout. Colliding public paths auto-downgrade to `needs-review`.

### Flags

<ParamField body="--apply" type="boolean" default="false">
Write `status: "approved"` rows into `manifest.organization` and set `stages.organized`.
</ParamField>

<ParamField body="--rebuild" type="boolean" default="false">
With `--apply`, overwrite already-organized chunks.
</ParamField>

<ParamField body="--only" type="string">
Comma-separated basenames to restrict planning.
</ParamField>

<ParamField body="--domain-map" type="string">
JSON file `{ "<basename-prefix>": "<domain>" }` for auto-assigning app chunks.
</ParamField>

<ParamField body="--out" type="string">
Plan output path (default: `_full/organize-plan.json`).
</ParamField>

### Override one chunk

```bash
bun scripts/ledger.ts set-organization composer-footer-DyRbFsKV \
  --domain composer --semantic-path composer/composer-footer.tsx \
  --recipe manual --classification app-feature --target "$TARGET"
```

## promote-organized.ts

Drains the promote frontier: builds typed deliverables, gates them, copies to semantic paths, updates `IMPORT_MAP.json`, rewrites imports, and sets `stages.promoted`. On gate failure, rolls back and continues — one bad chunk never blocks the batch.

```bash
bun scripts/promote-organized.ts --target "$TARGET" --dry-run
bun scripts/promote-organized.ts --target "$TARGET"
```

### Flags

<ParamField body="--dry-run" type="boolean" default="false">
Preview every move and gate verdict; write nothing.
</ParamField>

<ParamField body="--tier" type="string" default="deep">
`deep` enforces TypeScript types on candidates; `readable` allows untyped `manual` chunks with semantic names.
</ParamField>

<ParamField body="--only" type="string">
Comma-separated basenames to restrict promotion.
</ParamField>

<ParamField body="--limit" type="number">
Promote at most N chunks this run.
</ParamField>

<ParamField body="--owner" type="string">
Lock owner identifier (default: `agent-<pid>`).
</ParamField>

### Deliverable sources

| Recipe | Source at promote time |
|--------|------------------------|
| `icon`, `button` | `semantic-finalize.ts` runs automatically on checkpoint |
| `manual`, `split` | Hand-cleaned `_full/files/<basename>/candidate.tsx` required in deep mode |

Blocked chunks appear in `ledger.ts status` output: organized chunks in the promote frontier with no `candidate.tsx`.

## semantic-finalize.ts

Recipe-driven Stage 3 transform for icon and button checkpoints. Called by `promote-organized.ts` for `icon`/`button` recipe chunks; also usable standalone.

<CodeGroup>

```bash title="Finalize a checkpoint"
bun scripts/semantic-finalize.ts checkpoint.tsx \
  --out icons/download-icon.tsx \
  --recipe icon --source ref/webview/assets/download-XXXX.js --format
```

```bash title="Rewrite imports from import map"
bun scripts/semantic-finalize.ts --rewrite-imports restored/ \
  --import-map restored/IMPORT_MAP.json
```

</CodeGroup>

### Recipes

| Recipe | Detection | Output |
|--------|-----------|--------|
| `auto` | SVG exports → `icon`; `Button` pattern → `button`; else error | — |
| `icon` | Exported SVG components | Single file or directory with `types.ts`, per-icon files, `index.ts` barrel |
| `button` | Radius/color/size class tables | Typed `Button` with `Props`, `forwardRef`, `displayName`, `as const` lookup tables |

Icon output uses `IconProps = SVGProps<SVGSVGElement>`, kebab-case filenames, PascalCase component names. Button output extracts variant tables into named `*ClassNames` records with `keyof typeof` unions.

<ParamField body="--recipe" type="string" default="auto">
`auto`, `icon`, or `button`.
</ParamField>

<ParamField body="--source" type="string">
Original chunk path for provenance header and export-alias inference.
</ParamField>

<ParamField body="--basename" type="string">
Chunk basename when provenance header is absent.
</ParamField>

<ParamField body="--format" type="boolean" default="false">
Run Prettier on written files.
</ParamField>

## quality-gate.ts

Executable pre-filter and completion proof. Analyzes source mechanically; when the input is a target directory with `_full/manifest.json`, also runs full-restoration coverage checks.

```bash
# Per-file or mid-drain (intermediate)
bun scripts/quality-gate.ts restored/ --allow-organize-incomplete

# Completion proof (whole target)
bun scripts/quality-gate.ts restored/ --check-format
```

Exit `0` only when every analyzed file and coverage check passes.

### Per-file thresholds (defaults)

| Option | Default | Fails when |
|--------|---------|------------|
| `--max-cryptic-params` | `20` | Too many `*ParamN` / short param names |
| `--max-cryptic-bindings` | `80` | Too many cryptic identifiers |
| `--max-short-ref-count` | `50` | Excessive one-letter references |
| `--max-flat-lines` | `1000` | Flat file exceeds line cap (unless `--allow-flat`) |
| `--max-flat-exports` | `2` | Flat file has too many exports (unless `--allow-flat`) |

### Relaxation flags

<ParamField body="--allow-mechanical-names" type="boolean" default="false">
Permit generated fallback names (`ImportedBinding1`, `callbackValue1`, …).
</ParamField>

<ParamField body="--allow-untyped" type="boolean" default="false">
Skip TypeScript typing requirements on exported components.
</ParamField>

<ParamField body="--allow-missing-provenance" type="boolean" default="false">
Skip provenance header requirement.
</ParamField>

<ParamField body="--vendored" type="boolean" default="false">
Relax naming/typing on intentional boundary facades.
</ParamField>

<ParamField body="--allow-organize-incomplete" type="boolean" default="false">
Suppress drain stall checks during in-progress promotion.
</ParamField>

<ParamField body="--check-format" type="boolean" default="false">
Run Prettier `--check` on all files under the target.
</ParamField>

<ParamField body="--json" type="boolean" default="false">
Emit structured issue reports to stdout.
</ParamField>

### Full-restoration coverage issue codes

When scanning a target directory with an existing manifest, these codes indicate incomplete or invalid whole-tree restores:

| Code | Meaning |
|------|---------|
| `full-restoration-checkpoints-not-drained` | Checkpoints exist but chunks not `promoted`; `restored/` empty |
| `full-restoration-organize-incomplete` | Chunks `finalized` but never promoted |
| `full-restoration-public-file-in-hash-dir` | Deliverable still under hash-named directory |
| `full-restoration-npm-boundary-not-resolved` | Third-party npm chunk left as `any`-facade |
| `full-restoration-app-feature-facade` | App feature chunk promoted as boundary/facade |
| `full-restoration-mechanical-app-feature` | App chunk still mechanical-readable |
| `full-restoration-app-feature-not-accepted` | Missing Stage 3 acceptance / `stages.finalized` |
| `full-restoration-oversized-local` | Reachable chunk marked `oversized-local` |
| `full-restoration-app-feature-ts-nocheck` | `@ts-nocheck` in app deliverable |

Mechanical checks catch bundler residue (`jsx-runtime`, React Compiler cache, `toESM` shims), generated fallback names, and missing JSX intrinsics. Stage 3 acceptance review (categories B1–B4 in `acceptance-checklist.md`) is the semantic layer the script cannot judge.

## Completion contract

A whole-tree restore is done **iff** all three hold:

1. `quality-gate.ts <target-dir> --check-format` exits `0`
2. Every reachable local chunk has `stages.promoted` (deep mode also requires `stages.finalized`)
3. `ledger.ts frontier --stage promote --target <dir>` is empty

While checkpoints sit in `_full/checkpoints/` and `restored/` is empty, the gate fails with `full-restoration-checkpoints-not-drained` — mechanical checkpoint completion is not a reachable done state.

<Steps>

<Step title="Build graph and ledger">
Run `check-entry.ts`, then `build-import-graph.ts` and `build-symbol-ledger.ts`.
</Step>

<Step title="Produce checkpoints">
Run `auto-restore-full.ts --format` or iterate manually via `ledger.ts`.
</Step>

<Step title="Organize and promote">
Run `plan-organize.ts`, review/override, `--apply`, then `promote-organized.ts` until the promote frontier is empty.
</Step>

<Step title="Accept and audit">
Complete Stage 3 acceptance review per `acceptance-checklist.md`, then `quality-gate.ts` over the whole target with `--check-format`.
</Step>

</Steps>

## Related pages

<CardGroup>

<Card title="Full tree restoration" href="/full-tree-restoration">
End-to-end workflow tying these scripts together from entry discovery through completion proof.
</Card>

<Card title="Import graph and boundaries" href="/import-graph-and-boundaries">
Manifest and ledger schemas, terminal chunk kinds, facade lifecycle, and coverage rules.
</Card>

<Card title="Workspace and output" href="/workspace-and-output">
Staging layout, promote bar, semantic domains, and IMPORT_MAP.json contract.
</Card>

<Card title="Quality bar and anti-patterns" href="/quality-bar-and-anti-patterns">
Readable vs deep completion criteria, naming anti-patterns, and gate failure modes.
</Card>

<Card title="Stage 2 scripts reference" href="/stage-2-scripts">
Per-chunk rename and polish scripts invoked inside the ledger loop and auto-restore batch.
</Card>

</CardGroup>
