# Refresh script reference

> refresh-codex-ref.mjs flags (--dry-run, --skip-format), CODEX_APP_ASAR override, safety guards on ./ref replacement, Prettier verification passes, and expected stdout completion lines.

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

---

---
title: "Refresh script reference"
description: "refresh-codex-ref.mjs flags (--dry-run, --skip-format), CODEX_APP_ASAR override, safety guards on ./ref replacement, Prettier verification passes, and expected stdout completion lines."
---

`refresh-codex-ref.mjs` is the bundled Node entry point for the `codex-app-ref-refresh` skill. From the repository root it deletes `./ref`, extracts the Codex.app `app.asar` with `@electron/asar`, formats every extracted `.js` and `.css` file with Prettier (skipping `ref/node_modules`), and verifies JavaScript formatting with up to three `--list-different` passes before printing a completion line.

## Invocation

<CodeGroup>

```bash title="Default refresh"
node .agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs
```

```bash title="Dry-run path inspection"
node .agents/skills/codex-app-ref-refresh/scripts/refresh-codex-ref.mjs --dry-run
```

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

</CodeGroup>

Run from the directory that should own `./ref`. The script resolves `ref` as `path.join(process.cwd(), "ref")` and refuses unsafe targets before any deletion.

<ParamField body="--dry-run" type="flag">
Prints resolved `Workspace`, `Source asar`, and `Target ref` paths, then exits with `Dry run only; no files changed.` Does not delete `./ref`, extract the asar, or invoke Prettier.
</ParamField>

<ParamField body="--skip-format" type="flag">
Extracts the asar and logs `Skipping Prettier formatting.` before exit. Use only when raw, unformatted extraction is intentional — minified asar output is unreadable for deobfuscation without the default format step.
</ParamField>

<ParamField body="--help" type="flag">
Aliases: `-h`. Prints usage (flags and `CODEX_APP_ASAR`) and exits 0.
</ParamField>

<ParamField body="CODEX_APP_ASAR" type="string">
Overrides the default source asar path `/Applications/Codex.app/Contents/Resources/app.asar`. The value is passed through `path.resolve()` before existence checks and extraction.
</ParamField>

Unknown positional flags or arguments cause a non-zero exit: `Error: unknown argument(s): <names>`.

## Pipeline phases

```mermaid
sequenceDiagram
  participant CLI as refresh-codex-ref.mjs
  participant FS as ./ref
  participant ASAR as npx @electron/asar
  participant P as npx prettier

  CLI->>CLI: assertSafeRefDir(./ref)
  CLI->>CLI: log Workspace / Source asar / Target ref
  alt --dry-run
    CLI-->>CLI: exit 0 (no changes)
  else live run
    CLI->>FS: rmSync ./ref (recursive)
    CLI->>FS: mkdirSync ./ref
    CLI->>ASAR: extract asarPath → refDir
    alt --skip-format
      CLI-->>CLI: exit 0 (skip Prettier)
    else default
      CLI->>CLI: walkFormatTargets (skip node_modules)
      CLI->>P: --write --ignore-path /dev/null (JS + CSS)
      loop up to 3 verification passes
        CLI->>P: --list-different (JS only)
        alt files still differ
          CLI->>P: --write on differing JS files
        end
      end
      CLI-->>CLI: Codex app ref refresh complete.
    end
  end
```

| Phase | Action | Subprocess | Skipped when |
| ----- | ------ | ---------- | ------------ |
| Guard | `assertSafeRefDir` on resolved `./ref` | — | Never |
| Sync | `rmSync` + `mkdirSync` + asar extract | `npx -y @electron/asar extract` | `--dry-run` |
| Format | Prettier write over all `.js`/`.css` under `ref` | `npx -y prettier --write` | `--dry-run`, `--skip-format` |
| Verify | `--list-different` loop on JS files only | `npx -y prettier --list-different` | `--dry-run`, `--skip-format`, or zero JS files |
| Report | Completion or skip-format line | — | `--dry-run` only |

## Safety guards on `./ref` replacement

`assertSafeRefDir` runs before path logging and before `--dry-run` short-circuits deletion. All checks must pass or the script exits with `Error: …`.

| Guard | Condition | Error message prefix |
| ----- | --------- | -------------------- |
| Not a system anchor | `refDir` must not equal filesystem root, user home (`homedir()`), or `cwd` itself | `ref directory is unsafe to replace` |
| Basename | Directory name must be exactly `ref` | `ref directory must be named "ref"` |
| Relative path | `path.relative(cwd, refDir)` must equal `ref` | `ref directory must resolve to ./ref under the current working directory` |

<Warning>
The guard validates the *shape* of the target (`./ref` under cwd), not whether cwd is this repository. Running from `/tmp` would replace `/tmp/ref`. Always `cd` to the intended workspace first.
</Warning>

After guards pass, a live run unconditionally executes `rmSync(refDir, { recursive: true, force: true })`. There is no backup or prompt.

## Prettier formatting and verification

### Walk and scope

`walkFormatTargets` recursively collects files ending in `.js` or `.css` under `refDir`. Any directory named `node_modules` is skipped entirely — extracted vendor trees under `ref/node_modules` are never formatted.

### Ignore-path bypass

Both write and verify invocations pass `--ignore-path /dev/null` (`PRETTIER_IGNORE_PATH`). This bypasses `.gitignore` and `.prettierignore`. In this repository, `ref/` is gitignored, so a plain `prettier --write ref/` would silently skip files; the script forces formatting anyway.

