# Refresh Codex reference source

> Run codex-app-ref-refresh to delete and recreate ./ref from Codex.app Contents/Resources/app.asar, format extracted JS/CSS with Prettier, and verify completion signals before deobfuscation.

- 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/codex-app-ref-refresh/SKILL.md`
- `.agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs`
- `.agents/skills/codex-app-ref-refresh/agents/openai.yaml`
- `README.md`

---

---
title: "Refresh Codex reference source"
description: "Run codex-app-ref-refresh to delete and recreate ./ref from Codex.app Contents/Resources/app.asar, format extracted JS/CSS with Prettier, and verify completion signals before deobfuscation."
---

The `codex-app-ref-refresh` skill runs `refresh-codex-ref.mjs` from the repository root: it deletes `./ref`, extracts `/Applications/Codex.app/Contents/Resources/app.asar` with `@electron/asar`, formats every extracted `.js` and `.css` file with Prettier (skipping `ref/node_modules`), and verifies JavaScript formatting before reporting success. A complete refresh is the mandatory first step before invoking `deobfuscate-javascript` on `ref/webview/assets`.

<Info>
`ref/` and `restored/` are gitignored generated artifacts. Regenerate `ref/` with this skill rather than editing it by hand.
</Info>

## Role in the pipeline

decode-codex exposes two skills that chain together:

| Skill | Input | Output |
| ----- | ----- | ------ |
| `codex-app-ref-refresh` | Installed `Codex.app` (`app.asar`) | `./ref/` |
| `deobfuscate-javascript` | `./ref/webview/assets` | `./restored/` |

The refresh step keeps the reference tree aligned with the Codex desktop app version you have installed. Prettier formatting is not optional decoration — asar extraction yields single-line minified bundles that are impractical for analysis or deobfuscation until formatted.

```mermaid
sequenceDiagram
    participant Agent as Agent or shell
    participant Script as refresh-codex-ref.mjs
    participant Asar as @electron/asar
    participant Prettier as Prettier (npx)
    participant Ref as ./ref

    Agent->>Script: node .../refresh-codex-ref.mjs
    Script->>Script: assertSafeRefDir(./ref)
    Script->>Ref: rmSync ./ref
    Script->>Asar: extract app.asar → ref/
    Asar-->>Ref: openai-codex-electron bundle
    Script->>Prettier: --write *.js, *.css
    Script->>Prettier: --list-different (JS only, up to 3 passes)
    Prettier-->>Script: Prettier verification complete.
    Script-->>Agent: Codex app ref refresh complete.
