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 the Google Gemini API (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
hero_image_url+hero_image_alt
Requirements
- •
CODEX_BHART_API_TOKEN(for Bhart Blog Automation API) - •
GEMINI_API_KEY(for Google Gemini API) - •Python with
google-genaiinstalled
Bhart API note
This skill uses a Codex API media helper endpoint:
- •
POST /api/codex/v1/media/import- •Downloads
source_url(must be an image) into theMEDIA_BUCKETR2 bucket - •Creates a
media_assetsrow in D1 - •Returns
{ media: { id, key, url, ... } }whereurlis a site-local/media/<key>URL
- •Downloads
- •
POST /api/codex/v1/media/upload- •Accepts a multipart form upload (
imagefile) - •Stores directly in
MEDIA_BUCKET - •Creates a
media_assetsrow in D1
- •Accepts a multipart form upload (
Recommended workflow
- •Identify the post:
- •
GET /posts/by-slug/:slug(preferred) orGET /posts/:id
- •
- •Generate alt text:
- •Keep it short, descriptive, and literal (what the image shows), not marketing copy.
- •Generate the image on Gemini (Nano Banana Pro):
- •Prefer passing the logo as an input image if it helps anchor the composition.
- •Import into R2:
- •Call
POST /media/uploadwithimage,alt_text, and the post author fields.
- •Call
- •Update the post hero fields:
- •
PATCH /posts/:idwithhero_image_url,hero_image_alt, andexpected_updated_at.
- •
Script (preferred)
Run:
bash .codex/skills/generate-header-image/scripts/generate_header_image.sh --slug <post-slug> --prompt-file <prompt.txt> --logo-url <https://.../logo.png>
Notes:
- •Default model is
gemini-3-pro-image-preview(Nano Banana Pro). - •Default aspect ratio is
16:9(header-friendly); override via--aspect-ratio. - •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.