Pink Lady Apple
/Apple toolchain plugin
Five Claude Code skills that take an Apple app from an unregistered bundle ID to a build on a tester’s phone — the fastlane bugs, ASC API quirks, and TestFlight traps written down once.
synodic-studio/pink-lady-apple· MIT
Shipping an Apple app from a headless machine is a long chain of steps where any one link fails quietly. fastlane reports success and the build is still invisible. altool rejects an upload for a purpose string buried in a linked framework. A version cliff between system Ruby and the current fastlane silently caps which versions you can even install. None of this is hard once you have hit it; all of it costs an afternoon the first time.
pink-lady-apple is the plugin I extracted out of my studio toolkit once the Apple content grew too big to live alongside everything else. It is five skills that encode that chain — the commands, the specific bugs, and the recovery procedures — so a coding agent can drive a release without re-learning the landmines each time. The repo ships with placeholder values instead of my own account details, so it is meant to be lifted, not just read.
The five skills
Each loads itself when its description matches the task; none has to be invoked by name.
apple-platform-dev— the architecture layer: MVVM-plus-Manager patterns, Metal and Core Data integration, concurrency, and the Tuist-first project conventions that keep everything CLI-drivable. It hands off SwiftUI quality rules to swiftskim and, increasingly, Metal shader work to alloy.apple-release— the fastlane layer: mise-pinned Ruby, bundler, ASC API-key auth, and a repeatablebetalane. It carries the two landmines that cost the most: thepricesrelationship bug that crashes any App lookup on fastlane ≤ 2.212.1, and the Ruby 2.6/2.7 version cliff that caps which fastlane you can run on system Ruby.testflight-ship— the distribution layer, and the reason the plugin exists.fastlane betafinishing successfully is not shipping: the build can go VALID in App Store Connect and still reach nobody, because an internal beta group with the right two attributes has to exist first. This skill is the checklist that turns “uploaded” into “on the tester’s phone,” including the ASC endpoints Apple’s own docs describe incorrectly.debug-builds— Debug/Release separation with distinct bundle-ID suffixes and overlay icons, so an Xcode install and a TestFlight install coexist on the same device with independent data.sim-capture— scripted iOS Simulator screenshots and video via launch arguments and XCUITest, for App Store assets without touching the GUI.
The traps it encodes
The value is not the happy path — fastlane documents that. It is the failures that produce no useful error:
- “Uploaded but invisible.” A build goes VALID, the lane reports success, and no tester ever sees it, because the internal group was never created or was created without
isInternalGroup: true(writable on POST, read-only on PATCH — the opposite of what the docs imply). - The processing rejection with no API. When Apple rejects a build during post-upload processing, there is no ASC endpoint for the reason — it arrives only by email to the account holder. The fastlane waiter will hang for hours on a build that will never appear. The skill knows to stop waiting and check email for the
ITMS-90xxxcode. - The purpose-string ambush. A linked framework references a privacy-sensitive API you never call directly, and altool rejects the upload for a missing
NS*UsageDescription— sometimes two at once.
Each of these is a rule in a skill because each cost real time to diagnose once.
Built to be lifted
The skills carry fastlane templates (Fastfile for iOS and macOS, Appfile, Gemfile, mise.toml, bundler config) and a standalone App Store Connect API helper. Everything specific to one account — team ID, key ID, issuer ID, device names, tester identity — is a placeholder, not a hardcoded value, so the toolchain describes a shape you fill in rather than a machine you have to be.
What to take from this
Treat “the lane succeeded” as a midpoint, not the finish. The most expensive class of shipping bug is the one where every tool reports success and the outcome still didn’t happen. Encode the verification, not just the action.
Write down the failure, not the feature. Documentation of the happy path already exists. What is worth capturing is the specific bug, the version it broke on, and the recovery — the things you only learn by losing an afternoon to them.
Keep your specifics out of your tools. A toolchain hardcoded to one account is a personal artifact; the same toolchain with placeholders is something anyone can lift. The difference is a scrub.
The full source is on GitHub at synodic-studio/pink-lady-apple, MIT-licensed.