### Write pass

`formatWithPrettier` batches file paths so the combined path-string length stays under 50,000 characters per `npx` invocation, then runs:

```
npx -y prettier --write --ignore-path /dev/null <batch...>
```

All discovered JS and CSS files are formatted in the initial write pass.

### Verification passes (JS only)

`verifyWithPrettier` runs only on `.js` files (`jsFiles` filter). CSS is formatted but not used as a hard verification gate — bundled Tailwind CSS can be non-idempotent under Prettier.

| Pass behavior | Detail |
| ------------- | ------ |
| Max passes | 3 (`maxVerificationPasses`) |
| Check command | `prettier --list-different --ignore-path /dev/null` |
| Allowed exit codes | `0` (all match) and `1` (some differ) |
| Retry | On pass 1–2, differing files are reformatted and the loop continues |
| Failure | On pass 3 with remaining diffs: `Prettier verification failed: N file(s) still need formatting.` |
| Zero JS files | Logs `Prettier verification complete.` immediately |

Intermediate retry stdout:

```
Prettier verification found N file(s) needing another pass; reformatting...
```

Acceptable only when followed by `Prettier verification complete.`

## Expected stdout and stderr

### Startup (all modes except `--help`)

<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>

With `CODEX_APP_ASAR=/custom/path/app.asar`, the `Source asar:` line reflects the resolved override.

### Successful full refresh

<ResponseExample>

```text
Workspace: /path/to/decode-codex
Source asar: /Applications/Codex.app/Contents/Resources/app.asar
Target ref: /path/to/decode-codex/ref
Removing existing ./ref...
Extracting Codex app asar...
Formatting 842 JS/CSS file(s) with Prettier, ignoring git/prettier ignore files...
Prettier verification complete.
Codex app ref refresh complete.
```

</ResponseExample>

The file count `N` varies with the installed Codex.app version. A retry pass may appear between the formatting line and `Prettier verification complete.`

### `--skip-format` completion

```text
Skipping Prettier formatting.
```

Treat this as an incomplete refresh for deobfuscation unless extraction-only was intentional.

### Error lines

| Trigger | Example stderr |
| ------- | -------------- |
| Missing asar | `Error: asar file not found: /Applications/Codex.app/Contents/Resources/app.asar` |
| Unsafe ref path | `Error: ref directory is unsafe to replace: /Users/you` |
| Wrong ref name/location | `Error: ref directory must be named "ref": …` or `… must resolve to ./ref …` |
| Unknown flag | `Error: unknown argument(s): --bogus` |
| Subprocess failure | `Error: npx exited with status 1` |
| Verification exhausted | `Error: Prettier verification failed: 3 file(s) still need formatting.` |

All errors are prefixed with `Error:` and exit non-zero via `process.exit(1)`.

## Verification checklist

<Steps>

<Step title="Confirm cwd">
Ensure `Target ref:` in startup output ends with your workspace `/ref`, not another directory's `./ref`.
</Step>

<Step title="Read completion signals">
A complete default run must include, in order after extraction:
`Formatting N JS/CSS file(s)…` → `Prettier verification complete.` → `Codex app ref refresh complete.`
</Step>

<Step title="Spot-check formatted output">
Open a known file under `ref/webview/assets/` — it should be multi-line Prettier output, not a single minified line.
</Step>

<Step title="Manual Prettier check (optional)">
If re-verifying by hand, pass `--ignore-path /dev/null`; otherwise gitignored `ref/` files may be skipped. Prefer strict checks on JS files only.
</Step>

</Steps>

<Check>
`Prettier verification found N file(s) needing another pass; reformatting…` is normal when followed by `Prettier verification complete.`
</Check>

## Troubleshooting

<AccordionGroup>

<Accordion title="Prettier reports success but ref files look minified">
You likely ran plain `prettier` without `--ignore-path /dev/null`. Because `ref/` is gitignored, Prettier 3 defaults skip those files. Re-run the bundled script or add the ignore-path flag manually.
</Accordion>

<Accordion title="Verification fails after three passes">
Inspect the files listed in the failure message. Persistent diffs usually indicate Prettier parser options incompatible with a specific bundle chunk. Fix or exclude manually, then re-run; the script does not support per-file overrides.
</Accordion>

<Accordion title="asar file not found">
Install Codex.app at the default path or set `CODEX_APP_ASAR` to the actual `Contents/Resources/app.asar` inside your bundle.
</Accordion>

<Accordion title="npx failed to start or exited non-zero">
Confirm Node.js and network access for `npx -y` downloads of `@electron/asar` and `prettier`. Subprocess stderr is inherited (`stdio: "inherit"` on extract/format; captured on list-different with stderr forwarded).
</Accordion>

</AccordionGroup>

## Related pages

<CardGroup>

<Card title="Refresh Codex reference source" href="/refresh-codex-ref">
Workflow-oriented guide: when to refresh, agent invocation, and pre-deobfuscation checks.
</Card>

<Card title="External tools and dependencies" href="/external-tools-and-dependencies">
`@electron/asar`, Prettier via `npx`, subprocess exit codes, and offline behavior.
</Card>

<Card title="Pipeline caveats" href="/pipeline-caveats">
Prettier `.gitignore` traps, non-idempotent CSS, and recovery steps shared with the deobfuscation pipeline.
</Card>

<Card title="Installation" href="/installation">
macOS Codex.app path, Node.js prerequisite, and first-time setup before running the script.
</Card>

</CardGroup>
