# Codex project profile

> Layout of the extracted openai-codex-electron bundle: ref/webview/index.html entry discovery, ref/webview/assets chunk root, npm-leaf and Pierre vendor boundaries, and default deep-restore command frame for this repository.

- 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/reference/codex-ref.md`
- `.agents/skills/deobfuscate-javascript/scripts/check-entry.ts`
- `.agents/skills/deobfuscate-javascript/scripts/build-import-graph.ts`
- `restored/app-shell/thread-handoff-operations/index.ts`
- `restored/composer/composer-footer-branch-switcher/branch-switcher.tsx`
- `restored/runtime/vite-browser-external.ts`

---

---
title: "Codex project profile"
description: "Layout of the extracted openai-codex-electron bundle: ref/webview/index.html entry discovery, ref/webview/assets chunk root, npm-leaf and Pierre vendor boundaries, and default deep-restore command frame for this repository."
---

The extracted Codex desktop bundle under `./ref` is the `openai-codex-electron` package: the browser UI entry is `ref/webview/index.html`, bundled JavaScript lives in `ref/webview/assets/`, and deep restoration auto-discovers the app entry from that HTML before walking the import graph into `./restored/`. Chunk content hashes rotate every Codex.app build, so entry and chunk basenames must be resolved at runtime — never hard-coded from an older snapshot.

## Bundle scope map

After [refreshing `./ref`](/refresh-codex-ref) from `/Applications/Codex.app/Contents/Resources/app.asar`, the layout relevant to restoration looks like this:

:::files
decode-codex/
├─ ref/
│  ├─ package.json              # identifies openai-codex-electron; dependency oracle
│  ├─ node_modules/**           # extracted deps — API shape only, not restore targets
│  ├─ native-menu-locales/**     # JSON locale data
│  └─ webview/
│     ├─ index.html              # <script> + modulepreload roots
│     └─ assets/
│        ├─ *.js                 # Vite/Rollup content-hashed chunks (restore input)
│        ├─ *.css, *.wasm, fonts, images, animation/data files
│        └─ (no per-build stable names — hashes change each release)
└─ restored/                     # semantic deliverables (generated by deobfuscation)
   ├─ IMPORT_MAP.json            # chunk basename → public path
   ├─ .deobfuscate-javascript/_full/
   │  ├─ manifest.json           # import graph + per-chunk stages
   │  └─ ledger.json             # symbol-level rename state
   └─ <domain>/                  # app-shell, composer, browser, utils, vendor, …
:::

<ParamField body="ref/package.json" type="file">
Names the extracted app as `openai-codex-electron`. Use it to confirm npm package identity when classifying boundary chunks.
</ParamField>

<ParamField body="ref/webview/index.html" type="file">
Declares the browser bootstrap: `<script src="…">` roots and `<link rel="modulepreload" href="…">` dependencies. Read this before choosing a restoration entry.
</ParamField>

<ParamField body="ref/webview/assets/*.js" type="glob">
The bundled code root. Every whole-tree restore starts here. CSS, WASM, fonts, and static assets in the same directory are preserved or referenced — not rewritten to TS/TSX unless a JS chunk wraps them.
</ParamField>

<ParamField body="ref/node_modules/**" type="glob">
Extracted dependency and native-module source. Consult for API shape and fork detection; do not run the restoration pipeline against it.
</ParamField>

<Note>
`./ref` is generated and git-ignored. This repository may ship a populated `./restored/` snapshot (for example `restored/.deobfuscate-javascript/_full/manifest.json` records entry `index-CG92uawu` with high-fan-out neighbor `app-main-lwTO-JL9`) even when `./ref` is absent. Refresh `./ref` before starting a new restore against your installed Codex version.
</Note>

```mermaid
flowchart TB
  subgraph source ["Extracted bundle (./ref)"]
    PKG["ref/package.json<br/>openai-codex-electron"]
    HTML["ref/webview/index.html"]
    ASSETS["ref/webview/assets/*.js"]
    NM["ref/node_modules/**"]
  end

  subgraph discovery ["Entry discovery"]
    CE["check-entry.ts --discover"]
    BIG["app-main-* high fan-out"]
  end

  subgraph graph ["Import graph orchestration"]
    M["manifest.json"]
    L["ledger.json"]
  end

  subgraph output ["Public deliverables (./restored)"]
    MAP["IMPORT_MAP.json"]
    DOM["Semantic domains<br/>app-shell, composer, utils, vendor, …"]
  end

  PKG --> ASSETS
  HTML --> CE
  CE --> ASSETS
  CE --> BIG
  ASSETS --> M
  M --> L
  L --> DOM
  DOM --> MAP
  NM -.->|"fork / API checks only"| ASSETS
