skills/cupertino/SKILL.md
This skill should be used when working with Apple APIs, iOS/macOS/visionOS development, or Swift language questions. Covers searching Apple developer documentation, looking up SwiftUI views, finding UIKit APIs, reading Apple docs, browsing Swift Evolution proposals, checking Human Interface Guidelines, and exploring Apple sample code. Supports 402 frameworks including SwiftUI, UIKit, Foundation, and Combine via offline search of 277,000+ documentation pages.
npx skillsauth add mihaelamj/cupertino cupertinoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Search 277,000+ Apple developer documentation pages offline. Cupertino is a lexical search engine over Apple's docs, samples, HIG, Swift Evolution, Swift.org, the Swift book, and Swift package metadata. It returns deterministic, citable results, never hallucinations.
cupertino search. If the user's question doesn't obviously involve Apple, but mentions a symbol that might be Apple's (e.g., NavigationStack, URLSession, @Observable), query cupertino to confirm before assuming.UIWebView when WKWebView exists, URLConnection when URLSession exists, Combine when modern Swift Concurrency fits, or UIKit list patterns when SwiftUI List is what the user asked for. Search for the conceptual area ("loading a web view", "displaying a list of items", "background URL session") and read what Apple's doc actually steers people toward. If the user's context is iOS 17+ or Swift 6, prefer the API Apple ships for that era.Don't ship code that names APIs cupertino can't find, and don't ship patterns Apple's current docs actively steer away from. This "verify before sending" pass is cheap (millisecond search, few-hundred-token cost), catches most hallucinations, and runs in seconds.
First-time setup (downloads ~2.4GB database):
cupertino setup
If cupertino setup hasn't been run, do that first.
Cupertino does exact lexical matching. You handle the language understanding before calling it.
Users describe things by appearance, by UIKit muscle memory, or with typos. Cupertino indexes Apple's canonical names. Translate first; search second.
Common translations:
| User says | Likely SwiftUI | Likely UIKit | Likely AppKit |
|---|---|---|---|
| search bar / searchbar | searchable modifier | UISearchBar | NSSearchField |
| text field | TextField | UITextField | NSTextField |
| list view / table view | List | UITableView / UICollectionView | NSTableView |
| segmented control | Picker(.segmented) | UISegmentedControl | NSSegmentedControl |
| spinner / loading indicator | ProgressView | UIActivityIndicatorView | NSProgressIndicator |
| alert | .alert modifier | UIAlertController | NSAlert |
| modal / popup | .sheet, .fullScreenCover | present(_:animated:) | NSWindow.beginSheet |
| switch / toggle | Toggle | UISwitch | NSSwitch |
| stepper | Stepper | UIStepper | NSStepper |
| web view | WKWebView (UIKit) | WKWebView | WKWebView |
When you translate, tell the user: "Searching for searchable (SwiftUI equivalent of search bar)."
Cupertino does not fuzzy-match. If the user types searchabe, calling cupertino search "searchabe" will return weak results. You correct the typo first, then search:
searchabe → search for searchableunviewcontroller → search for UIViewControllertabel view → search for UITableView or List (depending on framework)Use your knowledge of Apple naming conventions. If unsure, search for both the literal query and your guess; compare results.
Use --framework to narrow when the framework is obvious:
--framework swiftuiNS* → --framework appkitUI* → --framework uikitMK* → --framework mapkitIf the framework is genuinely ambiguous, search without --framework and disambiguate from results.
Apple keeps deprecated symbols indexed. Lead with the current canonical:
UIWebView is deprecated → recommend WKWebViewUISearchDisplayController is deprecated → recommend UISearchControllerUITableView for new code → recommend UICollectionView or SwiftUI ListWhen you mention a deprecated symbol in your answer, flag it.
Bare-name queries can collide with namespaced symbols elsewhere in the index. Common collisions:
searchable → returns CoreSpotlight CSSearchableIndex, not the SwiftUI modifier. Use searchable(text: to find the modifier directly.View → returns hits across many frameworks; prefer View with --framework swiftui and check the metadata.framework field on each candidate.Identifiable, Codable) hit the protocol page only when paired with a more specific term.When a bare-name query returns the wrong thing, try the function-signature form (name(arg1:arg2:) or pair the query with a distinguishing keyword.
If a search returns nothing useful:
tableview returns weak results, try cupertino search "building list interfaces" or cupertino search "displaying a list of items" to find Apple's conceptual pages. Descriptive queries often surface the right concept page.searchable(text: instead of searchable.searchbar. Retried as searchable(text: (SwiftUI modifier), found 5 results."Never silently rewrite without telling the user what you did.
Filtered searches (--source X) return a per-source dedicated view, not the unified candidates shape. The unified search exists for cross-source ranking; the per-source views are for browsing one source's structured data.
Shapes (stable across v1.0.x):
--source): {candidates, contributingSources, question}--source apple-docs: top-level list of doc objects with availability, framework, id, rank--source samples: {files: [{filename, path, projectId, rank, snippet}]}--source hig: {count, query, results: [{title, uri, summary, availability}]}--source packages: {candidates, contributingSources: ["packages"], question} (matches the unified shape; routes to packages.db)--source apple-archive / swift-evolution / swift-org / swift-book: source-specific shapesIf you parse JSON, expect different keys per source. The default unified search is the most consistent option when you don't need source-specific fields.
These are gotchas worth knowing so you can route around them:
"how to display loading spinner" misses, try "ProgressView" directly or "loading interface".If the user asks "SwiftUI equivalent of UITableView" or mentions migration:
List) AND the old symbol the user knows (UITableView)Cupertino's value is grounding. Use it.
For every API, framework, or concept you mention in your answer, name the cupertino URI it came from. Example:
Use
searchable(text:)(apple-docs://swiftui/view/searchable(text:)) to add a search field to a SwiftUI view. The modifier was introduced in iOS 15.
This costs you almost nothing in tokens (you're already typing the symbol name) and prevents hallucination because you can only cite what you actually retrieved.
Before finalizing your answer, scan it for every API/symbol you named. Each one must trace back to a URI you got from cupertino. If it doesn't:
cupertino search "<symbol>" --format json| Pattern | Cost | When to use | |---|---|---| | Cite as you go (no extra calls) | ~5% overhead | Always | | Re-search uncertain claims | 1 search call per claim (~500 tokens) | When you mention an API you don't 100% remember | | Full LLM verify pass | 1.5–2× baseline | High-stakes answers (production code, security) | | Wrong answer + user correction | 3–5× baseline | Worst case; avoid |
The cite-as-you-go default is essentially free and prevents most hallucinations. Re-search for uncertain claims is cheap. Full verify passes are usually overkill.
Search across all sources (apple-docs, samples, hig, swift-evolution, swift-org, swift-book, packages):
cupertino search "SwiftUI View" --format json
cupertino search "SwiftUI View" --format json --limit 5
Filter by source:
cupertino search "async await" --source swift-evolution --format json
cupertino search "NavigationStack" --source apple-docs --format json
cupertino search "button styles" --source samples --format json
cupertino search "button guidelines" --source hig --format json
Filter by framework:
cupertino search "@Observable" --framework swiftui --format json
Retrieve full document content by URI:
cupertino read "apple-docs://swiftui/documentation_swiftui_view" --format json
cupertino read "apple-docs://swiftui/documentation_swiftui_view" --format markdown
List all indexed frameworks with document counts:
cupertino list-frameworks --format json
Browse indexed Apple sample code projects:
cupertino list-samples --format json
cupertino list-samples --framework swiftui --format json
Read a sample project or specific file:
cupertino read-sample "foodtrucksampleapp" --format json
cupertino read-sample-file "foodtrucksampleapp" "FoodTruckApp.swift" --format json
| Source | Description |
|--------|-------------|
| apple-docs | Official Apple documentation (~277,000+ pages indexed in v1.0.2) |
| swift-evolution | Swift Evolution proposals |
| hig | Human Interface Guidelines |
| samples | Apple sample code projects |
| swift-org | Swift.org documentation |
| swift-book | The Swift Programming Language book |
| apple-archive | Legacy guides (Core Animation, Quartz 2D, KVO/KVC) |
| packages | Swift package documentation |
All commands support --format with these options:
text - Human-readable output (default for most commands)json - Structured JSON for parsing (use this when reasoning about results)markdown - Formatted markdowncupertino search returns:
{
"candidates": [
{
"rank": 1,
"score": 0.91,
"title": "VStack | Apple Developer Documentation",
"identifier": "apple-docs://swiftui/documentation_swiftui_vstack",
"source": "apple-docs",
"metadata": {
"filePath": "https://developer.apple.com/documentation/SwiftUI/VStack",
"framework": "swiftui"
},
"chunk": "VStack | Apple Developer Documentation\n\nA view that arranges...",
"readFullCommand": "cupertino read apple-docs://swiftui/documentation_swiftui_vstack --source apple-docs"
}
],
"contributingSources": ["packages", "samples", "apple-docs", "hig", "swift-evolution"],
"question": "VStack"
}
Use identifier (not uri) with cupertino read. Each candidate carries a readFullCommand field with the exact command pre-built.
cupertino read returns:
{
"id": "...",
"title": "VStack | Apple Developer Documentation",
"url": "https://developer.apple.com/documentation/swiftui/vstack",
"abstract": "A view that arranges its children vertically.",
"overview": "...",
"rawMarkdown": "---\nsource: ...\n...",
"declaration": {"code": "...", "language": "swift"},
"availability": [...],
"codeExamples": [...],
"sections": [...],
"kind": "structure",
"source": "appleWebKit",
"contentHash": "...",
"crawledAt": "2026-05-01T20:50:48Z"
}
Note framework is encoded in the url path, not as a top-level field. The source field on read returns the crawler identifier (appleWebKit), not the cupertino source taxonomy from search.
--source to narrow searches to a specific documentation source--framework to filter by framework (e.g., swiftui, foundation, uikit)--limit to control the number of results returned (default works well; 5–10 is plenty)cupertino read--include-archive to include themdevelopment
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.