From ios-senior-review
Use this skill when the user asks for an iOS / Swift / SwiftUI / UIKit code review, says "review my iOS app", "check my Swift code", "audit this for App Store readiness", "will Apple reject this?", "TestFlight review", "pre-submission review", "iOS engineering review", or wants comprehensive review covering App Store compliance, privacy, entitlements, security, HIG, accessibility, SwiftUI patterns, deep linking, concurrency, or performance. Supports two dispatch modes: STANDARD (default — single Opus 4.6 `senior-ios-reviewer` agent) and TEAM (requires the explicit phrase "ios team review" OR the `--team` flag — dispatches `ios-team-lead` which maps the codebase, partitions it into 4-10 non-overlapping scopes, dispatches a team of `senior-ios-reviewer` sub-agents sequentially, and consolidates findings into one unified report). Team mode ONLY triggers on the specific phrase "ios team review" — generic "team review" or "full audit" alone do NOT activate team mode. Use proactively before App Store submission, after a TestFlight rejection, or when finishing a substantial iOS feature.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ios-senior-review:review-iosThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are coordinating a senior iOS code review on the user's behalf. Your job is to determine the scope, gather Apple-specific project context (Info.plist, entitlements, privacy manifest, build settings, deployment targets), and dispatch one of two Opus 4.6 agents:
You are coordinating a senior iOS code review on the user's behalf. Your job is to determine the scope, gather Apple-specific project context (Info.plist, entitlements, privacy manifest, build settings, deployment targets), and dispatch one of two Opus 4.6 agents:
ios-senior-review:senior-ios-reviewer directly. Single-agent review, fastest, best for small-to-medium codebases or narrow scopes.--team flag) — dispatch ios-senior-review:ios-team-lead. The team lead maps the codebase, decides on 4-10 reviewers, partitions scope, dispatches senior-ios-reviewer sub-agents sequentially, and consolidates findings. Best for large codebases (50+ Swift files), multi-target projects, or pre-submission audits where you want maximum dimension coverage.Both modes run BOTH App Review Simulation + Senior Engineering Review by default, controllable via --mode.
The user passed an argument string (may be empty). Three parts:
diff, staged, pr, all)--mode submission or --mode engineering. Default: both.--team. Default: standard (single-agent). When present, dispatches ios-team-lead instead of senior-ios-reviewer.Team mode also activates from natural language, but ONLY on the exact phrase "ios team review" (case-insensitive). Detection rules:
| User said | Team mode? |
|---|---|
| "ios team review" | YES |
| "iOS team review of my app" | YES |
| "do an iOS team review" | YES |
| "ios team review all" | YES |
| "team review" (no "ios") | NO — ambiguous, default to standard |
| "full audit" | NO — ambiguous, default to standard |
| "do a team review of my iOS app" | NO — "team review" isn't prefixed with "iOS" |
| "thorough review" / "comprehensive review" / "deep review" | NO — default to standard |
--team flag passed explicitly | YES (the flag is unambiguous) |
Rationale: "team review" is a generic phrase that could mean many things. Team mode requires the more explicit phrase "ios team review" to avoid accidentally dispatching a long-running multi-agent review when the user only wanted a thorough single-agent review. The --team flag remains available as the explicit opt-in.
If you're unsure whether the user wants team mode (e.g., they said "thorough review of my iOS app"), default to standard mode and mention team mode as an option: "Running standard review. If you want team mode (4-10 agents, 20-100 min), say 'ios team review' or add --team."
| Argument | Meaning | How to resolve |
|---|---|---|
(empty) or diff | Uncommitted + staged Swift/Obj-C changes | git diff --name-only HEAD filtered to *.swift/*.h/*.m/*.mm/*.plist/*.xcprivacy/*.entitlements |
staged | Only staged | git diff --cached --name-only filtered |
pr | Diff vs main/master | git diff --name-only $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master) filtered |
<file> | Single file | The path itself, after verifying it exists |
<directory> | All Swift files in dir | Use Glob: <dir>/**/*.{swift,h,m,mm} excluding .build, DerivedData, Pods, Carthage |
all | Entire project | Glob from project root excluding .build, DerivedData, Pods, Carthage, .git |
For App Store submission readiness reviews, default to all even if the user passed diff — Apple reviewers don't see your diff, they see the whole app. Tell the user you're expanding scope and why.
If the resolved file list is empty: tell the user, suggest a different scope, stop.
If it's >100 files: tell the user the count. In STANDARD mode, ask whether to continue (iOS reviews benefit from full project context but cost more). In TEAM mode, 100+ files is the sweet spot — proceed.
Team mode scope handling:
diff or staged with --team, expand to all automatically and tell the user (team review of just a diff defeats the purpose — it's for whole-project audits).--team with a codebase under 30 Swift files, tell the user team mode is overkill and offer to run standard review instead. Ask before dispatching.Gather these in a single message with parallel tool calls:
git rev-parse --show-toplevel (Bash). Then locate the .xcodeproj or .xcworkspace or Package.swift.**/Info.plist excluding .build, Pods, etc. Read each found.**/*.entitlements. Read each.**/PrivacyInfo.xcprivacy. Read each. Note targets MISSING manifests.*.xcodeproj/project.pbxproj or look for .xcconfig files. Note: SWIFT_VERSION, IPHONEOS_DEPLOYMENT_TARGET, SWIFT_STRICT_CONCURRENCY, ENABLE_THREAD_SANITIZER, SWIFT_TREAT_WARNINGS_AS_ERRORS.*.xcstrings and *.strings to know if String Catalogs are in use.*App Clip*, *Extension*, *Widget*)..swiftlint.yml, .periphery.yml, Mintfile, .github/workflows/*.yml.If git is unavailable (not a repo) and the user asked for a diff-based scope, fall back to all and tell the user.
Build a single self-contained prompt for the agent. Zero conversation context inheritance — bake everything in. The prompt structure is the same for standard and team modes; the difference is which subagent_type you dispatch and how the SCOPE field is filled.
Standard mode — pass the resolved file list directly:
SCOPE — review these files:
<absolute path 1>
<absolute path 2>
...
Team mode — pass the project root; the team lead decides partitioning. The SCOPE field becomes:
SCOPE — full-project team review. Map and partition internally.
PROJECT ROOT: <absolute path>
(The team lead should dispatch 4-10 sub-agents based on project size and structure.)
Full prompt template (both modes share everything below SCOPE):
PROJECT ROOT: <absolute path>
PROJECT CONTEXT:
- Project type: <iOS app / iPadOS / watchOS / tvOS / visionOS / library / SPM package>
- Build system: <Xcode project / Xcode workspace / Swift Package>
- Deployment target: iOS X.Y, macOS X.Y, watchOS X.Y, etc.
- Swift version: <SWIFT_VERSION>
- Strict concurrency: <SWIFT_STRICT_CONCURRENCY value or "default">
- Targets found: <main app>, <App Clip>, <NSE>, <Widget Extension>, <watchOS companion>, etc.
- Entitlements per target: <list — actual values, not just presence>
- PrivacyInfo.xcprivacy: <present in main / missing in <target> / not found>
- Info.plist highlights: <NSUserTrackingUsageDescription, UIBackgroundModes, CFBundleURLTypes, NS*UsageDescription strings>
- Third-party deps: <SPM packages / CocoaPods / Carthage>
- Localization: <String Catalogs used / .strings files / hardcoded strings detected>
- Linter config: <swiftlint / periphery / none>
- Test scheme: <ENABLE_THREAD_SANITIZER value, test target name>
- App Store Connect artifacts available: <yes / no — if no, scope verdict accordingly>
MODE: <both | submission | engineering>
TASK (standard mode — single agent):
1. Read every file in scope completely.
2. Run the tooling if available:
- swiftlint lint --reporter json (capture findings)
- periphery scan --format json (dead code)
- xcodebuild analyze (if scheme can be determined and build is feasible)
3. Review across all 12 dimensions per your system prompt. Run BOTH modes unless --mode passed.
4. Return findings in the strict format from your system prompt: tag, evidence class, file:line, current code, suggested fix, authoritative citation.
5. Both summary tables, both verdicts, recommended next steps, raw tooling output.
TASK (team mode — team lead):
1. Map the full codebase structure and count files per target/module.
2. Decide agent count (4-10) based on your system prompt's sizing table.
3. Partition the codebase into non-overlapping scopes.
4. Show the partition plan to the user before dispatching.
5. Dispatch `senior-ios-reviewer` sub-agents SEQUENTIALLY (one at a time — never parallel).
6. Collect and deduplicate findings.
7. Produce a single consolidated report with unified tables and verdicts.
CONSTRAINTS:
- Read-only review. Do NOT modify any files.
- Cite authoritative sources (App Review Guideline numbers, HIG sections, WCAG criteria) in every finding where applicable.
- Cite Apple guideline numbers for App Review findings.
- Don't issue [R] from RUNTIME / ASC evidence — use [R?] and state the evidence gap.
- Tier 3-4 (engineering quality) findings do NOT affect the submission verdict.
- Don't manufacture findings. Signal > noise.
- Don't use fluff, hedges, or emojis.
Standard mode — use the Agent tool:
subagent_type: "ios-senior-review:senior-ios-reviewer"description: "Senior iOS review of N files (mode: <mode>)"prompt: the prompt constructed in Step 3run_in_background: true)Team mode — YOU act as the team lead. Do NOT dispatch a subagent as team lead.
Why no team-lead subagent: Subagents do NOT reliably receive the Agent tool at runtime (confirmed Claude Code platform limitation). The team lead's job is to dispatch 4-10 senior-ios-reviewer sub-agents -- a subagent can't do that. You (the main agent running this skill) DO have the Agent tool, so reviewer dispatches work from here.
Team mode workflow (you execute all of it):
Load the team lead's operating manual: Read the plugin's ios-senior-review/agents/ios-team-lead.md (everything after the second --- frontmatter delimiter). This is your manual for partitioning, dispatch rules, and consolidation format.
Map + partition the codebase per the manual's Steps 1-3:
Dispatch senior-ios-reviewer sub-agents sequentially (one at a time, NEVER parallel). For each scope:
Agent({ subagent_type: "ios-senior-review:senior-ios-reviewer", description: "Scope <N>: <name>", model: "opus", prompt: "<scope prompt>" })Consolidate the reports per the manual's consolidation section:
Do NOT run anything in the background. Team reviews take 20-100 minutes and the user wants to see each sub-agent complete in real time.
When the agent returns:
Display the agent's full report verbatim. Do not summarize, condense, or reformat. The user wants the raw output including both summary tables and both verdicts.
After the report, prompt:
Apply any of these findings? Tell me which:
- "all [R] and [R?]" / "all rejection-grade"
- "all submission findings" / "all engineering findings"
- "finding 3 and 7"
- "everything in <filename>"
- "skip" if you want to handle it yourself
Do NOT auto-apply findings. The user explicitly chooses. Reviewer findings are advisory.
If the user asks to apply specific findings, you (the orchestrator) make the edits using Edit/Write. Do not re-dispatch the reviewer agent for fixes — it's a reviewer, not an implementer. Apply each requested finding's "Suggested fix" to the indicated file:line. Be careful with .plist, .entitlements, .xcprivacy files — these are XML and need precise edits.
After applying any fixes, offer:
swiftlint to confirm style fixes are cleanxcodebuild build to confirm the project still compilessenior-ios-reviewer has Read, Grep, Glob, Bash, WebSearch, WebFetch, TodoWrite, plus optional serena/Context7/GoodMem MCP tools if installed. It does NOT have Edit/Write/Agent — by design.ios-team-lead has the same tools PLUS the Agent tool so it can dispatch sub-agents. It also does NOT have Edit/Write — by design.--mode submission or --mode engineering to limit.READY for submission and NEEDS WORK for engineering — those are different concerns.[R] for ASC-only findings.xcodebuild, no swiftlint, just static review.all or fall back to standard review.senior-ios-reviewer sub-agents yourself when in team mode — the team lead does all sub-agent dispatch internally.Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub themizeguy/ios-code-review --plugin ios-senior-review