```

## Entry discovery from index.html

Whole-tree restoration treats `ref/webview/index.html` as authoritative. `check-entry.ts --discover` parses `<script src>` and `<link rel="modulepreload" href>` basenames, resolves them under `ref/webview/assets`, and scores each candidate before printing the chosen entry path on stdout.

<Steps>
<Step title="Discover the entry">
```bash
SKILL_DIR=.agents/skills/deobfuscate-javascript
ENTRY=$(bun "$SKILL_DIR/scripts/check-entry.ts" --discover --root ref/webview/assets)
echo "$ENTRY"
```
</Step>
<Step title="Interpret exit codes">
<ResponseField name="0" type="exit code">Entry looks reasonable — proceed.</ResponseField>
<ResponseField name="3" type="exit code">Suspicious vendor/transitive leaf — do not build the graph from this file.</ResponseField>
<ResponseField name="1" type="exit code">I/O failure or no entry discovered.</ResponseField>
<ResponseField name="64" type="exit code">Usage error (missing `--root`).</ResponseField>
</Step>
<Step title="Verify fan-out signals">
A real app entry has high **local out-degree** (many sibling chunk imports) and low **in-degree** (few siblings import it). A vendor leaf shows the inverse: imported by many siblings, imports few locals. The `<script>` root in `index.html` is the bootstrap; `app-main-*` is the usual deep-restore target because it fans out into most feature code even when it is not the script tag itself.
</Step>
</Steps>

Selection order inside `discoverEntry`:

1. Prefer a non-suspicious `<script>` root with the highest local out-degree.
2. Fall back to the best non-suspicious, non-vendored candidate (script or preload).
3. If every root looks vendored or suspicious, pick the highest fan-out basename and flag the risk in the discovery reason string.

`build-import-graph.ts` performs the same auto-discovery when the positional entry is omitted or `--discover` is passed. It warns on suspicious entries but does not block — run `check-entry.ts` first or heed the warning.

<Warning>
Pointing the graph at a transitive vendor leaf (for example a `vscode-languageserver-types` or lodash utility chunk imported by dozens of siblings) produces a tiny dependency closure that looks complete but is the wrong subtree. Exit code `3` from `check-entry.ts` is the guardrail.
</Warning>

## Chunk root and file kinds

`build-import-graph.ts` walks every reachable `./xxx-HASH.js` import from the entry and classifies each node in `manifest.json`:

| Kind | Behavior | Restore action |
| --- | --- | --- |
| `local` | Project-local sibling chunk | BFS continues; staged under `_full/files/<basename>/` |
| `oversized-local` | Local chunk over `--max-lines N` cap (partial mode only) | Recorded but not descended into unless `--include` or `--max-lines 0` |
| `npm-leaf` | Known npm package or bundled vendor data (Shiki grammar/theme, 3Dmol, etc.) | Terminal node; consumers rewritten to bare specifiers |
| `external` | Bare specifier like `"react"` | Terminal node |

For Codex deep restores, pass `--max-lines 0` so no local chunk is treated as an oversized boundary. A positive `--max-lines` is a quick/partial mode only.

Known npm chunks are detected via `CHUNK_NAME_REGISTRY` in `resolve-npm-imports.ts` (basename stems like `clsx`, `react`, `jsx-runtime`, `tslib.es6`, `marked.esm`, `floating-ui.react-dom`, `core.esm`, `statsig`, …) plus `classifyVendorDataChunk` for grammar/theme/data payloads. Example from a live manifest: a shared chunk named `app-initial~app-main~…` is classified `npm-leaf` with `npmPackage: "@shikijs/langs"` and skipped — it never lands in `restored/utils/`.

## npm-leaf and bare-import boundaries

Stock npm packages bundled under project-local basenames (`isEqual-*`, `lib-*`, `single-value-*`, `chunk-XXXX-*`) should become **bare re-export shims**, not `any`-facades. The model file is a `vendor/highlight-js-core.ts`-style re-export recorded in `IMPORT_MAP.json`.

| Typical chunk signal | npm specifier | Deliverable pattern |
| --- | --- | --- |
| `isEqual-*` | `lodash` | `vendor/lodash.ts` star/named re-export |
| `chunk-LFPYN7LY-*` | `react-router` | bare re-export shim |
| `lib-BWT6A3Q0` | `react-intl` | `useIntl` / `FormattedMessage` surface |
| `single-value-*` | `framer-motion` | bare re-export shim |
| `pkg-*` | `@segment/analytics-next` | analytics SDK boundary |
| `dist-*`, `Combination-*` | `@radix-ui/react-*` | per-primitive shim (**may be forked**) |
| `src-*` | `zod` | verify stock Zod vs Codex fork |

Extend `CHUNK_NAME_REGISTRY` or pass `--treat-as-npm name,name,…` when the bundler uses a basename the registry does not yet cover. Record the package in `IMPORT_MAP.json` so `classifyBoundary()` and `quality-gate.ts` treat the chunk as resolved vendor npm, not an open `any`-facade.

Runtime/host boundaries that are genuine app infrastructure (`app-scope`, `vscode-api`, `rpc`, `host-config`) may receive typed `any`-facades via `make-facade.ts` and `ledger.ts mark-faced` so consumers compile while the runtime is restored later. Facades are open boundaries — a deep restore is not complete while they stand in for project-local chunks.

## Pierre vendor boundaries

Codex bundles `@pierre/trees` (file tree, Preact-based) and `@pierre/diffs` (diff views, Shiki-backed) inline. These are **vendored package boundaries**, not Codex feature code — but Codex **forked** them, so a clean bare swap is often infeasible.

Recognize the Pierre family by fingerprint, not basename:

| Signal | Examples |
| --- | --- |
| CSS custom properties | `--trees-row-height`, `--trees-file-icon-color-rust`, `--diffs-addition-base`, `--diffs-line-bg` |
| DOM attributes | `data-file-tree-virtualized-root`, `data-diffs-header`, `data-diff-type`, `data-diff-span` |
| Theme names | `pierre-light`, `pierre-dark`, `pierre-dark-soft` |
| Renderer cluster basenames | `file-tree-search-input-*`, `shiki-highlight-provider-gate-*`, `file-diff-*`, `diff-unified-*`, `parsePatchFiles-*`, highlight `worker-*` |

Treatment order:

1. **Clean leaves → bare import.** The highlight worker (Oniguruma WASM, no Codex logic) maps to `@pierre/diffs/worker`. A self-contained `parsePatchFiles-*` chunk may map to `@pierre/diffs` if the public surface reconciles.
2. **Forked / entangled engine → keep wrapper, boundary-ize.** Do not delete forked files or pretend they are upstream. Mark vendored (`quality-gate.ts --vendored`), keep thin Codex wrappers, lift Codex-local inputs to props/config. Example mapping: `file-diff-*` → `vendor/pierre-diffs/file-diff.ts` exporting `FileDiff`.
3. **Themes** (`pierre-*`) → `@pierre/theme` data (low priority).

<Warning>
**Basename traps — these are Codex code, not Pierre:**

`diff-stats-*`, `diff-view-mode-*`, `use-diff-annotations-*`, `parse-diff-*` (size-guard wrapper), `grammars/diffGrammar.ts`, `treeView-*` / `treemap-*` (Mermaid/d3), `worktree-*` / `pending-worktree-*`, and genuine consumers (`review-*`, `workspace-directory-tree-*`, `editor-diff-page-*`) stay in restored feature domains.
</Warning>

This restore workspace has no vendored `node_modules` under `restored/`. Externalizing Pierre packages means ambient `declare module "…"` stubs plus `IMPORT_MAP.json` reclassification — not installing packages.

## Default deep-restore command frame

For a main app restore or continuation against this repository:

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

Omit the positional entry and pass `--discover` to `build-import-graph.ts` when you want the script to resolve the entry itself:

```bash
bun "$SKILL_DIR/scripts/build-import-graph.ts" \
  --target restored \
  --root ref/webview/assets \
  --max-lines 0
