ScreenShotComposer

AI workflow

Tips for using sscc with AI.

The CLI was designed for agent loops first and humans second. These are the patterns that work, the failure modes that don’t, and the small disciplines that keep the agent from looping on broken bundles.

#01

Always install the create-screenshot-file skill before you start

The skill is a 12-step workflow with three editorial gates that fire beforeany composition is built. Without it, agents tend to jump from “the user wants screenshots” straight to sscc new, which produces bland, generic listings. With it, the agent enumerates visual ingredients panel-by-panel, gets your approval on the plan, then scaffolds.

Install the skill →
#02

Make the agent read the live catalog before it freehand-types any id

The four sscc catalog commands (templates, bezels, presets, fonts) return the canonical ids the rest of the CLI accepts. Agents that skip this step hallucinate bezel names like “iphone-15-pro” (the real id is iphone-17-pro-deep-blue-portrait).

bash
# In the agent's first scaffold pass:
sscc catalog bezels  --json > .sscc/bezels.json
sscc catalog presets --json > .sscc/presets.json
sscc catalog fonts   --json > .sscc/fonts.json

# Then have the agent grep these files for valid ids
# instead of inventing them.
#03

Capture every UUID at create-time

Every mutating command takes --id <uuid>. Agents that don’t capture --emit-id output spend the next ten tool calls re-discovering UUIDs via sscc show. Persist them in a scaffold file:

bash
# Map every (platform, panel) → composition UUID once,
# in a file the agent can re-read between turns.
declare -A IDS
for plat in mac iphone ipad; do
  for n in 01 02 03 04 05; do
    IDS[$plat-$n]=$(sscc composition add MyApp.screenshot \
      --platform $plat --title "$n" --emit-id)
  done
done

printf '%s\n' "${!IDS[@]}" "${IDS[@]}" \
  | jq -Rsn '[inputs] | _nwise(2) | { (.[0]): .[1] }' \
  | jq -s add > DraftTemplates/<slug>/ids.json
#04

Verify before you render

sscc validate proves the file is well-formed JSON. It does not prove the bundle will render correctly: a headline can fit the JSON schema and still clip past its frame, a background can be silently dropped, an asset can be referenced but missing.

The create-screenshot-file skill ships a verify.sh script that runs three classes of jq checks before you spend render time. Wire it into the agent’s loop:

bash
# After every batch of mutations, BEFORE sscc export.
bash .cursor/skills/create-screenshot-file/references/verify.sh \
  DraftTemplates/<slug>

# Exit code is 0 when:
#  - every composition has its background image attached
#  - no headline's font-size × line-count × 1.2 exceeds its frame height
#  - no plan-side PNG is missing from the bundle
#
# Re-render only after this exits 0.
#05

Read the audit PNGs the agent renders

Agents that skip the visual audit ship listings with width-wrapped headlines, font fallbacks, and decorative assets in the wrong z-order. The agent should always:

  1. rm -rf audit/ && sscc export --output audit/ (clean folder — stale PNGs lie).
  2. Open at least one PNG per platform.
  3. Count the lines in every rendered headline against the design plan. If the plan said 2 lines and the PNG shows 3, the frame is too narrow at the chosen font size — narrow the typography and re-render.
  4. Confirm every decorative asset, every device bezel, and every wallpaper the plan called for is visibly present.
#06

Use --json everywhere; parse the envelope

Every command supports --json and returns a stable envelope. Parse the envelope, never the human text. The agent should also surface data.warnings[] — a FONT_FALLBACK warning means the PNG shipped with the wrong typeface.

bash
OUT=$(sscc layer add text MyApp.screenshot \
  --composition "$COMP" --content "Hello" \
  --frame 100,100,800,200 --emit-id --json)

if [ "$(jq -r '.ok' <<<"$OUT")" != "true" ]; then
  echo "Failed: $(jq -r '.error.message' <<<"$OUT")"
  exit 1
fi

LAYER_ID=$(jq -r '.data.id' <<<"$OUT")
jq -r '.warnings[]?.message' <<<"$OUT"
#07

Plan ambitiously; let the CLI's primitives realize it

When the agent drafts a design plan, it should describe what it actually wants— not what’s easy to scaffold, not what the catalog already ships with. “Hand-drawn coral arrow pointing from headline to device screen, ~-10° rotation” is a valid plan ingredient. The realization step (image generation + adding a non-bezel image layer) handles it.

Constraint thinking belongs afterthe plan, not during it. The agent should never silently drop a planned ingredient because it “can’t do arrows” — it can.

#08

Keep work in DraftTemplates/<slug>/ — never tmp/

The skill convention is to keep every in-progress listing under DraftTemplates/<slug>/ at the repo root, with this shape:

bash
DraftTemplates/<slug>/
├── README.md                     # status + intent
├── design-plan.md                # the per-panel ingredient plan
├── refs/                         # reference screenshots (input)
├── assets/                       # generated backgrounds, decorations
├── captures/<platform>/          # placeholder captures, swapped later
├── scaffold.sh                   # idempotent rebuild from the plan
├── <ListingName>.screenshot/     # the saved bundle
└── audit/                        # freshly rendered PNGs

tmp/ is gitignored and used only by the template-author skill for downloaded App Store screenshots. Putting the design plan there means it disappears between sessions.

#09

Address by UUID, never by title

Every composition and layer has a stable UUID. Titles are display-only and can collide. Agents that match by title occasionally edit the wrong composition once two panels share an “Hero” title.

#10

Render narrow during iteration; render wide for final

Re-rendering the whole listing for a one-panel fix is slow. --composition takes a UUID and is repeatable:

bash
# Tightened the Mac hero headline. Re-render that panel only.
sscc layer set MyApp.screenshot --id "$MAC_HERO_HEADLINE" \
  --content "Your day,\non one screen."

sscc export MyApp.screenshot --output audit/ \
  --composition "$MAC_HERO_COMP" --opaque --overwrite

Anti-patterns

The fastest way to ship a broken listing.

  • Skipping the design plan and going straight to sscc new. Generic, lifeless listings. The plan is the cheapest place to iterate.
  • Hallucinating bezel ids or font names. Always read sscc catalog bezels --json and sscc catalog fonts --json first.
  • Calling sscc layer add background --source. It's silently dropped. Use sscc layer set --source on the auto-created bg layer instead.
  • Trusting sscc validate alone. It only checks JSON shape. Run the verify.sh script from the create-screenshot-file skill before rendering.
  • Telling the user 'opened it for you' without sampling the audit PNGs. The agent must read at least one rendered PNG per platform — that's the only way to catch font fallbacks, width-induced wrap, and decoration-z-order bugs.
  • Letting the agent rebuild the entire bundle for a one-panel fix. sscc export --composition <uuid> renders just the panel you edited.
  • Using <br/> for line breaks in --content. Renders as literal characters. Use \n inside double-quoted bash strings.
  • Passing --opaque on a bundle that has transparent decorations. Renders the alpha regions as a gray checkerboard. Drop --opaque for those bundles.

Ready to wire it up?

Install the skills, point your agent at the CLI reference, and tell it “design a 6-panel listing for <your app>.”