Skip to content
Agentmart
Submit a tool

apple-dev

Build, run, test, verify and install iOS and macOS apps as an agent - the just verbs of the Apple templates, the verification ladder (unit tests, SwiftUI…

Skill by alexjmiller5

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/alexjmiller5-apple-dev

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Build, run, test, verify and install iOS and macOS apps as an agent - the just verbs of the Apple templates, the verification ladder (unit tests, SwiftUI preview render, simulator drive with taps and the accessibility tree, physical-device install, macOS app on screen), Apple's Xcode MCP call order, raw xcodebuild/simctl/devicectl fallbacks, and the gotchas. Use for ANY task touching an Xcode project, a simulator, a physical iPhone or Mac app build, SwiftUI previews, .xcresult bundles, or the Xcode MCP server.

Use cases: backend, testing, productivity, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/apple-dev

What's inside

Skill name
apple-dev
Description
Build, run, test, verify and install iOS and macOS apps as an agent - the just verbs of the Apple templates, the verification ladder (unit tests, SwiftUI preview render, simulator drive with taps and the accessibility tree, physical-device install, macOS app on screen), Apple's Xcode MCP call order, raw xcodebuild/simctl/devicectl fallbacks, and the gotchas. Use for ANY task touching an Xcode project, a simulator, a physical iPhone or Mac app build, SwiftUI previews, .xcresult bundles, or the Xcode MCP server.
License
MIT
Instructions
312 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • files: referenced but missing: scripts/sign-ios.py, scripts/ota-install.py, scripts/ota-install.sh

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Apple Dev

How an agent builds, verifies, and delivers an Xcode project. Local
development uses the **build host** named in the machine sheet (Xcode,
simulators, the `xcode` MCP server). The sheet also identifies the **phone
installer**, the Mac paired to the owner's iPhone. While iterating, builds
are signed and installed from the build host; CI signs once the owner
confirms iteration is done.

## Verbs

Every Apple template (`ios-app`, `appstore-app`, `macos-app`) ships the same
`just` interface; a project's justfile is the truth for its own extras.

| Verb | Does | Needs |
|---|---|---|
| `just gen` | XcodeGen regenerates the `.xcodeproj` from `project.yml` (every other verb runs it first) | `xcodegen` |
| `just check` | Unsigned build - the CI gate | nothing |
| `just test` | Unit tests on a simulator (iOS) or the Mac (macOS) | a simulator runtime |
| `just run` | Debug build, boot the simulator if needed, install, launch; prints `bundle=<id> simulator=<udid>` (macOS: opens the app from `build/`) | a simulator runtime |
| `just build` | Debug build + install on the phone (automatic signing, readable logs) | `IOS_DEVELOPMENT_TEAM`, `IOS_DEVICE_ID`, Xcode signed into the team |
| `just deploy` | Local Release Ad Hoc export + phone install (`ios-app`; a host without the identity in its keychain uses `scripts/sign-ios.py` with the signing material in the environment) | `+ IOS_PROFILE`, the Apple Distribution identity in the keychain |
| `just ota` | Add `build/<App>.ipa` to the machine's shared tailnet install page, `https://<tailnet name>/install/` (`ios-app` only; returns at once) | a verified, decrypted CI IPA or local export; Tailscale with HTTPS certificates |
| `just logs` | Five minutes of device logs into `logs/` (Debug installs only) | `IOS_DEVICE_ID` |
| `just install` | `macos-app`: Release build copied to `~/Applications/<App>.app` and opened, beside a released copy in `/Applications` | nothing; `MAC_INSTALL_HOST` for another Mac |

Environment interface: `IOS_TEST_DESTINATION` (simulator, default in the
justfile), `IOS_DERIVED_DATA` (keep it outside any cloud-synced folder),
`IOS_INSTALL_HOST` (ssh host of the phone installer; unset = this Mac
installs), `MAC_INSTALL_HOST` (ssh host that gets the Mac pre-release build;
unset = this Mac). Raw `xcodebuild` output is long: pipe it through `xcbeautify`
when you read it yourself.

## Iterate locally, CI after the owner confirms

Measured on the build host (Apple silicon, 2026-10) against GitHub-hosted
runners for the same apps:

| Build | Local cold / warm | CI, push to artifact (median, worst) |
|---|---|---|
| Small iOS app, signed Ad Hoc `.ipa` | 13 s (12 s unsigned archive, 8 s warm) | 2.2 min, 4.8 min |
| Large multi-target iOS app | 48 s / 3 s | 6 min, 44 min (queued behind other runs) |
| Large macOS app, Release | 91 s / 2 s | 30 min, 2 h (signing + notarization) |

Local wins by one to two orders of magnitude while iterating. So:

1. While iterating, build, sign and install from the build host: `just
   build`, `just deploy`, or `scripts/sign-ios.py` into `build/` plus the
   `just ota` and the install; macOS `just install`. Never push, tag or dispatch
   CI only to get an installable build. Request a secret-manager unlock up
   front when local signing needs one.
2. Before a long local build: at least 15 GB free, one build at a time on a
   shared host (its build lock), `COMPILATION_CACHE_ENABLE_CACHING=NO`, and
   delete your own products afterwards.
3. Ask the owner whether iteration is done. Only then dispatch the Ad Hoc
   workflow or push the release tag, and install from the CI artifact. Wait
   on the run with a waker if the environment has one (one API call every
   few minutes), never with parallel `gh run watch` loops.
4. Use CI earlier only when the build host is short on disk or overloaded or
   the signing material cannot be reached. Developer ID notarization and
   App Store/TestFlight uploads are CI-only.

## Personal Ad Hoc CI

`ios-app` uses a manual `workflow_dispatch` signing workflow; ordinary
validation runs do not need signing secrets. CI archives and exports for
registered devices, with installation as a separate step. TestFlight and
App Store submission belong to `appstore-app`.

The signing helper accepts `--project`, `--scheme`, and `--output`, with
`IOS_CERTIFICATE_P12_BASE64`, `IOS_CERTIFICATE_PASSWORD`, `IOS_PROFILE_BASE64`,
and optional `IOS_DEVICE_ID`. Credentials come from the project's configured
secret manager. CI imports into a temporary keychain, restores the previous
keychain search list, and removes temporary signing material even on failure.
A runner does not need a desktop login or the phone paired to it.

Generate a temporary age identity in private local scratch for each dispatch.
Supply only its **public** key as `artifact_recipient`; keep the private
identity locally until download/decryption is complete. Watch the workflow,
then download its encrypted `.ipa.age` artifact within the one-day retention
period. Decrypt locally, verify the exported app's signature, bundle/team and
device profile, and place the IPA at the path expected by the project's
install/OTA helper. Remove the temporary identity after decryption and the
decrypted transfer copy when installation no longer needs it.

Public-repository Actions artifacts are not private. Upload only the
encrypted IPA, never standalone profiles, P12 files, private keys, keychains,
or plaintext IPAs. The IPA necessarily contains an embedded provisioning
profile with device IDs; retain it for installation and keep it out of logs.
No persistent encryption key or recipient repository variable is needed.

## Pre-release builds

A change reaches the owner as a pre-release build before it becomes a release:

1. Verify it yourself first (the ladder below: tests, preview, simulator or
   the Mac).
2. Install a pre-release build where the owner uses the app: iPhone `just
   build` (Debug, through `IOS_INSTALL_HOST`); macOS `just install` (through
   `MAC_INSTALL_HOST`).
3. Tell the owner exactly what to check, and finish testing with them.
4. Only once they confirm, suggest a release per the `semver` skill. Several
   verified changes ship as one release. A pre-release install is not a
   release: no version bump, no tag.

## Verification ladder

Choose the cheapest sufficient evidence for each affected behavior. A passing
mock does not discharge a separate hardware or interaction requirement.

1. **Logic**: `just test`. Write the test first; mutation-test it.
2. **A view**: `RenderPreview` through the Xcode MCP on the `#Preview` of the
   changed view - an image without booting anything.
3. **The running app on a simulator**: `just run`, then a device-interaction
   session through the Xcode MCP (below). Every capture returns a PNG and the
   accessibility hierarchy (label, frame, a precomputed point to tap); find
   controls by label, never by guessed coordinates. Read `GetConsoleOutput`
   for OSLog and crashes.
4. **Hardware-only behavior** (camera, microphone, ShazamKit, push, HealthKit,

From alexjmiller5/agent-config-public, MIT.

More from alexjmiller5/agent-config-public

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Oct 14, 2026 (14 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from alexjmiller5

Cite this page

apple-dev skill. Agent Mart. https://agentmart.dev/skills/alexjmiller5-apple-dev (last updated 2026-10-24)