Generate and edit images via codex exec with the built-in image_gen tool.
No OPENAI_API_KEY required.
Prerequisites
Codex CLI
# Mac / Linux (recommended)
curl -fsSL https://chatgpt.com/codex/install.sh | sh
# Homebrew
brew install --cask codex
# npm
npm install -g @openai/codex
Verify: codex --version
Authentication (check this FIRST when generation 404s)
codex runs on the ChatGPT account login stored in ~/.codex/auth.json.
The id_token expires roughly 10 hours after it is issued, and an
expired token does not surface as an auth error — it comes back as a
model 404:
ERROR: unexpected status 404 Not Found: The model `gpt-5.x` does not exist
or you do not have access to it.
Every other model then fails with ... is not supported when using Codex with a ChatGPT account, which makes it look like a plan/entitlement
problem. It is not. The token is simply stale.
Check the expiry before assuming anything else:
python3 - <<'PY'
import json, base64, datetime, os
d = json.load(open(os.path.expanduser('~/.codex/auth.json')))
p = d['tokens']['id_token'].split('.')[1]; p += '=' * (-len(p) % 4)
c = json.loads(base64.urlsafe_b64decode(p))
print('exp:', datetime.datetime.fromtimestamp(c['exp']).isoformat())
print('now:', datetime.datetime.now().isoformat())
PY
If exp is in the past, the fix is a re-login. It requires browser auth,
so Claude Code cannot run it — ask the user to run it themselves in the
prompt:
! codex login
Switching models (-m gpt-5.4, -m gpt-5-codex, …) does not work around
a stale token: older models are rejected outright for ChatGPT-account
logins. Upgrading the CLI (codex update) does not help either.
Re-login is the only fix.
Invocation contract (MUST follow)
The exact shape of the codex exec call matters. Use this for every mode:
cd <OUTPUT_DIR>
codex exec --sandbox workspace-write --skip-git-repo-check "<INSTRUCTION>" < /dev/null
Four non-obvious requirements, each from a real failure:
--sandbox workspace-write, never-s danger-full-access. Claude Code's auto-mode permission classifier blocksdanger-full-access, so the call never runs at all. Do not retry it or try to route around the denial.workspace-writeis sufficient — it grants write access to the working directory plus/tmpand$TMPDIR.cdinto the output directory and pass a RELATIVE filename in the instruction (e.g.hero.png, not an absolute path). Underworkspace-writeonly the cwd tree is writable, so the output must live inside it. Add "in the current working directory" to the instruction so Codex resolves the path the same way.--skip-git-repo-check. Without it, codex refuses to start:Not inside a trusted directory and --skip-git-repo-check was not specified.Scratchpad directories are not git repos.< /dev/null. Without it, codex blocks onReading additional input from stdin...and never returns.
Reliability rules (MUST follow)
These rules come from real production failures. Skipping them produces silently wrong images.
-
Delete a stale output file BEFORE generating (except in-place refinement, Mode 3). If the output path already exists, Codex may skip generation entirely and report "already saved" while leaving the old image in place.
rm -f <OUTPUT_PATH>Then phrase the instruction as:
"The file <OUTPUT_PATH> does not exist yet. You MUST generate a brand-new image using the built-in image_gen tool and save it to that exact path. Do not reuse or copy any previously generated image." -
Verify the output is fresh after every run. Compare the file's mtime against when the command started (
stat -f %m <OUTPUT_PATH>on macOS). If the mtime is old, the run skipped generation: delete the file and rerun with the MUST-generate phrasing above. -
Isolate concurrent runs with per-job
CODEX_HOME. Parallelcodex execjobs sharing the default~/.codexalso share~/.codex/generated_images/. A job whose generation fails may "recover" by copying the newest file there, which can be ANOTHER job's image, silently writing the wrong picture to the requested path. Therefore: when generating 2+ images, run them in parallel, each with its own isolatedCODEX_HOME(see "Parallel Generation" below). This removes the shared directory and makes parallelism safe. Never run parallel jobs against the shared default home; if a past run did, visually verify every output and rerun any duplicate solo. -
Visually inspect every generated image before using it (open/Read the PNG). Check for: garbled or misspelled text (especially Japanese), clipped labels, overlapping elements, broken or wobbly arrows and lines, pasted-on-looking text boxes. Regenerate until it passes; do not ship an image you have not looked at.
Modes
This skill supports three modes. Claude Code constructs a codex exec
command directly — no wrapper script is needed.
Mode 1: Prompt → Image
Generate an image from a text prompt.
cd <OUTPUT_DIR>
rm -f <OUTPUT_FILE>
codex exec --sandbox workspace-write --skip-git-repo-check \
"The file <OUTPUT_FILE> in the current working directory does not exist yet. You MUST generate a brand-new image using the built-in image_gen tool and save it to that exact path. Do not reuse or copy any previously generated image. Image prompt: <PROMPT>" < /dev/null
Prompt construction
Build the prompt by combining these elements in order:
- Style (optional):
Style: watercolor painting. - Subject: the user's description
- Aspect ratio (optional):
Use a wide landscape composition (16:9 aspect ratio). - Negative (optional):
Avoid: blurry, text, watermark.
Example:
Style: watercolor painting. A mountain landscape at sunset with dramatic clouds.
Use a wide landscape composition (16:9 aspect ratio). Avoid: text, watermark.
Mode 2: Document → Diagram
Pass a large text, Markdown, or PDF file to Codex and have it generate an information-rich infographic or diagram.
cd <OUTPUT_DIR>
rm -f <OUTPUT_FILE>
codex exec --sandbox workspace-write --skip-git-repo-check \
"Read the file <INPUT_PATH>. Analyze its content thoroughly and create an information-rich infographic/diagram that visually summarizes the key points, structure, and relationships. The file <OUTPUT_FILE> in the current working directory does not exist yet. You MUST generate the image using the built-in image_gen tool and save it to that exact path. Additional instructions: <USER_INSTRUCTIONS>" < /dev/null
- Claude Code reads the document first with the Read tool to understand its content, then crafts a detailed instruction for Codex.
- For very large documents, Claude Code should summarize the key points and include them directly in the Codex instruction for better results.
- The user's instructions guide the diagram type (infographic, flowchart, mind map, concept map, timeline, etc.).
- Follow the "Diagram & infographic quality" section below.
Mode 3: Image Refinement
Pass an existing image to Codex for modification.
cd <OUTPUT_DIR>
codex exec --sandbox workspace-write --skip-git-repo-check \
"Look at the image at <INPUT_IMAGE_FILE> in the current working directory. Make the following modifications using the built-in image_gen tool: <MODIFICATION_INSTRUCTIONS>. Overwrite the existing file at <OUTPUT_FILE> with the modified image." < /dev/null
- Use for color adjustments, style changes, element additions/removals, composition tweaks, etc.
- Reference the original image path so Codex can analyze it.
- Do NOT pre-delete the file when refining in place (input == output); instead say "Overwrite the existing file". If input and output differ, apply Reliability rule 1 to the output path.
Diagram & infographic quality
Diffusion-based generation breaks most often on arrows and lines. Design the composition so there is nothing fragile to break.
Composition rules
- Straight, short arrows only. Never request curved arrows, loop-back arrows, or long connector lines weaving between elements. Express cycles or bidirectional sync with a small pill label (e.g. "Synced bidirectionally ⇄") instead of a curved arrow.
- No overlapping elements. Give every label generous spacing; ask for "wide margins on every side" so nothing touches the canvas edge.
- Prefer structures that are hard to break: side-by-side panels, 2x2 card grids, stacked horizontal bars, single-row card flows. Avoid dense networks, swimlanes, and diagrams that need many crossing connectors.
- Keep the element count low; split into two images rather than cramming.
Style lines that work
- Flat diagram:
Crisp flat vector infographic, white background, styled like a clean professional presentation slide. Perfectly straight lines, uniform stroke width, sharp clean edges, generous spacing. - Graphic recording (grareco):
Warm hand-drawn graphic recording style, black ink pen and colored pencil accents on warm cream paper, rounded hand lettering.AddAvoid: digital flat vector lookso the style stays consistent across a series.
Standard Avoid list for diagrams
Avoid: watermark, misspelled text, wobbly lines, blur, curved arrows,
overlapping elements, clipped text, stray marks, decorative dots,
sketchy style, 3D effects, photorealism.
Text accuracy (especially Japanese)
- Quote every string that must appear verbatim (e.g. "approval gate") and add:
All Japanese text must be spelled exactly as given and legible. - After generation, zoom in and verify every label: tofu/garbled glyphs, swapped characters, and clipped endings are the most common failures.
Generated Image Recovery
Codex may save images to <CODEX_HOME>/generated_images/ instead of the
requested output path (~/.codex/generated_images/ for a default-home
run; $JOB/generated_images/ for an isolated parallel job). After
running codex exec:
- Check if the output file exists at the requested path and has a fresh mtime (Reliability rule 2).
- If not, look for the most recently created file in
~/.codex/generated_images/and copy it to the requested output path.
# Find the latest generated image
ls -t ~/.codex/generated_images/*.png 2>/dev/null | head -1
Warning: never blind-copy from
generated_images/while multiple generations are running in parallel — the newest file may belong to a different job (Reliability rule 3). Visually confirm the content matches the requested prompt before accepting it.
Multiple Images / Parallel Generation
Default to parallel execution when generating 2+ images. Serial
execution is only for retries of a single failed image. Parallelism is
safe as long as every job gets its own isolated CODEX_HOME
(cross-contamination — Reliability rule 3 — only happens through the
shared ~/.codex/generated_images/ directory).
Recipe
For each image i, prepare an isolated home and launch the job in the
background (use the Bash tool's run_in_background, one call per image):
JOB=<SCRATCHPAD>/codex-job-<i>
mkdir -p "$JOB"
cp ~/.codex/auth.json ~/.codex/config.toml "$JOB/"
cd <OUTPUT_DIR>
rm -f <OUTPUT_FILE_i>
CODEX_HOME="$JOB" codex exec --sandbox workspace-write --skip-git-repo-check \
"The file <OUTPUT_FILE_i> in the current working directory does not exist yet. You MUST generate a brand-new image using the built-in image_gen tool and save it to that exact path. Do not reuse or copy any previously generated image. Image prompt: <PROMPT_i>" < /dev/null
auth.jsoncarries the login;config.tomlcarries user settings. Copying both into the job home is enough — no re-login needed. Copyauth.jsonfresh at launch time: a copy taken from an already-expired token fails every job with the model 404 described under "Authentication".- Launch ALL jobs first, then wait for completions; do not run them one by one.
- After each job finishes, apply Reliability rules 2 and 4 to its output
(fresh mtime + visual inspection). Recovery lookups for that job go to
$JOB/generated_images/, NOT~/.codex/generated_images/. - If a job fails auth (stale token copy), re-copy a fresh
~/.codex/auth.jsoninto its home and rerun that job alone. - Delete the job homes (
rm -rf <SCRATCHPAD>/codex-job-*) after all outputs are verified.
Aspect Ratios
| Ratio | Use case |
|---|---|
| 1:1 | Social media icons, thumbnails, profile pictures |
| 16:9 | Banners, hero images, desktop wallpapers |
| 9:16 | Mobile wallpapers, stories, vertical videos |
| 4:3 | Blog images, presentations |
| 3:4 | Portrait photos |
| 3:2 | Classic photography landscape |
| 2:3 | Classic photography portrait |
The built-in
image_gentool does not accept explicit pixel dimensions. Aspect ratio and composition are controlled through prompt instructions.
Style Examples
| Style | Description |
|---|---|
photorealistic |
Realistic photography look |
watercolor |
Watercolor painting style |
oil painting |
Classical oil painting style |
anime |
Japanese anime style |
3D render |
3D computer graphics |
pencil sketch |
Hand-drawn pencil sketch |
flat design |
Modern flat design illustration |
pixel art |
Retro pixel art style |
concept art |
Professional concept art |
minimalist |
Clean, minimal design |
See references/prompts.md for detailed prompting guidance.
Limitations
- No explicit resolution control: Use aspect ratio and composition prompts to influence output proportions.
- Single image per call: Each
codex execinvocation generates one image. - Codex CLI required: The
codexcommand must be installed and authenticated with a non-expired token. - Output must live under the working directory:
workspace-writeonly permits writes to the cwd tree,/tmpand$TMPDIR, so every invocationcds to the output directory first. - Document diagram quality: Results depend on how well the instruction conveys the document's structure. For complex documents, Claude Code should pre-summarize key points in the instruction.
- Fragile geometry: curved arrows, long connectors, and dense overlaps frequently render broken. Design them out (see "Diagram & infographic quality").
Error Handling
| Error | Solution |
|---|---|
codex CLI not found |
Install Codex CLI: curl -fsSL https://chatgpt.com/codex/install.sh | sh |
404 Not Found: The model ... does not exist or you do not have access to it |
The stored id_token expired. Ask the user to run ! codex login. Do not switch models or update the CLI — neither fixes it (see "Authentication") |
The '<model>' model is not supported when using Codex with a ChatGPT account |
That model is not available to ChatGPT-account logins. Do not pass -m; let the configured default model apply |
Not inside a trusted directory and --skip-git-repo-check was not specified |
Add --skip-git-repo-check to the codex exec call |
Command hangs on Reading additional input from stdin... |
Append < /dev/null to the codex exec call |
-s danger-full-access call is blocked / denied |
Claude Code's permission classifier blocks it. Use --sandbox workspace-write --skip-git-repo-check with a relative output path under the cwd instead |
| Codex says it cannot write the output path | The path is outside the sandbox. cd to the output directory and pass a relative filename |
Codex timed out |
The default timeout is ~5 minutes. Retry or simplify the prompt |
No images were generated |
Rephrase the prompt; it may have been blocked by safety filters |
Image not at expected path |
Check ~/.codex/generated_images/ manually (see recovery warning) |
| Output file unchanged (old mtime) | Codex skipped generation because the file already existed. Delete the file and rerun with the "does not exist yet / MUST generate" phrasing |
| Output duplicates another parallel job's image | Cross-contamination via a shared generated_images/ — the jobs were run without isolated CODEX_HOME. Delete the file and rerun that image alone (or rerun all jobs with per-job CODEX_HOME) |
| Parallel job fails with auth error | The copied auth.json went stale. Re-copy a fresh ~/.codex/auth.json into that job's home and rerun it alone |
| Broken arrows / wobbly lines in diagrams | Simplify the composition per "Diagram & infographic quality": straight short arrows only, no curves, generous spacing, then regenerate |