Verify UI *workflow* correctness that a task list, code review, and static screenshots miss. Drives end-to-end user flows in the Simulator via XCUITest with per-step screenshots, statically audits the navigation graph for dead-ends and missing edit paths, and emits a human discoverability checklist. Use after building any phase/slice that adds or changes UI, or when a user reports "I could only figure out the flow by running it.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill flow-walkthrough
Task lists, compilers, and code review verify that *screens exist and compile*. They are structurally blind to whether the flow between screens actually works for a human with a goal — the transitions, the return paths, the dead-ends, the discoverability. This skill closes that gap.
Real UX bugs fail at three different layers, and no single mechanism catches all three — so this skill uses three:
| Failure class | Example | Caught by |
|---|---|---|
| Dead-end / missing path | A saved record can only be *viewed*, never reopened to edit; Done calls popToRoot() and orphans an in-progress entity | Layer 1 — static nav-graph audit (no build) |
| Reachability regression | "Run round" no longer reaches the capture screen after a refactor; a Done lands on the wrong screen | Layer 2 — automated flow driving (XCUITest) |
| Discoverability | "How do I even select a contestant?" — the only affordance is a bare row tap | Layer 3 — human checklist (a UI test taps the row and *passes*) |
> The trap: a UI test happily taps a hidden control and reports PASS. Automation proves a path *works*; only a human judges whether it is *findable*. That residue is why Layer 3 is mandatory, not optional.
<flows> from PLAN.md/apple:plan emits a <flows> block — end-to-end journeys, each a testable script. If PLAN.md has no <flows>, derive them from the phase's <mvp-features>/views and write them back into PLAN.md first (a flow that isn't written down can't be checked). A good flow names, for every persisted entity created: the step that reopens it editable, and the single least-discoverable action.
Grep the navigation surface and reason over it. Do this first; it's free and catches the highest-severity class.
Grep: NavigationStack, navigationDestination, NavigationLink, \.sheet, \.fullScreenCover, router.push, enum Route, dismiss(), popToRoot, @Query.Done/Back/dismiss land somewhere intentional? Flag any popToRoot() that discards an in-progress or just-saved entity.@Model with a Create path, is there a Read *and* an Update/reopen path from the persistence surface (a list/history)? A list that only opens a read-only detail is a dead-end for editing — flag it.NavigationLink/navigationDestination destination, check whether the destination view declares its own NavigationView/NavigationStack — a pushed view must never wrap one. This renders a second nav bar under the parent's and its leading bar items displace the back button. It's a cross-file bug: each file looks correct alone (and previews fine in isolation), so single-file review never catches it — only this pairwise check does.Output each finding as DEAD-END / NO-EDIT-PATH / ORPHANS-ENTITY / NESTED-NAV with the file:line and the missing arrow.
Turn each <flow> into a UI test that taps through it and screenshots every step, so the agent can *see* the transitions and assert the destinations.
type: bundle.ui-testing target; or xcodebuild). Keep the generated tests — they become the Phase 5 regression suite.<steps>. After each step, attach a screenshot: func snap(_ name: String) {
let s = XCTAttachment(screenshot: XCUIScreen.main.screenshot())
s.name = name; s.lifetime = .keepAlways; add(s)
}
Launch with any needed args (e.g. a -uiTestSeed launch argument that seeds SwiftData and, in DEBUG, flips entitlement flags so gated flows are reachable without a real purchase). Assert the destination of each step (XCTAssert(app.staticTexts["Results"].waitForExistence(timeout: 2))), especially after Done/Back — that is what catches wrong-destination bugs.
xcodebuild test -project <App>.xcodeproj -scheme <App> \
-destination 'platform=iOS Simulator,name=<device>' \
-resultBundlePath .planning/walkthrough/<flowId>.xcresult
# export per-step screenshots for the agent to read:
xcrun xcresulttool export attachments \
--path .planning/walkthrough/<flowId>.xcresult \
--output-path .planning/walkthrough/<flowId>/ # adapt flag to installed Xcode
(The xcresulttool attachment-export subcommand name shifts across Xcode versions — check xcrun xcresulttool --help and adapt.)
For each flow, emit a short script the human runs and rates — this is the only thing that catches "I couldn't find how to do X":
Flow F1 — Run a contest (as a host)
1. Tap "Start a Contest" → were you sure what to tap? (1–5)
2. Add two contestants → was adding the *second* obvious? (1–5)
3. Run each contestant's round → did you know rows were tappable? (1–5)
4. Done on results → did you land back where you expected? (Y/N)
Where did you hesitate? ______
Keep it to the 2–4 flows that matter; ask for a hesitation note, not just scores — the note is where the real bug hides.
.planning/WALKTHROUGH.md# Flow Walkthrough — Phase [N]
## Layer 1 — Navigation graph (static)
- 🔴 NO-EDIT-PATH: ContestHistoryView:19 opens read-only ResultsView; a saved Contest can't be reopened to edit. → route to editable setup.
- 🔴 ORPHANS-ENTITY: ResultsView "Done" calls router.popToRoot() → dumps user home, loses the contest. → dismiss() one level.
## Layer 2 — Driven flows (filmstrips in ./walkthrough/)
| Flow | Result | Note |
|------|--------|------|
| F1 create→run→results→reopen | ❌ DEAD-END at step 6 | reopen lands on read-only results |
| F2 add second contestant | ✅ reaches capture | |
## Layer 3 — Human discoverability checklist
[the per-flow scripts above, for the user to fill in]
## Verdict
[N] dead-ends (fix before phase-complete), [N] reachability failures, discoverability pending human pass.
Store screenshots under .planning/walkthrough/<flowId>/. Fix all Layer-1 dead-ends and Layer-2 failures before the phase is marked complete (same gate discipline as visual-qa).
-uiTestSeed path (insert sample models, set entitlement flags) so reopen/edit/results flows are reachable without manually rebuilding state each run. Remove or guard it behind the launch arg so it never affects release.visual-qa (which is static/code-level: colors, touch targets, view states). This skill is about *flow*, that one is about *screens*.testing/tdd-feature/test-spec rather than re-writing./apple:review gains a flow/dead-end agent, Layer 1 can run there too; this skill is the runnable, screenshot-producing counterpart.
Control Cursor AI code editor via CLI. Open files, folders, diffs, and manage extensions.
Comprehensive checklist for conducting thorough code reviews covering functionality, security, performance, and maintainability
Systematically evaluate architecture decisions, document trade-offs, and select appropriate patterns. This skill should be used when the user asks about 'architecture decision', 'ADR', 'design pattern selection', 'technology choice', or needs to evaluate architectural trade-offs. Keywords: architecture, ADR, patterns, trade-offs, technical debt, quality attributes, decision record.
Facilitates deliberate skill development during AI-assisted coding. Offers interactive learning exercises after architectural work (new files, schema changes, refactors). Use when completing features, making design decisions, or when user asks to understand code better. Triggers on "learning exercise", "help me understand", "teach me", "why does this work", or after creating new files/modules. Do NOT use for urgent debugging, quick fixes, or when user says "just ship it".
Organize project files and folders for maintainability and scalability. Use when structuring new projects, refactoring folder structure, or establishing conventions. Handles project structure, naming conventions, and file organization best practices.
Automatically trigger review agents after task completion. Use when strategic-planner finishes planning tasks (calls plan-consultant) or when main agent completes coding tasks in /implement workflow (calls code-reviewer). Triggers on phrases like "plan complete", "implementation done", "coding finished", "ready for review".
Provides a structured workflow for planning and executing code reviews like a senior engineer. Use when asked to review code, PRs, or plan a code review task.
Recall project-first and global-supplement ChatCrystal memories before substantive implementation, refactoring, migration, configuration, investigation, or optimization work. Use when the task is non-trivial, has repository or project context, and prior fixes, decisions, pitfalls, or reusable patterns may change the approach.
Take rshankras/flow-walkthrough from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.