SKILL.md
Generate Header Image
Use this skill when the user wants to create or replace an existing post's header/hero image.
This workflow:
- generates an image with Replicate (default model: Nano Banana Pro)
- uploads the generated image directly into the bhart.org R2 media bucket (so it is served from
/media/...) - updates the target post's
heroimageurl+heroimagealt
Requirements
CODEXBHARTAPI_TOKEN(for Bhart Blog Automation API)REPLICATEAPITOKEN(for Replicate API)- Python 3
Bhart API note
This skill uses a Codex API media helper endpoint:
POST /api/codex/v1/media/import
- Downloads sourceurl (must be an image) into the MEDIABUCKET R2 bucket - Creates a media_assets row in D1 - Returns { media: { id, key, url, ... } } where url is a site-local /media/<key> URL
POST /api/codex/v1/media/upload
- Accepts a multipart form upload (image file) - Stores directly in MEDIABUCKET - Creates a mediaassets row in D1
Recommended workflow
- Identify the post:
- GET /posts/by-slug/:slug (preferred) or GET /posts/:id
- Generate alt text:
- Keep it short, descriptive, and literal (what the image shows), not marketing copy.
- Generate the image on Replicate (Nano Banana Pro):
- Prefer passing the logo as an input image if it helps anchor the composition.
- Import into R2:
- Call POST /media/upload with image, alt_text, and the post author fields.
- Update the post hero fields:
- PATCH /posts/:id with heroimageurl, heroimagealt, and expectedupdatedat.
Script (preferred)
Run:
bash .codex/skills/generate-header-image/scripts/generateheaderimage.sh --slug <post-slug> --prompt-file <prompt.txt> --logo-url <https://.../logo.png>
Notes:
- Default model is
google/nano-banana-pro(Nano Banana Pro). If it fails and default is used, script falls back toblack-forest-labs/flux-1.1-pro. - Default aspect ratio is
16:9(header-friendly); override via--aspect-ratio. - Default resolution is
2K; override via--resolution. - Default upload mode is
direct(multipart upload to/media/upload). Use--upload-mode importto import from a URL or--upload-mode skipto stop after generating the image. - The script prefers
~/scripts/.venv/bin/pythonif available; otherwise it falls back topython3.