```

After checkpoints exist, run organization and promotion (`plan-organize.ts`, `promote-organized.ts`), Stage 3 acceptance review in deep mode, then:

```bash
bun "$SKILL_DIR/scripts/quality-gate.ts" restored
```

<Check>
Completion requires `quality-gate.ts` exit 0, every reachable local chunk at `stages.promoted` (plus `stages.finalized` in deep mode), and an empty `ledger.ts frontier --stage promote` — not merely populated checkpoints under `_full/`.
</Check>

## Resume before rebuilding

Inspect existing restoration state before re-running graph or auto-restore scripts:

```bash
find restored -maxdepth 3 \( -name README.md -o -name 'IMPORT_MAP.json' \)
find restored \( -path '*/.deobfuscate-javascript/_full/manifest.json' \
  -o -path '*/.deobfuscate-javascript/_full/ledger.json' \)
```

If `restored/.deobfuscate-javascript/_full/manifest.json` and `ledger.json` exist, resume from them unless the user asked to rebuild or the entry hash changed after a Codex.app refresh. Reuse the single shared `restored/IMPORT_MAP.json` at the restore root.

## Semantic output conventions

Public files under `restored/` follow product-domain folders (kebab-case, hash-free names). Provenance stays in file headers and `IMPORT_MAP.json`:

```typescript
// Restored from ref/webview/assets/composer-footer-branch-switcher-GaN7fzcq.js
```

Representative domains in the current snapshot: `app-shell/` (thread handoff operations), `composer/` (footer branch switcher), `browser/`, `threads/`, `runtime/` (including `vite-browser-external.ts` for `__vite-browser-external-*` chunks), `utils/`, `vendor/`, and `features/`.

Feature chunks named after product concepts (`composer-*`, `thread-*`, `app-shell-*`, `settings-*`, `mcp-*`, `*-page-*`, `*-panel-*`) deserve Stage 3 semantic splitting and typed TS/TSX surfaces. Syntax grammars, themes, locales, Mermaid, KaTeX, PDF, and protobuf runtime chunks should become compact facades or data modules — prove vendor/data identity by fingerprint before boundary-izing an app feature.

## Related pages

<CardGroup>
<Card title="Refresh Codex reference source" href="/refresh-codex-ref">
Extract and format `./ref` from the installed Codex.app before any deobfuscation run.
</Card>
<Card title="Full tree restoration" href="/full-tree-restoration">
End-to-end deep workflow: graph build, ledger, auto-restore, organize, promote, and quality gate.
</Card>
<Card title="Import graph and boundaries" href="/import-graph-and-boundaries">
manifest.json and ledger.json orchestration, terminal chunk kinds, and facade lifecycle.
</Card>
<Card title="Workspace and output conventions" href="/workspace-and-output">
Staging under `.deobfuscate-javascript/`, promote bar, semantic domains, and `IMPORT_MAP.json`.
</Card>
<Card title="Pipeline caveats" href="/pipeline-caveats">
Vendor-leaf entry misidentification, Pierre basename traps, and recovery steps.
</Card>
</CardGroup>
