aruffolo

aso-appstore-screenshots

Create and refine App Store screenshot sets from an app codebase plus existing app screenshots. Use when Codex needs to discover ASO benefit headlines, review and rate supplied screenshots, pair screens to messages, choose colors and typography, compose App Store-ready PNGs, or build a showcase image without Figma or simulator automation.

aruffolo 1 Updated 1mo ago

Resources

7
GitHub

Install

npx skillscat add aruffolo/codex-skill-aso-appstore-screenshots

Install via the SkillsCat registry.

SKILL.md

ASO App Store Screenshots

Work from screenshots the user already has. Do not assume simulator control. Build a deterministic scaffold first, then optionally polish it with any image-generation tool the user explicitly asks to use.

This skill is a Codex adaptation of Adam Lyttle's original Claude skill, claude-skill-aso-appstore-screenshots. Preserve that attribution when redistributing substantial copies or adaptations.

Core Workflow

1. Build product context

Inspect the app codebase, metadata, and any existing marketing copy to answer:

  • What the app does
  • Who it is for
  • Why it is better than alternatives

Ask only the missing market questions. Keep the discussion focused on conversion, not feature inventory.

2. Discover the screenshot messages

Draft 3 to 5 benefit headlines. Each should:

  • start with an action verb
  • describe a user outcome, not an implementation detail
  • map to a screen the user can actually show

Good pattern:

  • TRACK EVERY BOTTLE
  • PLAN PREP AHEAD
  • FOLLOW EVERY TIMELINE

Bad pattern:

  • ADVANCED ANALYTICS
  • MODERN UI
  • POWERFUL FEATURES

Do not move on until the user confirms the headline list and order.

3. Review the provided screenshots

Accept:

  • a directory
  • explicit file paths
  • a glob pattern

Open every candidate screenshot. Rate each one:

  • Great
  • Usable
  • Retake

For every screenshot, say:

  • what it shows
  • what works
  • what does not work
  • the verdict

Check for:

  • empty or low-content states
  • debug UI
  • weak hierarchy at thumbnail size
  • clipped key content
  • inconsistent light/dark mode
  • noisy status bar
  • generic or low-conviction screens like settings, onboarding, or sparse lists when a stronger screen exists

Give blunt retake guidance when needed. The goal is conversion, not coverage.

If any screenshot is Retake, do not hand-wave. Give an explicit retake plan:

  • which screen to capture instead
  • which app state or seeded data to show
  • whether to retake in light or dark mode for consistency
  • what visual clutter to remove
  • what the screenshot must prove at thumbnail size
  • whether simulator capture is recommended to get a cleaner result

When coaching simulator retakes, be concrete:

  • name the exact screen to open
  • name the exact data density to show
  • call out status bar cleanup
  • reject empty states unless the whole app is about empty-state onboarding

Persist retake guidance in appstore-screenshots/state/retake-plan.md when needed.

4. Pair screenshot to headline

For each confirmed headline, pick the best screenshot. Prioritize:

  • direct relevance
  • strong visual density
  • quick comprehension at thumbnail size
  • variety across the set

If a headline has no strong screenshot, say so and stop for retakes instead of forcing a weak pairing.

5. Lock design direction

Before composing, confirm:

  • primary background color
  • optional accent color
  • font choice
  • tone: minimal, premium, energetic, clinical, playful

Defaults:

  • title font: SF Pro Display Black if installed
  • subtitle font: SF Pro Display Black if installed
  • device frame: generated by scripts/generate_frame.py without Dynamic Island by default
  • export size: 1290x2796 unless the user wants a different App Store target

If branding is unclear, propose one primary color plus one fallback and explain which direction converts better.

6. Compose deterministic scaffolds

Use the bundled scripts:

  • scripts/generate_frame.py to regenerate the reusable device frame asset
  • scripts/compose.py to build each screenshot
  • scripts/showcase.py to assemble a quick preview strip

Recommended output structure inside the user project:

