# Codex Imagen [![CI](https://github.com/darkamenosa/codex-imagen/actions/workflows/ci.yml/badge.svg)](https://github.com/darkamenosa/codex-imagen/actions/workflows/ci.yml) OpenClaw skill and helper CLI for generating or editing images through the ChatGPT/Codex backend with local OAuth credentials. By default this follows Codex's current hosted image flow: `POST /responses` with the native `image_generation` tool. The standalone typed image endpoints are available for probing with `--backend images`, but Codex source currently gates that path behind the under-development image-generation extension. The helper also preserves ChatGPT Cloudflare cookies for allowed ChatGPT hosts, matching Codex's restricted request client behavior. It does not start `codex app-server`, does not require a Codex binary, and does not require `OPENAI_API_KEY`. ## Requirements - Node.js 22+ - Existing Codex or OpenClaw `openai-codex` OAuth credentials on the machine Supported auth stores: - OpenClaw auth profiles: `~/.openclaw/agents/main/agent/auth-profiles.json` - OpenClaw agent auth: `~/.openclaw/agents/main/agent/auth.json` - OpenClaw legacy OAuth: `~/.openclaw/credentials/oauth.json` - Codex CLI/Desktop: `~/.codex/auth.json` ## Quick Start Check auth without generating: ```bash node scripts/codex-imagen.mjs --smoke ``` Generate one image: ```bash node scripts/codex-imagen.mjs 'generate image follow this prompt, no refine: "a cinematic fantasy city at sunrise"' ``` Ask for multiple outputs in the prompt. There is no `--count` flag. ```bash node scripts/codex-imagen.mjs --timeout 900 'generate 3 images follow this prompt, no refine: "three distinct ancient ARPG MMO screenshots"' ``` Normal generation prints one saved PNG path per line. Diagnostics and progress are written to stderr unless `--quiet` is used. ## CLI Usage ```bash node scripts/codex-imagen.mjs "prompt" [options] ``` Prompt options: - `--prompt `: prompt text. - `--prompt-file `: read UTF-8 prompt text from a file. - Positional text is accepted when `--prompt` and `--prompt-file` are not used. Reference image options: - `-i, --image `: attach local image files. Repeat or comma-separate. - `--input-ref `: attach local paths, `http(s)` URLs, or `data:image/...` URLs. Repeat or comma-separate. - `--image-url `: attach an `http(s)` or `data:image/...` URL. - `--image-detail `: set the Responses `input_image.detail` value. Ignored by `--backend images`. Default: `high`. Output options: - `-o, --output `: exact PNG path for one image, directory for many, or a path template that is numbered for multiple images. - `--out-dir `: output directory when `--output` is not provided. - `--json`: print a machine-readable summary instead of only image paths. Runtime options: - `--backend `: Codex image backend. Default: `responses`, matching current Codex hosted `image_generation`. `images` calls the under-development standalone typed endpoint. - `--model `: model slug. Defaults: `gpt-5.4` for `responses`, `gpt-image-2` for `images`. - `--retries `: retry transient empty failures this many times. Default: `4`, matching Codex's request retry default of 5 total attempts. Retries apply to network failures, HTTP 5xx, backend `server_error` / overloaded / unavailable responses, dropped/incomplete streams before any image is saved, and typed JSON responses without image data. - `--no-retry`: disable transient generation retries. - `--timeout `: abort after this many seconds per generation attempt. Default: `900`, or `300` when an OpenClaw runtime is detected; must be greater than `0`. This is the recommended flag for OpenClaw and other agent usage. - `--timeout-seconds `: alias for `--timeout`. - `--timeout-ms `: advanced compatibility flag for millisecond timeouts and sub-second tests. Use only one timeout flag per command. After timeout, a hard watchdog forces exit code `124` if the HTTP abort does not settle. - `--no-stream`: request a non-streaming Responses response. The `images` backend is always non-streaming JSON. - `--quiet`: suppress progress diagnostics on stderr. - `--verbose` or `--debug`: print request progress, raw Responses event names, and reference image details to stderr. - `--cwd `: resolve relative input/output paths from this working directory. - `--base-url `: Codex backend base URL. Default: `https://chatgpt.com/backend-api/codex`. - `--refresh-url `: OAuth refresh endpoint. Default: `https://auth.openai.com/oauth/token`. Auth options: - `--auth `: explicit auth JSON path. - `--auth-profile `: OpenClaw profile id, for example `openai-codex:hxtxmu@gmail.com`. - `--smoke`: print redacted auth metadata and exit without generation. - `--force-refresh`: refresh OAuth before generating. - `--refresh-only`: refresh OAuth and exit. Does not require a prompt. - `--no-refresh`: disable proactive refresh and the 401 refresh retry. ## Reference Images Use explicit reference-image flags. Positional arguments are reserved for prompt text. ```bash node scripts/codex-imagen.mjs --input-ref ref1.png --input-ref ref2.jpg --prompt 'generate 3 images of him livestreaming in this world' node scripts/codex-imagen.mjs -i ref1.png -i ref2.jpg --prompt 'change the main character into a woman' node scripts/codex-imagen.mjs --image-url 'https://example.com/ref.png' --prompt 'use this image as the environment reference' ``` Local references are converted to base64 `data:image/...` input images before sending. Supported local formats are PNG, JPEG, GIF, and WebP. The CLI warns when a base64 reference is large; use smaller JPEG references when high-fidelity pixel detail is not needed. ## Output Paths When no output option is set, the first available directory is used: 1. `CODEX_IMAGEN_OUT_DIR` 2. `OPENCLAW_OUTPUT_DIR` 3. `OPENCLAW_AGENT_DIR/artifacts/codex-imagen` 4. `OPENCLAW_STATE_DIR/artifacts/codex-imagen` 5. `./codex-imagen-output` Automatic filenames use: ```text codex-imagen---.png ``` `--output` behavior: - `--output image.png` with one image writes exactly `image.png`. - `--output image.png` with multiple images writes `image-1.png`, `image-2.png`, and so on. - `--output out/` or `--output out` treats the value as a directory and uses automatic filenames. - `--out-dir out` always writes automatic filenames under `out`. In the default streaming Responses mode, each image is written as soon as it arrives. If a run times out after partial results, already saved images remain on disk and are still printed. If the hosted Responses stream terminates or closes before `response.completed`, the command follows Codex semantics: already completed images remain saved, but the command exits with a stream error. ## Auth Lookup Lookup order: 1. `--auth` 2. `CODEX_IMAGEN_AUTH_JSON`, `OPENCLAW_CODEX_AUTH_JSON`, `CODEX_AUTH_JSON` 3. `OPENCLAW_AGENT_DIR/auth-profiles.json` or `PI_CODING_AGENT_DIR/auth-profiles.json` 4. `OPENCLAW_AGENT_DIR/auth.json` or `PI_CODING_AGENT_DIR/auth.json` 5. `~/.openclaw/agents/main/agent/auth-profiles.json` 6. `~/.openclaw/agents/main/agent/auth.json` 7. `~/.openclaw/credentials/oauth.json` 8. `CODEX_HOME/auth.json` 9. `~/.codex/auth.json` Profile selection for OpenClaw `auth-profiles.json`: 1. `--auth-profile` 2. `CODEX_IMAGEN_AUTH_PROFILE` or `OPENCLAW_AUTH_PROFILE` 3. OpenClaw config `auth.order.openai-codex`, then configured `auth.profiles` for `openai-codex` 4. sibling `auth-state.json` `lastGood.openai-codex` 5. best available `openai-codex` OAuth profile, preferring `openai-codex:default`, later expiry, email, and account id Codex CLI is optional. If OpenClaw created the `openai-codex` OAuth profile through `openclaw onboard --auth-choice openai-codex` or `openclaw models auth login --provider openai-codex`, this helper can use that profile directly without installing Codex CLI. The helper reads and refreshes existing credentials; it does not run the first browser login itself. ## OAuth Refresh The CLI refreshes expired or near-expiry OAuth tokens with the OpenAI OAuth refresh endpoint and writes updates back to the same auth file. The default refresh skew is 5 minutes, matching OpenClaw's OAuth usability margin. When the auth file is OpenClaw's `auth-profiles.json`, refresh uses the same cross-agent lock path OpenClaw uses for `openai-codex` OAuth profiles, then locks the auth store before rereading and writing credentials. It also inherits a fresh matching profile from the main OpenClaw agent store when the current agent/workspace auth store is stale. That prevents concurrent agents from racing on one single-use refresh token and causing `refresh_token_reused`. When auth is auto-discovered and the first auth file is irrecoverably stale, the CLI tries the next compatible auth source, such as `CODEX_HOME/auth.json` or `~/.codex/auth.json`. Explicit `--auth` paths are not bypassed. ```bash node scripts/codex-imagen.mjs --refresh-only --json node scripts/codex-imagen.mjs --force-refresh --smoke --json node scripts/codex-imagen.mjs --no-refresh --prompt 'generate one image' ``` Use `--no-refresh` only when the caller already owns token refresh. For normal standalone/OpenClaw skill usage, leave refresh enabled. ## JSON Output Use `--json` for the full machine-readable summary: ```bash node scripts/codex-imagen.mjs --json 'generate a small blue lotus icon' ``` Generation JSON includes: - `request_id`, `session_id`, `endpoint`, `model` - `image_count` and `imageCount` - `images[].path` and `images[].decodedPath` - `images[].bytes`, `sha256`, `call_id`, `status`, `partial`, `revised_prompt` - `seen_event_types` - `operation`, for example `responses image_generation`, `image generation`, or `image edit` - `response_metadata` for typed Images responses - `timed_out` - `retry_attempts` and `retryAttempts` when a later retry succeeds - `auth_refresh` when refresh happened or was skipped during the run `--smoke --json` prints redacted auth metadata. `--refresh-only --json` prints refresh metadata. ## OpenClaw Usage Use the skill directory as an OpenClaw skill: ```text codex-imagen/ SKILL.md scripts/codex-imagen.mjs ``` OpenClaw callers should usually rely on the active agent auth store and output directory: ```bash node {baseDir}/scripts/codex-imagen.mjs --json --timeout 300 --prompt 'generate an image' ``` `--timeout 300` means 5 minutes and matches OpenClaw's surrounding `exec` tool `timeout` unit. `--timeout-ms 300000` is still accepted for older callers and advanced millisecond use. For prompts that ask for 3 images, prefer `--timeout 600`, or ask for 2 images when the conversation should return quickly. If a multi-image request times out after saving 1 or 2 images, the helper returns those saved paths with `timed_out: true`. By default the helper also retries transient empty failures with `--retries 4`, so a caller that sets a strict outer OpenClaw `exec.timeout` should budget for retry time or pass `--no-retry`. The helper never retries after streaming has saved an image. Timeouts after saved images return the saved paths; broken hosted Responses streams after saved images leave the files on disk but exit with a stream error, matching Codex turn semantics. Use `--cwd ` when another agent launches this script from an unpredictable working directory. ## Cross-Platform Notes The helper is plain Node.js 22+ and uses `os.homedir()`, `path`, and environment overrides instead of platform-specific shell behavior. It should work on macOS, Linux, and Windows. In Windows `cmd.exe`, single quotes are not shell quotes, so use double quotes or `--prompt-file`: ```bat node scripts\codex-imagen.mjs --prompt-file prompt.txt --out-dir out ``` PowerShell accepts normal quoted strings, but for long prompts `--prompt-file` is still safer. ## Exit Codes - `0`: success - `1`: generation failed, no image returned, or HTTP error - `2`: invalid CLI usage - `124`: timed out before any image was saved, or the hard watchdog forced exit after abort did not settle ## Development Run local static checks: ```bash npm run check ``` The CI workflow checks syntax and CLI help/version output. It does not call live image generation because that requires local OAuth credentials. ## License MIT