# Social Image

> Generate a concept illustration for a social post (X, LinkedIn, Bluesky) with gpt-image-2 in the Argos dark-indigo house style, using scripts/social-image.mjs. Use when a post needs an abstract image rather than a code snippet.

- Skill: `argos-ci/social-image` (Agent Skill)
- Install (CLI): `npx skillmds@latest add argos-ci/social-image`
- Raw SKILL.md: https://api.skillmd.com/api/skills/argos-ci/social-image/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: argos-ci (https://skillmd.com/u/argos-ci)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/argos-ci/social-image

---


# Social concept illustrations

Social posts carry one of two image types. This skill covers the abstract one:
a flat editorial vector scene on deep indigo, violet and cyan. Every image is
generated by `scripts/social-image.mjs`, which appends one locked style string —
that string, not the individual prompt, is what makes a set look like a set.

- **This skill** — the idea is abstract: a workflow, a tradeoff, scale, a bottleneck.
- **`code-card`** — the snippet _is_ the message. Always prefer it for commands and config.
- **`changelog-image`** — changelog entries only. Different system entirely: pastel
  gradient background via the `images/edits` endpoint. Never mix the two looks.

## Inputs

- **Script**: `scripts/social-image.mjs`. No dependencies beyond Node.
- **API key**: `ARGOS_OPENAI_API_KEY`, in `~/.zshrc`. Run `source ~/.zshrc` if it is not already in the environment.
- **Output**: 1536×1024 (3:2) PNG — reads well in every feed and crops safely.
- **Cost**: roughly $0.10–0.15 per image. A 40-image set is a few dollars, so batch deliberately and never regenerate a set casually.
- **Destination**: a scratch directory. Social assets — do **not** commit them.

### Blog headers

The same style, a different frame. Blog headers render at `aspectRatio: 2/1` with
`object-fit: cover` in both the article (`MainImage`) and the post grid
(`PostCardImage`), so a 3:2 image loses a quarter of its height to the crop.
Generate those at 2:1 instead — `--size 2048x1024`, or `"size"` in the spec:

```bash
node scripts/social-image.mjs --spec /tmp/blog.json --size 2048x1024
```

2048 is wide enough for the full-width featured card (1100 CSS px) at ~1.9× DPR
and lands exactly on a Next.js `deviceSizes` breakpoint. These images _are_
committed, next to their article as `main.jpg` — convert the PNG before landing
it, and drop the article's photo credit so `<MainImage />` renders bare.

## Steps

### A batch (preferred)

```json
{
  "images": [
    {
      "name": "AI1",
      "scene": "A very wide fast pipe on the left carrying many stacked rectangular blocks, narrowing sharply into a thin bottleneck channel on the right where the blocks queue up and pile."
    },
    {
      "name": "POV4",
      "scene": "Two side-by-side panels, each with a circular tolerance dial. The left dial is set coarse with a wide fuzzy ring; the right dial is set fine with a tight precise ring."
    }
  ]
}
```

```bash
source ~/.zshrc
node scripts/social-image.mjs --spec /tmp/images.json --out-dir /tmp/img
```

Runs 4 at a time, retries once, and **skips any image already on disk** — so a
re-run only fills gaps. Pass `--force true` to regenerate deliberately.

### One image

```bash
node scripts/social-image.mjs --scene "A closed circular loop of three stations…" --out /tmp/a.png
```

### Always review every image

Read each PNG back. Reject and rewrite the scene if: the concept isn't legible
in two seconds, any letterform crept in, the composition is cropped, or the
model latched onto the wrong meaning of a word.

## Writing a scene

The style string handles all the styling. A scene should describe **only the
composition** — shapes, quantities, spatial relationships, what's emphasised.

- **Describe geometry, not metaphor.** "A wide pipe narrowing into a thin channel
  where blocks queue" works. "The bottleneck of AI code review" produces mush.
- **Be literal about idioms.** "Below the fold" rendered a _folding phone_. Say
  "a horizontal dashed line two thirds down the screen, with the button below it
  greyed out". Any phrase with a second meaning will find that meaning.
- **Name the emphasis.** Say which element is bright, enlarged, or highlighted —
  otherwise everything gets equal weight and the point disappears.
- **Give counts.** "Three ascending blocks", "a three by two grid, five dimmed and
  one bright". Vague quantities produce vague images.
- **Never ask for text**, and don't try to sneak in a number or label — the style
  string forbids it because the model garbles letterforms. If the image needs
  words, it wants a `code-card` instead.
- **Reuse the established vocabulary** so a set coheres: browser windows and
  panels as rounded rectangles, agents as angular modules, screenshots as tiles,
  measurement brackets for precision, concentric rings and dot-grids as texture.

## Changing the look

Edit `STYLE` in `scripts/social-image.mjs`, then regenerate **the whole set** and
re-attach the images. A half-migrated set is worse than the old look — that
inconsistency is exactly what this script exists to prevent.