appstore-screenshots/
  state/
    benefits.md
    screenshot-review.md
    pairings.md
    design-direction.md
    retake-plan.md
    style-template.md
    polish-decisions.md
  work/
    01-benefit-slug/
      scaffold.png
      v1.png
      v2.png
      v3.png
      v1-resized.png
      v2-resized.png
      v3-resized.png
    02-benefit-slug/
      scaffold.png
  final/
    01-benefit-slug.png
    02-benefit-slug.png
  showcase.png

Always persist state files in the project so work can resume in a later Codex session without rediscovery.

7. Optional polish

If the user explicitly wants AI polish and Gemini MCP or equivalent Gemini-compatible image editing is available, use the scaffold as the source of truth:

  • preserve text hierarchy
  • preserve screenshot content
  • preserve frame placement
  • ask for small visual polish, not a redesign

Never skip the deterministic scaffold. It is the recovery path.

Before running Gemini polish:

  • state clearly that Gemini polish is optional
  • state that Gemini usage may incur API charges
  • confirm deterministic mode remains the fallback if Gemini tooling is unavailable

When the user wants Gemini polish:

  1. Create the deterministic scaffold first.
  2. For the first benefit, generate 3 polished variants from the scaffold.
  3. Crop or resize every polished variant to the final App Store export size before review.
  4. Ask the user to pick a winner.
  5. Save the winning polished slide path and its visual treatment in appstore-screenshots/state/style-template.md.
  6. For later benefits, keep the new scaffold layout and screenshot content, but match the approved visual treatment from the saved style template.
  7. When iterating, generate 3 new variants again unless the user asks for fewer.

Persist Gemini decisions in appstore-screenshots/state/polish-decisions.md:

  • whether Gemini polish was enabled
  • which provider/tooling was available
  • which slide was chosen as the style template
  • any locked visual constraints for later slides

If Gemini tooling is missing, stop at the deterministic scaffold and say exactly what integration is missing.

8. Final review

Before declaring done, check:

  • message order makes narrative sense
  • typography consistent across all slides
  • screenshot crops show the intended feature clearly
  • backgrounds consistent
  • final files open at the requested export size

File Guidance

Load workflow.md when you need the detailed rating rubric, naming rules, or composition checklist.
Load gemini-polish.md when the user explicitly wants AI polish or when you need the detailed Gemini variant workflow.

Commands

Generate or refresh the frame:

python3 ~/.codex/skills/aso-appstore-screenshots/scripts/generate_frame.py

Generate an optional Dynamic Island frame:

python3 ~/.codex/skills/aso-appstore-screenshots/scripts/generate_frame.py --dynamic-island

Compose one screenshot:

python3 ~/.codex/skills/aso-appstore-screenshots/scripts/compose.py \
  --bg "#8C3D1B" \
  --verb "TRACK" \
  --desc "EVERY BOTTLE" \
  --screenshot path/to/screen.png \
  --output appstore-screenshots/work/01-track-every-bottle/scaffold.png

Opt in to a Dynamic Island frame:

python3 ~/.codex/skills/aso-appstore-screenshots/scripts/compose.py \
  --bg "#8C3D1B" \
  --verb "TRACK" \
  --desc "EVERY BOTTLE" \
  --screenshot path/to/screen.png \
  --dynamic-island \
  --output appstore-screenshots/work/01-track-every-bottle/scaffold.png

Create a showcase:

python3 ~/.codex/skills/aso-appstore-screenshots/scripts/showcase.py \
  --screenshots appstore-screenshots/final/01-track-every-bottle.png appstore-screenshots/final/02-plan-ahead.png \
  --output appstore-screenshots/showcase.png

Boundaries

  • Do not invent features that the product cannot show.
  • Do not write generic marketing lines when the screen can support something more specific.
  • Do not force every screenshot to use the same layout if the user asks for variation, but keep one consistent system unless asked otherwise.
  • Do not require Figma. Use code first.
  • Do not imply Gemini polish is free; call out that API charges may apply.
  • Do not run AI polish by default; deterministic scaffolds stay the default path.