```

## Prerequisites

<Warning>
Run from the repository root — the directory that should own `./ref`. The script intentionally replaces `./ref` and refuses unsafe targets.
</Warning>

| Requirement | Purpose |
| ------------- | ------- |
| macOS with `Codex.app` at `/Applications/Codex.app` | Default source for `app.asar` |
| Node.js | Runs the refresh script and `npx` subprocesses |
| Network (first run) | `npx -y @electron/asar` and `npx -y prettier` download on demand |

Override the asar location when Codex is installed elsewhere:

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

## Run the refresh

<Tabs>
  <Tab title="Agent">

Ask your agent from the repo root:

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

The skill's default prompt matches this intent: refresh `./ref` from the installed `Codex.app` asar and format extracted JS/CSS.

  </Tab>
  <Tab title="Script">

```bash
# from the repository root
node .agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs
```

  </Tab>
</Tabs>

<Steps>
  <Step title="Confirm working directory">

Verify `pwd` resolves to the decode-codex repository root. The script only accepts a target named `ref` that resolves to `./ref` under the current working directory.

  </Step>
  <Step title="Run sync and format">

The script executes three phases in order:

1. **Sync** — removes existing `./ref`, then extracts the asar into a fresh `ref/` directory.
2. **Format** — walks `ref/` recursively, collects `.js` and `.css` files (skipping any `node_modules` subtree), runs Prettier `--write`, then verifies JavaScript with up to three `--list-different` passes.
3. **Report** — prints the formatted file count and a completion line.

  </Step>
  <Step title="Verify completion signals">

Confirm stdout includes the expected lines before starting deobfuscation:

- `Formatting N JS/CSS file(s) with Prettier, ignoring git/prettier ignore files...`
- `Prettier verification complete.`
- `Codex app ref refresh complete.`

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

If you see `Skipping Prettier formatting.`, the refresh is incomplete unless you intentionally passed `--skip-format`.

Spot-check a known file under `ref/webview/assets/` — it should be multi-line formatted, not a single minified line.

  </Step>
</Steps>

## CLI flags and environment

<ParamField body="--dry-run" type="boolean">
Print resolved `Workspace`, `Source asar`, and `Target ref` paths without deleting or extracting anything. Exits after `Dry run only; no files changed.`
</ParamField>

<ParamField body="--skip-format" type="boolean">
Extract only; skip the Prettier write and verification phases. Logs `Skipping Prettier formatting.` and exits. Use only when you explicitly want raw, unformatted extraction.
</ParamField>

<ParamField body="CODEX_APP_ASAR" type="string">
Override the default asar path (`/Applications/Codex.app/Contents/Resources/app.asar`). Resolved with `path.resolve` before extraction.
</ParamField>

Unknown arguments cause a non-zero exit with `unknown argument(s): ...`. Missing or invalid asar files fail with `asar file not found: ...`.

## What the script does internally

### Safety guards

Before any file operations, `assertSafeRefDir` enforces:

- Basename must be exactly `ref`
- Relative path from cwd must be `ref` (not an absolute or nested path)
- Target must not be filesystem root, home directory, or the cwd itself

These guards prevent accidental deletion of the wrong directory when chaining `rm` and extract manually.

### Prettier behavior

The refresh script deliberately bypasses `.gitignore` and `.prettierignore` by passing `--ignore-path /dev/null`. This matters because `ref/` is gitignored — a plain `prettier --write ref/` would silently skip every file under Prettier 3's default ignore rules.

| Phase | Files | Gate |
| ----- | ----- | ---- |
| `--write` | All `.js` and `.css` under `ref/` (except `node_modules`) | Required |
| `--list-different` verification | JavaScript only | Hard gate — fails after 3 passes if files remain |
| CSS | Formatted but not verified | Bundled Tailwind CSS can be non-idempotent under Prettier |

Files are batched in groups up to ~50 KB of path length to avoid command-line limits.

### Subprocess tools

| Tool | Invocation | On failure |
| ---- | ------------ | ---------- |
| `@electron/asar` | `npx -y @electron/asar extract <asar> <refDir>` | Non-zero exit aborts |
| `prettier` | `npx -y prettier --write` / `--list-different` | Non-zero exit aborts (verification allows exit 1 for differing files) |

Prefer the bundled script over manually chaining `rm`, `npx @electron/asar`, and `prettier` — the script applies consistent safety checks and `node_modules` exclusion.

## Output layout

After a successful refresh, the extracted bundle mirrors the Codex Electron app structure:

:::files
decode-codex/
└─ ref/                              # generated — do not commit
   ├─ package.json                   # name: openai-codex-electron
   ├─ node_modules/                  # extracted deps (format skipped)
   ├─ native-menu-locales/           # JSON locale data
   └─ webview/
      ├─ index.html                  # browser entry + modulepreload roots
      └─ assets/
         ├─ *.js                     # bundled chunks (deobfuscation input)
         ├─ *.css                    # stylesheets
         └─ WASM, fonts, images      # non-JS assets
:::

The deobfuscation skill reads `ref/webview/index.html` for entry discovery and treats `ref/webview/assets/*.js` as the primary restoration target. Chunk hashes rotate every Codex build — always resolve the entry from the freshly extracted `index.html` rather than hard-coding a basename.

<Check>
A refresh is ready for deobfuscation when formatting verification passed and `ref/webview/index.html` exists with script tags pointing at hashed chunks under `ref/webview/assets/`.
</Check>

## Troubleshooting

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

Confirm Codex.app is installed. Check the default path:

```bash
ls -la /Applications/Codex.app/Contents/Resources/app.asar
```

Or set `CODEX_APP_ASAR` to your bundle location and re-run.

  </Accordion>

  <Accordion title="ref directory is unsafe to replace">

You are not in the intended repository root, or cwd resolves incorrectly. `cd` to the decode-codex root where `./ref` should live and retry.

  </Accordion>

  <Accordion title="Prettier verification failed after 3 passes">

Some JavaScript files did not stabilize under Prettier. Inspect the stderr output for the failing paths. Re-run the full refresh; if the problem persists, check whether a specific file triggers a Prettier parser error.

  </Accordion>

  <Accordion title="Formatting appears skipped despite no --skip-format">

Confirm stdout shows `Prettier verification complete.` — not `Skipping Prettier formatting.`. For manual verification against gitignored `ref/`, always include `--ignore-path /dev/null`; otherwise Prettier may report success while skipping all files.

  </Accordion>

  <Accordion title="Command failed to start: npx">

Node.js is missing or not on `PATH`. Install Node.js and verify with `node --version`.

  </Accordion>
</AccordionGroup>

## Dry-run inspection

Use `--dry-run` to confirm paths before wiping `./ref`:

<RequestExample>

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

</RequestExample>

<ResponseExample>

```text
Workspace: /path/to/decode-codex
Source asar: /Applications/Codex.app/Contents/Resources/app.asar
Target ref: /path/to/decode-codex/ref
Dry run only; no files changed.
```

</ResponseExample>

## Legal note

Extracted Codex source is © OpenAI. This project is for personal study and interoperability research of software you have installed. Do not redistribute extracted or restored code.

## Next

<CardGroup>
  <Card title="Quickstart" href="/quickstart">
    First end-to-end run: refresh `./ref`, then deobfuscate `ref/webview/assets` into `./restored/`.
  </Card>
  <Card title="Codex project profile" href="/codex-project-profile">
    Layout of the extracted bundle: entry discovery, chunk roots, and default deep-restore command frame.
  </Card>
  <Card title="Refresh script reference" href="/refresh-script-reference">
    Full CLI reference for `refresh-codex-ref.mjs`: flags, safety guards, verification passes, and stdout contract.
  </Card>
  <Card title="Pipeline caveats" href="/pipeline-caveats">
    Prettier gitignore traps and other failure modes that affect both refresh and restoration.
  </Card>
</CardGroup>
