Polyhydra Skills  /  Content & Art

codex-art

Generate hero or illustration art (not icons or pixel-art sprites) for a product/landing page via Codex CLI's built-in image tool, authenticated through ChatGPT login rather than API credits. Use when a page needs a hero image or thematic accent art and there is no existing asset to reuse -- e.g. "generate some art for this", "make a hero image". Not for UI icons, pixel-art game sprites, or photorealistic app screenshots.

Content & Art

Drop this in — save the block below as ~/.claude/skills/codex-art/SKILL.md, or run:

mkdir -p ~/.claude/skills/codex-art
cat > ~/.claude/skills/codex-art/SKILL.md <<'EOF'
# (paste the full source block below into this file)
EOF

Full source

SKILL.md — copy everything inside
# Codex Art

## Capability

Codex CLI (`codex`) has a built-in image generation tool available to the agent when run non-interactively via `codex exec`. It's authenticated through `codex login` (ChatGPT), not the `OPENAI_API_KEY` route — those are two separate credentials with separate billing, and the API-key route is not reliably configured in most environments. Check `codex login status` if you're unsure; it should say "Logged in using ChatGPT."

This skill turns that raw capability into a repeatable workflow: generate one or more coherent images, validate what actually came back, and integrate the result into a real project without leaving orphaned test files behind.

## Before generating: check for prior art

Don't reach for this skill reflexively. If the page already has usable art (see `visual-asset-inventory` for how to audit that), or if what's needed is small UI iconography rather than a hero/illustration image, this is the wrong tool — icon/pixel-art sprite generation is out of scope for this skill.

## Step 1: Establish the style brief once

If you're generating more than one image for the same page or product, write a short **style brief** first — palette (pull actual hex values from the page's CSS `:root` variables if it's a web page), medium (e.g. "painterly digital fantasy art, not photorealistic, not cartoonish"), mood, and anything explicitly forbidden (readable text, logos, specific real people). Reuse this brief verbatim across every image prompt in the set. This is what makes a hero image and two accent images look like they belong to the same page instead of three unrelated stock photos.

Read the actual page/CSS before writing the brief — don't guess at the palette.

## Step 2: Generate

Batch everything into as few `codex exec` invocations as reasonably possible — each invocation is a real ChatGPT-account usage cost, and running the agent loop once for 2-3 images is cheaper and faster than one process per image. A single invocation can generate multiple images in sequence if you list them all in the prompt.

Working invocation pattern:

```sh
codex exec \
  -C /path/to/repo \
  -s workspace-write \
  --skip-git-repo-check \
  "Using your built-in image generation tool, generate <N> illustrations and save them under <target-dir>/.

<style brief — palette, medium, mood, constraints>

1. <path-1> — <size, e.g. 1536x1024> — <scene/subject for image 1>
2. <path-2> — <size, e.g. 1024x1024> — <scene/subject for image 2>

After generating, run 'file' on each output and print the results so dimensions and format can be confirmed."
```

Notes on the flags:
- `-s workspace-write` and `--skip-git-repo-check` are needed if the target directory isn't (yet) a trusted git repo Codex already has write access to.
- `-C <repo>` scopes the sandbox to the project directory — don't generate into `/tmp` and copy over manually, let Codex write directly into the target path in the same call, since Codex has to `cp` from its own `~/.codex/generated_images/<session>/...` output anyway and can do that copy itself.
- Ask Codex to print `file` output on the results in the same call — that's your first, cheapest validation signal (real PNG, expected dimensions) without spending a second turn on it.

**Run it in the foreground, not backgrounded.** A `codex exec` image-generation call typically takes 2-3 minutes — long, but bounded. Resist backgrounding it: if the calling agent has no `run_in_background`-style notification wired up for plain Bash calls (most don't — that mechanism is usually reserved for other tool types), a backgrounded call leaves the agent with nothing to wait on, and it's easy to burn the rest of the turn budget looping or guessing instead of just letting the foreground command return. Just run it and let it block; that's the correct amount of waiting.

If it must run in the background for some reason (parallelizing several unrelated images across separate calls), poll by checking whether the target file actually exists on disk — don't wait on a generic completion signal that may not fire for raw shell commands.

If Codex reports it does not have a built-in image tool in that session (rare, but possible depending on account/session state), stop and say so plainly rather than falling back to the `OPENAI_API_KEY` route silently — that route has historically been an invalid/expired credential in this environment and will just burn a turn on a 401.

## Step 3: Actually look at the result

A `file` check confirming "PNG, correct dimensions" is necessary but not sufficient — it tells you Codex produced *a* valid image, not a *good* one. Use the Read tool to view every generated image yourself before treating the task as done. Things `file` can't catch: wrong mood, readable gibberish text rendered into the scene, a subject that doesn't read as fantasy or reads as generic stock art, a composition that won't crop well into the target UI slot.

If it's a multi-image set, check that they actually look like they belong together (consistent palette/lighting), not just that each one individually is fine.

Show the result to the user before generating variations or moving on to integration — don't burn another generation pass on a hunch that they'll want something different. If something's off, regenerate the one specific image with a corrected prompt rather than the whole set.

## Step 4: Integrate, then clean up

- Copy (don't leave the raw `~/.codex/generated_images/...` files as the source of truth) into the project's real asset location — e.g. `site/assets/`, `public/`, wherever the project already keeps images.
- Wire it into the actual markup/CSS (`<img>` tag, CSS `background-image`, whatever the page needs) rather than just dropping the file and calling it done.
- Delete any throwaway test/preview images generated along the way (e.g. a `hero-test.png` used to validate the style before committing to the full set) — rename the keeper to its real filename instead of leaving both around.
- If the images are large (a single generated PNG commonly lands in the 1-2MB range), and the deployment target uses something with a small payload ceiling — Docker Swarm `configs` cap at 500KB, some CDNs have similar limits — don't discover that at deploy time. Check the target's constraints before deploy and use a bind-mounted volume or object storage instead of a size-limited config/secret mechanism if needed.

## What this skill does not cover

- Real product screenshots — those require an actually running app (see the `run` skill) and a screenshot tool, not generated art.
- Small UI icons / pixel-art sprites — out of scope for this skill.
- Image editing/compositing of existing assets — this is generation only.
</content>
</invoke>