# Quickstart

> First successful run: refresh ./ref from Codex.app, invoke deobfuscate-javascript on ref/webview/assets, and verify formatted output under restored/ with expected log lines and directory layout.

- 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

- `README.md`
- `.agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs`
- `.agents/skills/deobfuscate-javascript/reference/codex-ref.md`
- `.agents/skills/deobfuscate-javascript/scripts/check-entry.ts`
- `restored/app-shell/thread-app-shell-chrome-entry.ts`
- `restored/composer/project-selector/project-selector.tsx`

---

---
title: "Quickstart"
description: "First successful run: refresh ./ref from Codex.app, invoke deobfuscate-javascript on ref/webview/assets, and verify formatted output under restored/ with expected log lines and directory layout."
---

decode-codex runs two agent skills in sequence: `codex-app-ref-refresh` extracts and formats the installed Codex.app bundle into `./ref`, then `deobfuscate-javascript` reads `ref/webview/assets` and promotes readable TypeScript into `./restored/`. Both `./ref` and `./restored/` are generated artifacts — regenerate them with the skills rather than editing by hand.

## Prerequisites

| Requirement | Role |
| ----------- | ---- |
| macOS with Codex.app at `/Applications/Codex.app` | Source `app.asar` for `./ref` |
| Node.js | Runs `refresh-codex-ref.mjs` and `npx @electron/asar` / Prettier |
| Bun | Runs deobfuscation TypeScript scripts |
| Agent harness (optional) | Invokes skills by name; scripts also run directly |

First-time setup for deobfuscation script dependencies:

```bash
cd .agents/skills/deobfuscate-javascript
bun install
```

<Note>
Run all commands from the repository root — the directory that owns `./ref` and `./restored/`. See [Installation](/installation) for full prerequisite detail.
</Note>

## Pipeline overview

```mermaid
sequenceDiagram
  participant App as Codex.app
  participant Refresh as codex-app-ref-refresh
  participant Ref as ./ref
  participant Deob as deobfuscate-javascript
  participant Stage as restored/.deobfuscate-javascript/
  participant Out as ./restored/

  App->>Refresh: app.asar extract
  Refresh->>Ref: sync + Prettier format
  Ref->>Deob: ref/webview/assets chunks
  Deob->>Stage: mechanical checkpoints
  Deob->>Out: organize → promote deliverables
```

Mechanical script and batch output lands in `restored/.deobfuscate-javascript/` first. Only organized, gated files promote into the public `restored/` tree.

<Steps>
<Step title="Refresh ./ref from Codex.app">

<Tabs>
<Tab title="Agent">

From the repo root, ask your agent:

> Use **codex-app-ref-refresh** to refresh `./ref` from the installed Codex app.

</Tab>
<Tab title="CLI">

```bash
node .agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs
```

</Tab>
</Tabs>

The script deletes `./ref`, extracts the asar, then formats every `.js` and `.css` file with Prettier (skipping `ref/node_modules`).

**Refresh completion signals** — treat the run as incomplete unless you see:

| Log line | Meaning |
| -------- | ------- |
| `Formatting N JS/CSS file(s) with Prettier, ignoring git/prettier ignore files...` | Format pass started |
| `Prettier verification complete.` | JS verification passed |
| `Codex app ref refresh complete.` | Refresh finished |

If you see `Prettier verification found N file(s) needing another pass; reformatting...`, that is acceptable when followed by `Prettier verification complete.`

**Spot-check after refresh:**

- `ref/webview/index.html` exists and references hashed chunks under `ref/webview/assets/`
- `ref/package.json` has `"name": "openai-codex-electron"`
- A sample JS file under `ref/` is multi-line (Prettier-formatted), not a single minified line

<Warning>
The refresh script intentionally wipes `./ref`. It refuses to run unless the target resolves to `./ref` under the current working directory.
</Warning>

</Step>

<Step title="Discover the app entry">

Before building the import graph, confirm the entry is the app bootstrap, not a transitive vendor leaf:

