create-image-fal
Generate or edit an image via any FAL image model (nano-banana edit, gpt-image, flux, ...), ROUTED THROUGH THE fal-proxy so it bills the Ads agent. image_urls…
Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.
$ npx -y skills add gooseworks-ai/goose-skills --skill create-imessage-mockup --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/create-imessage-mockupContext preview
The summary Claude sees to decide when to auto-load this skill.
Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.
name: create-imessage-mockup description: Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.
Generate iMessage screenshots that look like real iOS captures — correct bubbles with tails, typing indicators, timestamps, "Delivered" captions, group avatars + sender names, keyboard chrome, and an optional iPhone 15 Pro bezel with Dynamic Island and status bar.
Turn a structured thread JSON into a believable iMessage screenshot — first as standalone HTML (`generate.js` + `templates/chat.css`), then rasterized to PNG with headless Chromium (`screenshot.js`/`render.js` via Playwright). It is the atom you reach for when an ad, social post, or video scene needs a fake-but-convincing iOS message capture.
What it gets right, grounded in the renderer:
The atom embeds **no LLM** — it is deterministic. The orchestrating agent is responsible for composing the thread JSON; the renderer only draws exactly what the JSON says.
If you're rendering programmatic graphic frames more broadly (cards, posters, infographics), use `create-goose-graphics` instead.
The skill is deterministic — it does not embed an LLM. To translate a free-form prompt into a thread, the orchestrating agent (you) composes a JSON file matching the schema below, then invokes the renderer.
{
"mode": "dm" | "group",
"title": "Karaoke Crew",
"participants": [
{ "id": "me", "name": "Me", "self": true },
{ "id": "sarah", "name": "Sarah", "color": "#FF9500", "initials": "S" }
],
"messages": [
{ "type": "timestamp", "label": "iMessage\nToday 9:41 AM" },
{ "type": "timestamp", "bold": "Sat, Jan 2", "light": "11:07" },
{ "type": "text", "from": "sarah", "text": "Did we crash it?" },
{ "type": "text", "from": "me", "text": "Couldn't withstand our friendship", "delivered": true, "read": false },
{ "type": "typing", "from": "sarah" }
],
"keyboard": { "leftIcon": "plus" }
}node render.js --thread examples/group-with-frame.json --with-iphone-frame node render.js --thread examples/dm-with-keyboard.json --with-keyboard node render.js --thread examples/dm-minimal.json --minimal node render.js --thread my-thread.json --with-keyboard --output ./my-exports/ --name nightout
| Flag | Effect | |---|---| | `--thread <path>` | (required) JSON file matching the schema above | | `--prompt "<brief>"` | prints the schema and exits — agent must compose a thread.json and re-invoke | | `--minimal` | bubbles + timestamps only (no header, no keyboard, no frame) | | `--with-keyboard` | bubbles + iOS keyboard chrome (default) | | `--with-iphone-frame` | full iPhone 15 Pro bezel + Dynamic Island + status bar + soft gradient backdrop | | `--dm` / `--group` | force chat mode (otherwise auto-detected from participants) | | `--name <slug>` | override the output folder slug | | `--output <dir>` | parent dir for the dated output folder; default `./imessage-mockup-exports/` |
Frame flags are mutually exclusive.
<output>/<YYYY-MM-DD>-<slug>/ index.html # full standalone HTML screenshot.png # rendered PNG (DPR 3, "Retina") thread.json # copy of the input for reproducibility
Default `<output>` is `./imessage-mockup-exports/` in the cwd.
1. Receive a prompt or existing thread JSON. 2. If only a prompt was given: compose a thread.json matching the schema, save it. 3. Run `node render.js --thread <path> [flag]`. 4. Open the resulting PNG to verify the layout. If something looks wrong (clipping, wrong tail side, missing avatar), edit the thread JSON or the relevant template under `templates/` and re-render.
cd skills/ads/capabilities/create-imessage-mockup npm install npx playwright install chromium
| File | Purpose | |---|---| | `render.js` | CLI entry —
Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.
Repo: gooseworks-ai/goose-skills
Generate or edit an image via any FAL image model (nano-banana edit, gpt-image, flux, ...), ROUTED THROUGH THE fal-proxy so it bills the Ads agent. image_urls…
Generate a single photoreal or designed image with OpenAI gpt-image via fal.ai. Supports gpt-image-1 (default, fixed sizes — the FAL fallback for Higgsfield's…
Generate an instrumental music bed via ElevenLabs Music, ROUTED THROUGH THE elevenlabs-proxy so it bills the Ads agent. Trims any sparse intro, loudnorm, fades…
Image-to-video (or text-to-video) via any FAL video model (Kling, Seedance, Veo), ROUTED THROUGH THE GooseWorks fal-proxy so the call bills the Ads agent. The…
Generate a voiceover (VO) clip via ElevenLabs text-to-speech, ROUTED THROUGH THE elevenlabs-proxy so it bills the Ads agent. Voice id + script text come from…
Scrape competitor ads from Google Ads by domain. Returns ad creatives, formats, and campaign details. Use for competitive ad research and messaging analysis.