Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
258 changes: 169 additions & 89 deletions .claude/commands/setup-screenshots.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,154 @@
---
description: Set up Screenshot Factory in an iOS project — creates UITests, Snapfile, screenshots.json with per-screen design variety, capture scripts, and --screenshot-mode flag
description: Set up Screenshot Factory in an iOS project — interactive wizard that asks ALL questions before making any changes
---

Integrate Screenshot Factory into this iOS project. Follow these steps exactly:
# Screenshot Factory Setup Wizard

## 1. Identify the project
This is a **step-by-step interactive wizard**. It has two phases:

- Find the `.xcodeproj` or `.xcworkspace` file
- Find the main app scheme name
- Find the UITests target (create one if it doesn't exist)
- Detect all supported locales (check `Localizable.xcstrings`, `.strings` files, or `Info.plist` — look for `CFBundleLocalizations`)
- Identify the 5 most important screens for App Store screenshots
- Identify the app's brand colors (primary, accent, background)
- **Phase 1 — Questionnaire** (4 mandatory stops). You gather information and ask the user questions. **DO NOT create, modify, or write ANY files during Phase 1.**
- **Phase 2 — Execution**. You create all files using the answers collected in Phase 1.

## 2. Copy infrastructure files
**CRITICAL RULE: Phase 1 has 4 stops. At each stop you MUST present information to the user and wait for their reply. DO NOT skip any stop. DO NOT continue to the next stop until the user has replied. DO NOT start Phase 2 until all 4 stops are completed.**

Copy these files from the ScreenshotFactory repo (at `https://github.com/iMark21/ScreenshotFactory`):
---

- `Capture/SnapshotHelper.swift` → `{UITests target}/SnapshotHelper.swift`
- `Capture/capture.sh` → `fastlane/capture.sh` (make executable)
- `Capture/pipeline.sh` → `fastlane/pipeline.sh` (make executable)
# ═══════════════════════════════════════════════════
# PHASE 1 — QUESTIONNAIRE (read-only, no file changes)
# ═══════════════════════════════════════════════════

If the files aren't available locally, create them from the repo's content.
## ⛔ STOP 1 of 4 — Prerequisites Check

Run these checks silently, then present the results to the user:

1. **Screenshot Factory CLI**: Run `which screenshot-factory`. Is it installed?
2. **UITests target**: Does the project have a UITests target? (look for `*UITests` directory or target in the `.xcodeproj`)
3. **Fastlane directory**: Does `fastlane/` exist in the project root?
4. **Xcode project**: Find the `.xcodeproj` or `.xcworkspace` and scheme name

Present the results as a checklist:

```
📋 Prerequisites Check

✅ / ❌ screenshot-factory CLI installed
✅ / ❌ UITests target found: {name}
✅ / ❌ fastlane/ directory exists
✅ / ❌ Xcode project: {name} (scheme: {scheme})

{If anything is missing, explain how to fix it}
```

Then ask: **"Everything look correct? Should I fix anything before continuing?"**

**⛔ DO NOT CONTINUE until the user replies.**

---

## ⛔ STOP 2 of 4 — Project Analysis & Screens

Analyze the project (read-only) and detect:

## 2.5 Choose a design template (REQUIRED — STOP and ask the user)
1. **Supported locales**: Check `Localizable.xcstrings`, `.strings` files, or `Info.plist` (`CFBundleLocalizations`)
2. **Brand colors**: Look at `Assets.xcassets` for AccentColor, primary colors, or the app's main color palette
3. **Key screens**: Identify the 5 most important screens for App Store screenshots (home, main feature, detail, settings, etc.)
4. **iPad support**: Check if the app supports iPad (check `Info.plist` or target settings)

**Before generating any config files, STOP completely and ask the user the following question.**
Do NOT choose a template yourself. Do NOT continue to Step 3 until the user has answered.
Present the analysis:

```
📋 Project Analysis

📱 App: {name}
🌍 Detected locales: {list}
🎨 Brand colors: {primary}, {accent}, {background}
📱 iPad support: Yes / No

📸 Proposed screenshots (5 screens):
1. {screen name} — {what it shows}
2. {screen name} — {what it shows}
3. {screen name} — {what it shows}
4. {screen name} — {what it shows}
5. {screen name} — {what it shows}
```

Then ask: **"Are these the right screens? Want to change, add, or remove any? Are the detected locales correct?"**

**⛔ DO NOT CONTINUE until the user replies.**

---
**Which screenshot style fits your app best?**

| # | Template | Look & Feel | Best for |
|---|----------|-------------|----------|
| 1 | `dark-teal-accent` | Dark bg — each screen's hero `{word}` highlighted in a different accent color | Games, social, entertainment |
| 2 | `space-navy` | Deep navy/indigo that shifts hue per screen — atmospheric journey feel | Meditation, lifestyle, health |
| 3 | `obsidian-minimal` | Pure black, crisp white headlines, alternating text above/below | Premium, e-commerce, productivity |
| 4 | `dark-atmospheric` | Moody single dark gradient, no accent words | Atmospheric, immersive apps |
| 5 | `light-clean` | White/gray background, dark charcoal text | Utilities, tools, professional |
| 6 | `vibrant-gradient` | Bold diagonal color gradient (indigo → violet → pink) | Fitness, social, creative |
## ⛔ STOP 3 of 4 — Design Template

Reply with a number (1–6) or a template name.
Present the template options and ask the user to choose:

```
🎨 Choose a screenshot design template:

| # | Template | Look & Feel | Best for |
|----|----------------------|----------------------------------------------------------------|---------------------------------|
| 1 | dark-teal-accent | Dark bg — each screen's hero {word} in a different accent | Games, social, entertainment |
| 2 | space-navy | Deep navy/indigo that shifts hue per screen | Meditation, lifestyle, health |
| 3 | obsidian-minimal | Pure black, crisp white headlines, alternating layout | Premium, e-commerce, productivity|
| 4 | dark-atmospheric | Moody single dark gradient, no accent words | Atmospheric, immersive apps |
| 5 | light-clean | White/gray background, dark charcoal text | Utilities, tools, professional |
| 6 | vibrant-gradient | Bold diagonal color gradient (indigo → violet → pink) | Fitness, social, creative |
```

Ask: **"Which template fits your app? Reply with a number (1–6)."**

**⛔ DO NOT CONTINUE until the user replies with their choice.**

---

Once the user replies, load `Templates/{chosen-template}.json` from the ScreenshotFactory repo as the design base for Step 4.
## ⛔ STOP 4 of 4 — Confirmation Checklist

Present a summary of EVERYTHING that will be created, using the answers from stops 1–3:

```
📋 Setup Summary — Please confirm before I start

I will create the following files in your project:

[ ] SnapshotHelper.swift → {UITests target}/
[ ] capture.sh → fastlane/ (executable)
[ ] pipeline.sh → fastlane/ (executable)
[ ] Snapfile → fastlane/ ({N} devices, {M} languages)
[ ] screenshots.json → fastlane/ (template: "{chosen template}", {N} screens, {M} locales)
[ ] --screenshot-mode handling → {app entry point file}
[ ] ScreenshotTests.swift → {UITests target}/ ({N} snapshots)

Design: {template name}
Devices: iPhone 6.9"{+ iPad 13" if supported}
Languages: {locale list}
Screens: {screen list}
```

## 3. Create fastlane/Snapfile
Ask: **"Ready to proceed? (yes/no)"**

**⛔ DO NOT CREATE ANY FILES until the user confirms.**

---

# ═══════════════════════════════════════════════════
# PHASE 2 — EXECUTION (only after all 4 stops confirmed)
# ═══════════════════════════════════════════════════

**You may only reach this phase after the user has replied to all 4 stops above.**

## Step 1. Copy infrastructure files

Copy these files from the ScreenshotFactory repo (at `https://github.com/iMark21/ScreenshotFactory`):

- `Capture/SnapshotHelper.swift` → `{UITests target}/SnapshotHelper.swift`
- `Capture/capture.sh` → `fastlane/capture.sh` (make executable)
- `Capture/pipeline.sh` → `fastlane/pipeline.sh` (make executable)

If the files aren't available locally, create them from the repo's content.

## Step 2. Create fastlane/Snapfile

Use the project info from Stop 1 and locales from Stop 2:

```ruby
project("{ProjectName}.xcodeproj")
Expand All @@ -62,64 +164,32 @@ launch_arguments(["--screenshot-mode"])
output_directory("./fastlane/screenshots")
```

## 4. Create fastlane/screenshots.json
## Step 3. Create fastlane/screenshots.json

Use the template chosen in Step 2.5 as the design foundation. Then:
Load `Templates/{chosen-template}.json` from the ScreenshotFactory repo as the design base. Then:

- **`outputSizes`**: Copy from template. Add `iPad_13` (2064x2752) if iPad supported
- **`design`**: Copy from template, then adjust brand colors to match the app
- **`screens`**: 5 screens with per-screen `design` overrides to create visual variety
- **`texts`**: Generate benefit-focused copy for **each locale detected in Step 1**, in the native language of that locale — never translate everything to English
- **`outputSizes`**: Copy from template. Add `iPad_13` (2064x2752) if iPad supported (from Stop 2)
- **`design`**: Copy from template, then adjust brand colors to match the app (from Stop 2)
- **`screens`**: Use the screens confirmed in Stop 2 with per-screen `design` overrides for visual variety
- **`texts`**: Generate benefit-focused copy for **each locale confirmed in Stop 2**, in the native language of that locale — never translate everything to English

### Localized texts generation rule
### Localized texts generation rules

For each screen and each detected locale, write:
For each screen and each locale, write:
- `keyword`: 3–5 words max, **benefit-focused** (what the user gains, not what the feature does), in the locale's native language
- `subtitle`: 1 short sentence, supporting context, in the locale's native language

**Spanish locale warning**: `es-ES` is Spain Spanish — use standard tuteo ("Juega", "Ataca", "Debate"). Never use Latin American voseo ("Jugá", "Atacá", "Debatí"). These are different dialects and voseo reads as incorrect to Spain users.
**Spanish locale warning**: `es-ES` is Spain Spanish — use standard tuteo ("Juega", "Ataca", "Debate"). Never use Latin American voseo ("Jugá", "Atacá", "Debatí").

Example for a game with `en-US`, `es-ES`, `de-DE`:
```json
"texts": {
"en-US": { "keyword": "Hunt or be {hunted}", "subtitle": "The village decides your fate" },
"es-ES": { "keyword": "Caza o sé {cazado}", "subtitle": "El pueblo decide tu destino" },
"de-DE": { "keyword": "Jäger oder {Gejagter}", "subtitle": "Das Dorf entscheidet dein Schicksal" }
}
```

### Making screenshots visually varied (important!)

Each screen should have a unique look. Use per-screen `design` overrides:

```json
"screens": [
{
"id": "01-Home",
"rawFile": "iPhone_6.9_01-Home.png",
"texts": { "en-US": { "keyword": "Hunt or be {hunted}", "subtitle": "..." } }
},
{
"id": "02-Feature",
"rawFile": "iPhone_6.9_02-Feature.png",
"design": {
"textColor": { "keyword": "#FFFFFF", "subtitle": "#FFFFFFAA", "keywordAccent": "#FF6B6B" },
"background": { "type": "gradient", "colors": ["#1A0D0D", "#2E0D0D"], "direction": "topToBottom" }
},
"texts": { "en-US": { "keyword": "Strike with {precision}", "subtitle": "..." } }
}
]
```

**Accent word syntax**: wrap any word in `{braces}` to render it in `keywordAccent` color.
### Per-screen variety checklist

**Per-screen variety checklist**:
- Different `keywordAccent` color per screen (teal → blue → orange → purple → pink)
- Slightly shift background darkness or hue per screen
- Alternate between `textAboveDevice` and `textBelowDevice` for some screens
- Each screen's headline highlights a DIFFERENT word representing its unique value
- Use `{word}` accent syntax to highlight the hero concept per screen

## 5. Add --screenshot-mode to the app
## Step 4. Add --screenshot-mode to the app

Find the app's entry point (@main struct or AppDelegate) and add screenshot mode handling:

Expand All @@ -134,9 +204,15 @@ if CommandLine.arguments.contains("--screenshot-mode") {

Create a `ScreenshotData.swift` file in the app target with realistic mock data for each supported language using `String(localized:)`.

## 6. Create the screenshot UITest
## Step 5. Create the screenshot UITest

Create `{UITests target}/{Scheme}UITests.swift`:

Create `{UITests target}/{Scheme}UITests.swift` (class name MUST be `{Scheme}UITests`, method MUST be `testGenerateAppStoreScreenshots` — capture.sh auto-detects this):
- Class name MUST be `{Scheme}UITests`
- Method MUST be `testGenerateAppStoreScreenshots` (capture.sh auto-detects this)
- Use `accessibilityIdentifier` for navigation (NOT text labels — they change with language)
- Add the `tapTab()` helper for iPad floating tab bar compatibility
- Add `sleep(1)` after animations

```swift
final class {Scheme}UITests: XCTestCase {
Expand All @@ -153,32 +229,36 @@ final class {Scheme}UITests: XCTestCase {
func testGenerateAppStoreScreenshots() throws {
app.launch()
sleep(2)
snapshot("01-Home")
// Navigate and snapshot each screen...
snapshot("01-{Screen1}")
// Navigate and snapshot each screen confirmed in Stop 2...
}

private func tapTab(_ app: XCUIApplication, identifier: String) {
let tabButton = app.tabBars.buttons[identifier]
if tabButton.exists && tabButton.isHittable {
tabButton.tap()
return
}
let fallback = app.descendants(matching: .any)[identifier].firstMatch
if fallback.waitForExistence(timeout: 2) {
fallback.tap()
}
}
}
```

- Use `accessibilityIdentifier` for navigation (NOT text labels — they change with language)
- Add the `tapTab()` helper for iPad floating tab bar compatibility
- Add `sleep(1)` after animations
- For game/app state screens: use `--screen=X` launch arg + `--screenshot-mode` to inject mock state

## 7. Verify
## Step 6. Verify setup

- Ensure `screenshot-factory` CLI is installed (`which screenshot-factory`, or build from repo)
- Create `fastlane/screenshots/` and `fastlane/screenshots_framed/` directories
- Test framing: `screenshot-factory --config fastlane/screenshots.json --input fastlane/screenshots/ --output fastlane/screenshots_framed/`
- Run full pipeline: `./fastlane/pipeline.sh`
- Test framing only: `screenshot-factory --config fastlane/screenshots.json --input fastlane/screenshots/ --output fastlane/screenshots_framed/`
- Full pipeline: `./fastlane/pipeline.sh`

## Important rules

- Screenshot text: write BENEFITS, not features ("Perfect Messages" not "AI Generator")
- Each locale's text MUST be in that locale's native language — never English everywhere
- Keyword: 3–5 words maximum. Subtitle: 1 short sentence
- Use `{word}` accent syntax to highlight the hero concept per screen
- Give each screen a different `keywordAccent` color — visual monotony kills conversions
- `accessibilityIdentifier` on all tappable elements used in the test
- Class name must be `{Scheme}UITests`, method `testGenerateAppStoreScreenshots` (auto-detected by capture.sh)
- Raw and framed screenshots in SEPARATE directories (never the same)
- Each device class needs its own raw captures (never reuse iPhone screenshots for iPad)
Loading