```bash
SKILL_DIR=.agents/skills/deobfuscate-javascript
bun "$SKILL_DIR/scripts/check-entry.ts" --discover --root ref/webview/assets
```

**Expected stderr summary:**

```
✓ discovered entry
  index.html        = ref/webview/index.html
  → index-XXXX.js (script, out-degree N)
  ...
```

The command prints the resolved entry path on stdout (for example `ref/webview/assets/app-main-XXXX.js`). Exit codes: `0` = ok, `3` = suspicious vendor/transitive leaf, `1` = I/O or discovery failure.

If exit code is `3`, switch to the `index.html` `<script>` root or a high-fan-out `app-main-*.js` chunk before continuing.

</Step>

<Step title="Run deobfuscate-javascript on ref/webview/assets">

<Tabs>
<Tab title="Agent (recommended)">

After `./ref` exists, ask your agent:

> Use **deobfuscate-javascript** to restore `./ref`.

Equivalent triggers: *"deobfuscate `ref/webview/assets`"*, *"反混淆 `./ref`"*.

For a whole-tree restore (the default when `index.html` plus an asset tree exist), depth defaults to **deep**: typed `.tsx` output, import-graph orchestration, and every reachable project-local chunk promoted. Say **"quick"**, **"readable"**, or **"快速"** to downgrade to untyped readable output.

</Tab>
<Tab title="CLI bootstrap">

Bootstrap the import graph and mechanical checkpoints:

```bash
SKILL_DIR=.agents/skills/deobfuscate-javascript
ENTRY=$(bun "$SKILL_DIR/scripts/check-entry.ts" --discover --root ref/webview/assets)
TARGET=restored
FULL="$TARGET/.deobfuscate-javascript/_full"

bun "$SKILL_DIR/scripts/sourcemap-check.ts" "$ENTRY" || true
bun "$SKILL_DIR/scripts/build-import-graph.ts" "$ENTRY" \
  --target "$TARGET" \
  --root ref/webview/assets \
  --max-lines 0
bun "$SKILL_DIR/scripts/build-symbol-ledger.ts" \
  --target "$TARGET" \
  --manifest "$FULL/manifest.json" \
  --out "$FULL/ledger.json"
bun "$SKILL_DIR/scripts/auto-restore-full.ts" --target "$TARGET" --format
```

`auto-restore-full.ts` writes checkpoints under `restored/.deobfuscate-javascript/_full/checkpoints/` — these are not final deliverables. The agent (or you) must run `plan-organize.ts` and `promote-organized.ts` to drain checkpoints into `restored/`. See [Full tree restoration](/full-tree-restoration) for the complete orchestration loop.

</Tab>
</Tabs>

**Deobfuscation log signals:**

| Source | Log line | Meaning |
| ------ | -------- | ------- |
| `sourcemap-check.ts` | `✓ sourcemap detected` | Stop and recover from the map instead of renaming |
| `sourcemap-check.ts` | `✗ no sourcemap` | Continue with the rename pipeline |
| `check-entry.ts` | `✓ entry looks ok` | Entry passes sanity check |
| `auto-restore-full.ts` | `checkpoints built` | Mechanical checkpoints written |
| `auto-restore-full.ts` | `auto-restore: wrote N file(s) and .../auto-restore-report.json` | Batch checkpoint report saved |
| `quality-gate.ts` | `quality-gate: PASS <path>` | Deliverable passes the gate |

</Step>

<Step title="Verify restored/ output">

Confirm the public deliverable tree, not just staging checkpoints.

**Directory layout** — promoted files live under semantic-domain subfolders with kebab-case names:

:::files
decode-codex/
├─ ref/                              # extracted Codex.app (Skill 1)
│  └─ webview/
│     ├─ index.html
│     └─ assets/*.js
└─ restored/                         # readable output (Skill 2)
   ├─ IMPORT_MAP.json               # shared chunk → public path map
   ├─ app-shell/
   ├─ composer/
   ├─ browser/
   ├─ ui/
   ├─ utils/
   ├─ icons/
   └─ .deobfuscate-javascript/       # staging only (gitignored working area)
      └─ _full/
         ├─ manifest.json
         ├─ ledger.json
         └─ checkpoints/
:::

**File-level checks** — open any promoted file and confirm:

- First line is a provenance header: `// Restored from ref/webview/assets/<chunk>.js`
- Identifiers are semantic (not single-letter or `buttonValue3`-style fallbacks)
- React components use PascalCase exports in kebab-case filenames (`project-selector.tsx` exports `ComposerProjectSelector`)
- Code is Prettier-formatted (wrapped lines, readable JSX)

**Gate verification** on a promoted file or the whole target:

```bash
bun .agents/skills/deobfuscate-javascript/scripts/quality-gate.ts restored/composer/project-selector/project-selector.tsx
# or, after full promotion:
bun .agents/skills/deobfuscate-javascript/scripts/quality-gate.ts restored --check-format
```

**Shared import map** — `restored/IMPORT_MAP.json` maps hashed chunk basenames to public paths and export aliases. One map at the restore root; do not create per-entry maps.

</Step>
</Steps>

## Agent vs CLI responsibilities

| Surface | Refresh `./ref` | Deobfuscate whole tree |
| ------- | --------------- | ---------------------- |
| Agent skill | Fully automated | Orchestrates graph, rename, organize, promote, acceptance |
| Direct CLI | `refresh-codex-ref.mjs` is self-contained | Scripts handle mechanical work; semantic rewrite and promotion need agent judgment |

Skill packs are portable file or repository sources — any agent harness that reads `.agents/skills/` can invoke them without a specific model provider.

## Troubleshooting

<AccordionGroup>
<Accordion title="asar file not found">

Confirm Codex.app is installed at `/Applications/Codex.app`. Override the source path:

```bash
CODEX_APP_ASAR=/path/to/app.asar node .agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs
```

</Accordion>

<Accordion title="Skipping Prettier formatting">

If refresh logs `Skipping Prettier formatting.`, the extraction is raw and unreadable. Re-run without `--skip-format` unless you explicitly want unformatted output.

</Accordion>

<Accordion title="restored/ is empty but checkpoints exist">

Mechanical checkpoints under `restored/.deobfuscate-javascript/_full/checkpoints/` are not deliverables. Run `plan-organize.ts` then `promote-organized.ts` until files appear under semantic subfolders. `quality-gate.ts` fails with `full-restoration-checkpoints-not-drained` while this stall persists.

</Accordion>

<Accordion title="Only a handful of files restored">

You may have pointed at a vendor leaf instead of the app entry. Re-run `check-entry.ts --discover`; exit code `3` means the chosen chunk is a transitive dependency, not the bootstrap. Use the `index.html` script root or `app-main-*.js`.

</Accordion>

<Accordion title="Resuming instead of rebuilding">

If `restored/IMPORT_MAP.json` and `restored/.deobfuscate-javascript/_full/manifest.json` already exist, inspect them before starting fresh. See [Delta restore and resume](/delta-and-resume).

</Accordion>
</AccordionGroup>

<Warning>
Extracted and restored Codex source is for personal study and interoperability research. Do not redistribute. See the legal note in the repository README.
</Warning>

## Next

<CardGroup>
<Card title="Installation" href="/installation">
Prerequisites and first-time `bun install` for deobfuscation scripts.
</Card>
<Card title="Refresh Codex reference source" href="/refresh-codex-ref">
Detailed refresh workflow, flags, and Prettier verification behavior.
</Card>
<Card title="Full tree restoration" href="/full-tree-restoration">
Deep default workflow: import graph, ledger, organize, promote, and quality-gate.
</Card>
<Card title="Workspace and output conventions" href="/workspace-and-output">
Staging rules, promote bar, provenance headers, and `IMPORT_MAP.json` contract.
</Card>
<Card title="Codex project profile" href="/codex-project-profile">
Layout of the extracted `openai-codex-electron` bundle and default command frame.
</Card>
</CardGroup>
