Skip to content
Development
Skill

/ui-crawler-max

Autonomous UI crawler for iOS simulator apps — rapid, element-precise data collection. Use whenever the user says "crawl my app", "auto-test the UI", "click/tap through every screen", "monkey test", "explore the app and find errors/crashes", "collect screenshots of all screens",

From plugin
swift-tothemax
78 skills
Install
$ npx -y skills add Dev869/swift-tothemax --skill ui-crawler-max --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ui-crawler-max

Context preview

The summary Claude sees to decide when to auto-load this skill.

Autonomous UI crawler for iOS simulator apps — rapid, element-precise data collection. Use whenever the user says "crawl my app", "auto-test the UI", "click/tap through every screen", "monkey test", "explore the app and find errors/crashes", "collect screenshots of all screens",

SKILL.md

ui-crawler-max.SKILL.md
name: ui-crawler-max
description: >-
  Autonomous UI crawler for iOS simulator apps — rapid, element-precise data collection.
  Use whenever the user says "crawl my app", "auto-test the UI", "click/tap through every
  screen", "monkey test", "explore the app and find errors/crashes", "collect screenshots
  of all screens", "smoke test the whole app", or asks for any app QA sweep, crash hunt,
  or screen inventory. It taps every reachable button/cell/switch via XCUITest,
  screenshots and journals every screen, detects crashes AS THEY HAPPEN with repro steps,
  streams console errors, and fans out cheap parallel Haiku subagents to label the haul.
  Data collection only — route fixes to swiftui-max/swift-language afterwards. Trigger
  even for a vague "is anything in my app broken?" — a crawl answers it empirically.

UI Crawler Max

Crawl an iOS app in the simulator like a tireless QA intern: tap everything reachable, record everything seen, never judge. This skill **collects data**; siblings analyze it (`swiftui-max` for UI fixes, `swift-language` for crashes/concurrency, `apple-hig-ux` for design verdicts). Environment: Xcode 26.6, iOS 26.5 simulators (`iPhone 17 Pro` present), `xcodegen` installed. No `idb`, no `cliclick` needed — the crawler runs *inside* the app process via XCUITest, so every tap is element-precise (`element.tap()`), never screen-coordinate guessing.

Architecture (4 moving parts)

1. **`scripts/UICrawlerTests.swift`** — a complete, compile-verified XCUITest that greedy-DFS explores the app: screen signature = FNV-1a hash of visible element identifiers+labels+ frames (rounded to 10pt buckets); global visited-set of `(screen, element)` keys; taps unvisited buttons/cells/switches/segmented controls (tab-bar/nav/back buttons are `.button` descendants, covered); `swipeUp` up to 3× per screen to reveal more; back-nav ladder: nav back button → Done/Close/Cancel/Dismiss → edge swipe → relaunch. 2. **`scripts/crawl.sh`** — boots the sim, starts a console **error log stream before the run**, invokes `xcodebuild test`, harvests `.ips` crash reports afterwards, prints the artifact tree. 3. **Journal + screenshots** — JSON-lines journal per step, PNG + accessibility-hierarchy dump per *new* screen. After every single tap the crawler asserts `app.state == .runningForeground`; on crash it writes a repro record (last 10 steps), relaunches, marks the crashing element visited (**never tapped twice**), and continues. 4. **Haiku labeling fan-out** — after the run, parallel `model: haiku` subagents label batches of ~10 screens using `scripts/haiku-analysis-prompt.md`. Fast, factual, no fixes.

Prerequisite: a UI-testing target

XCUITest needs a `bundle.ui-testing` target. Check: `xcodebuild -list -project App.xcodeproj` — if no `*UITests` target exists and the project uses xcodegen, add one and regenerate:

# project.yml (minimal app + UI test bundle)
name: MyApp
options: { bundleIdPrefix: com.example }
targets:
  MyApp:
    type: application
    platform: iOS
    deploymentTarget: "17.0"
    sources: [MyApp]
  MyAppUITests:
    type: bundle.ui-testing
    platform: iOS
    sources: [MyAppUITests]          # put UICrawlerTests.swift in this folder
    dependencies:
      - target: MyApp                # sets TEST_TARGET_NAME → XCUIApplication() targets MyApp
schemes:
  MyApp:
    build: { targets: { MyApp: all } }
    test:  { targets: [MyAppUITests] }

Then: `mkdir -p MyAppUITests && cp <skill>/scripts/UICrawlerTests.swift MyAppUITests/ && xcodegen generate`. For non-xcodegen projects, add the target in Xcode (File → New → Target → UI Testing Bundle) or route to `apple-dev-conductor` for project surgery. The template is warning-free in both Swift 5 and Swift 6 language modes.

Run workflow

SKILL=<path-to-this-skill>
bash "$SKILL/scripts/crawl.sh" ~/Projects/MyApp MyApp "iPhone 17 Pro"

Knobs (env vars on `crawl.sh`):

| Var | Default | Meaning | |---|---|---| | `CRAWL_MAX_STEPS` | 150 | hard step budget | | `CRAWL_MAX_MINUTES` | 5 | hard time budget | | `CRAWL_DENYLIST` | see Safety | comma-separated destructive labels, substring match | | `CRAWL_ARTIFACTS` | `<proj>/crawl-artifacts/<ts>` | output dir | | `UITEST_TARGET` | `<SCHEME>UITests` | UI test bundle name | | `APP_NAME` | scheme name | process name for log predicate + crash matching |

**Env into the test runner — the #1 footgun.** Vars reach the runner only via xcodebuild's *environment* with the `TEST_RUNNER_` prefix (stripped on delivery; verified in `man xcodebuild`):

# WRONG — sets a build setting; the test process never sees it
xcodebuild test -scheme MyApp CRAWL_MAX_STEPS=300

# RIGHT — environment variable with TEST_RUNNER_ prefix
env TEST_RUNNER_CRAWL_MAX_STEPS=300 xcodebuild test -scheme MyApp ...

`crawl.sh` does this for you — prefer it over hand-rolled xcodebuild. It also starts `xcrun simctl spawn <udid> log stream --level error --style compact --predicate 'processImagePath CONTAINS[c] "<AppName>"' > "$ART/console-errors.log" &` **before** `xcodebuild test` (a stream started after misses launch-time errors), kills it after, and copies new `.ips` files from `~/Library/Logs/DiagnosticReports` created since run start.

The crawler exports `CRAWL_MODE=1` into the app's launch environment — the app may check it to load fixture data or skip onboarding.

Output artifact contract

crawl-artifacts/<timestamp>/
├── journal.jsonl            # per step: {step, screenSignature, action, elementLabel,
│                            #   elementType, timestamp, result}
│                            # actions: newScreen|tap|scroll|back|skipDenied|dismissAlert|
│                            #   leftApp|crashDetected|relaunch|done
├── screens/<sig>.png        # first screenshot of each unique screen
├── screens/<sig>.txt        # accessibility hierarchy (app.debugDescription)
├── crash-<step>.json        # {crashDetected, step, lastAction, time
Read more
Ships withswift-tothemax

A Claude Code plugin covering every facet of Swift and Apple-platform development, current to mid-2026 (Swift 6.3 stable / 6.4 beta, Xcode 26.6, iOS 27 beta).

Get the whole plugin
Stats
7
Stars
0
Forks
Maintained
Maintenance
Swift
Language
MIT
License
2mo ago
Last commit
2mo ago
Created

Repo: Dev869/swift-tothemax

Other skills on swift-tothemax.