- name
- social-image
- description
- 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.
# 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.
Ver no GitHub