RepoPilotOpen in app →

nomad-cli/cupertino

CLI for the Apple Dev Center

Mixed

Stale — last commit 5y ago

worst of 4 axes
Use as dependencyMixed

last commit was 5y ago; no tests detected…

Fork & modifyMixed

no tests detected; no CI workflows detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 5y ago; no CI workflows detected

  • 23+ active contributors
  • MIT licensed
  • Stale — last commit 5y ago
Show 3 more →
  • Concentrated ownership — top contributor handles 66% of recent commits
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days; add a test suite
  • Fork & modify MixedHealthy if: add a test suite
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Great to learn from" badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/nomad-cli/cupertino?axis=learn)](https://repopilot.app/r/nomad-cli/cupertino)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/nomad-cli/cupertino on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: nomad-cli/cupertino

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/nomad-cli/cupertino shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 5y ago

  • 23+ active contributors
  • MIT licensed
  • ⚠ Stale — last commit 5y ago
  • ⚠ Concentrated ownership — top contributor handles 66% of recent commits
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live nomad-cli/cupertino repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/nomad-cli/cupertino.

What it runs against: a local clone of nomad-cli/cupertino — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in nomad-cli/cupertino | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 1815 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>nomad-cli/cupertino</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of nomad-cli/cupertino. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/nomad-cli/cupertino.git
#   cd cupertino
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of nomad-cli/cupertino and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "nomad-cli/cupertino(\\.git)?\\b" \\
  && ok "origin remote is nomad-cli/cupertino" \\
  || miss "origin remote is not nomad-cli/cupertino (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1815 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1785d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/nomad-cli/cupertino"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Cupertino is a Ruby CLI tool that automates administrative tasks on Apple's Developer Portal, specifically managing provisioning profiles, certificates, devices, and app IDs without manually logging into the web interface. It wraps Apple's provisioning portal API through an HTTP agent (lib/cupertino/provisioning_portal/agent.rb) to enable bulk operations like registering devices and managing profiles from the command line. However, note that Apple's recent portal changes have broken this tool—it is no longer maintained, and the README explicitly recommends using fastlane's spaceship or match/sigh as modern alternatives. Monolithic single gem structure: lib/cupertino/ is the main module with a provisioning_portal/ subdirectory containing agent.rb (HTTP communication), commands.rb (command dispatcher), and commands/ folder with individual command modules (devices.rb, profiles.rb, certificates.rb, app_ids.rb, login.rb, logout.rb). Entry point is bin/ios CLI script. lib/cupertino/provisioning_portal/helpers.rb provides shared utilities.

👥Who it's for

iOS developers and development teams who manage multiple test devices and provisioning profiles for ad-hoc or enterprise distribution. They want to automate repetitive iOS certificate and device registration tasks without navigating Apple's web portal for each device—particularly useful in CI/CD workflows or onboarding scenarios.

🌱Maturity & risk

Abandoned/legacy. The README explicitly states "Cupertino stopped working due to a recent change on the Apple Developer Portal" and recommends fastlane tools as maintained alternatives. The codebase shows no recent activity (commit dates not provided in data, but the warning is prominent). This is a historical/educational project rather than production-ready software.

High risk for current use. The tool no longer works against Apple's actual Developer Portal due to API changes, making it unsuitable for production. There are no visible test files in the top 60 file structure, so test coverage is unclear. Single maintainer (nomad-cli org) with no apparent recent maintenance. Dependency on Xcode Command Line Tools and Keychain (Mac-only) adds platform brittleness. Do not use this in new projects—use fastlane instead.

Active areas of work

Nothing. The project is dormant with a deprecation warning. No active development, PRs, or milestones are indicated in the provided data. It serves as a historical reference for how to structure a Ruby CLI tool for Apple automation before fastlane became the standard.

🚀Get running

Clone and install: git clone https://github.com/nomad-cli/cupertino.git && cd cupertino && bundle install (uses Bundler via Gemfile). Then build locally: gem build cupertino.gemspec or bundle exec rake install. Before running: install Xcode Command Line Tools with xcode-select --install. Note: the tool will not function against current Apple Developer Portal.

Daily commands: This is a CLI tool, not a server. After installation, run commands directly: ios login (authenticate), ios devices:list, ios devices:add "name"=identifier, ios profiles:list, etc. See README for full command reference. Requires active Apple Developer account and internet access. Important: will fail against current Apple portal due to breaking changes.

🗺️Map of the codebase

🛠️How to make changes

For new commands: add a file under lib/cupertino/provisioning_portal/commands/ (e.g., commands/new_feature.rb), implement the command class, and register it in commands.rb. For HTTP logic: modify lib/cupertino/provisioning_portal/agent.rb to handle new portal endpoints. For shared utilities: add to helpers.rb. The entry point dispatcher is likely in bin/ios or the main provisioning_portal.rb module.

🪤Traps & gotchas

Keychain Mac-only dependency: credentials are stored in macOS Keychain by default; Linux/Windows users must use IOS_USERNAME and IOS_PASSWORD environment variables instead. Apple portal API fragility: the tool directly scrapes/parses Apple's portal responses, so any HTML/endpoint changes break it (which already happened). No session persistence: each command re-authenticates unless credentials are cached in Keychain. Xcode Command Line Tools required: setup step not always obvious to Windows developers. Deprecated: do not expect this to work without significant fixes.

💡Concepts to learn

  • Web scraping / portal HTML parsing — Cupertino's agent.rb likely parses Apple's portal HTML responses to extract device IDs and profile data; understanding this brittle approach explains why it broke when Apple redesigned the portal
  • Credential storage in system Keychain — The tool stores Apple credentials in macOS Keychain to avoid re-prompting users; understanding Keychain integration is key to the login/logout flow and why environment variables are a fallback
  • Command-line argument parsing and dispatch — The commands/ structure and bin/ios entry point implement a CLI dispatcher pattern; this is foundational to how the tool maps ios devices:list to code
  • Apple Developer provisioning profiles and certificates — The entire tool exists to automate iOS provisioning, device registration, and certificate management; understanding what profiles and certificates are is essential to using or modifying the tool
  • Mechanical HTTP client automation — The agent likely uses a library like Mechanize to automate HTTP requests and form submissions to the portal; this approach is now superseded by Apple's public APIs (spaceship)
  • fastlane/fastlane — Modern, maintained successor ecosystem; fastlane's spaceship gem and match/sigh tools provide the same Apple Developer Portal automation with active support
  • fastlane/spaceship — Direct API client for Apple's Developer Portal; the maintained alternative to Cupertino's agent.rb approach
  • nomad/shenzhen — Companion CLI tool for iOS building and distribution; often used alongside Cupertino in the same nomad ecosystem
  • mattt/houston — Sibling nomad-style tool for push notifications; part of the same suite of iOS automation utilities
  • nomad/nashville — Part of the nomad suite providing iTunes Store API access; shared architectural philosophy with Cupertino

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add deprecation warning and migration guide to README

The README already mentions that Cupertino stopped working due to Apple Developer Portal changes and recommends spaceship/fastlane alternatives, but this critical information is buried in a small note. A new contributor could create a prominent deprecation banner at the top of README.md with a structured migration guide showing code examples for moving from Cupertino commands to spaceship/fastlane equivalents, making it immediately clear to users that this project is unmaintained.

  • [ ] Add a prominent 'DEPRECATED' warning banner at the top of README.md with clear visual styling
  • [ ] Create a 'Migration Guide' section listing common Cupertino commands and their spaceship/fastlane equivalents
  • [ ] Include code examples showing how to replace typical workflows (e.g., device registration, profile management)
  • [ ] Link to official spaceship and fastlane documentation

Refactor lib/cupertino/provisioning_portal/commands into individual command files

The commands directory contains a monolithic lib/cupertino/provisioning_portal/commands.rb file alongside individual command files (app_ids.rb, certificates.rb, etc.). This suggests the main commands.rb is doing too much. A contributor should audit what's in commands.rb, extract any shared command registration logic, and consolidate it into a proper command loader, reducing code duplication.

  • [ ] Examine lib/cupertino/provisioning_portal/commands.rb to identify all command registration and routing logic
  • [ ] Check if command logic is duplicated across individual command files (app_ids.rb, certificates.rb, devices.rb, etc.)
  • [ ] Create a new lib/cupertino/provisioning_portal/commands/base.rb for shared command infrastructure if needed
  • [ ] Refactor commands.rb to be a lightweight loader/registry that imports from individual command files
  • [ ] Verify all CLI commands still work correctly via bin/ios after refactoring

Add comprehensive unit tests for lib/cupertino/provisioning_portal/agent.rb

The agent.rb file likely contains the core HTTP/session management logic for interacting with Apple's Developer Portal, but there are no visible test files in the repo structure. A contributor should create spec/lib/cupertino/provisioning_portal/agent_spec.rb with unit tests covering authentication, request handling, error cases, and session management to catch regressions and document expected behavior.

  • [ ] Create spec/lib/cupertino/provisioning_portal/ directory structure if it doesn't exist
  • [ ] Review lib/cupertino/provisioning_portal/agent.rb to understand all public methods and their responsibilities
  • [ ] Write unit tests covering: successful authentication, failed login, session handling, HTTP request formation, response parsing, error handling
  • [ ] Add tests for edge cases like network timeouts, malformed responses, and expired sessions
  • [ ] Ensure test suite uses appropriate mocking (e.g., WebMock or VCR) to avoid hitting real Apple servers

🌿Good first issues

  • Add test coverage for lib/cupertino/provisioning_portal/commands/devices.rb and profiles.rb—currently no visible test files in structure; writing unit tests for device listing and profile creation would clarify API expectations.
  • Document the exact Apple Developer Portal API endpoints used in agent.rb—add inline comments mapping HTTP requests to portal pages so future maintainers understand which endpoint each method targets (aids debugging when Apple changes the portal).
  • Add integration tests or examples for the login flow in commands/login.rb and Keychain credential handling—clarify how credentials are retrieved and stored across platforms (especially for non-macOS environments).

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 537b971 — Update README.md (mattt)
  • fc11129 — Fixing command to accept the type option like others (#221) (MSylvia)
  • ec774ee — Version 1.4.0 (dankimio)
  • 8d59181 — Add Bundler tasks to Rakefile (dankimio)
  • cb03608 — Update code style (dankimio)
  • 776ca8e — Merge pull request #241 from nomad/relax-version-constraints (dankimio)
  • 913595b — Update version constraints (dankimio)
  • fa5bdeb — Relaxed overly strict dependencies to allow semver minor version upgrades (due to conflicts with other libraries, e.g. f (lmirosevic)
  • 7acf9d2 — Merge pull request #235 from KrauseFx/patch-1 (KrauseFx)
  • 8256358 — Updated URL to match and sigh (KrauseFx)

🔒Security observations

The Cupertino project presents significant security concerns. Most critically, it is deprecated and no longer maintained, making it unsuitable for production use. The project handles sensitive Apple Developer credentials through CLI mechanisms without visible secure storage protections. Input validation, secure communication configuration, and session management practices are not evident from the code structure. The lack of dependency information and security testing infrastructure compounds these risks. Users should migrate to actively maintained alternatives (spaceship or fastlane tools) as recommended in the project's README.

  • High · Deprecated and Unmaintained Project — README.md, Project Status. The README explicitly states 'Cupertino stopped working due to a recent change on the Apple Developer Portal.' This indicates the project is no longer functional and likely receives no security updates or maintenance. Using this project poses significant risks as it cannot adapt to API changes or security requirements from Apple's infrastructure. Fix: Do not use this project in production. Migrate to maintained alternatives such as spaceship, fastlane/match, or fastlane/sigh as recommended in the README.
  • High · Credential Management via CLI Arguments — lib/cupertino/provisioning_portal/commands/login.rb. The project includes login/logout commands (lib/cupertino/provisioning_portal/commands/login.rb) that handle Apple Developer credentials. CLI-based credential handling may expose credentials in shell history, process lists, or logs without proper protection mechanisms. Fix: Implement secure credential storage using OS-level keychains (macOS Keychain, Windows Credential Manager). Avoid storing credentials in plain text. Use environment variables or secure credential managers. Sanitize logs and shell history.
  • High · No Visible Input Validation — lib/cupertino/provisioning_portal/commands/. The file structure shows multiple command modules (app_ids.rb, certificates.rb, devices.rb, profiles.rb) that likely parse and process user input and API responses. Without visible input validation logic, these could be vulnerable to injection attacks or malformed data exploitation. Fix: Implement comprehensive input validation for all user-supplied data. Validate and sanitize API responses. Use parameterized queries or safe data handling patterns. Add unit tests for input validation.
  • Medium · Insufficient Dependency Visibility — Gemfile, gemspec dependencies. The Gemfile content is not provided in the analysis context. Ruby gem dependencies may include vulnerable or outdated libraries. Without seeing the dependency manifest, potential supply chain risks cannot be fully assessed. Fix: Review Gemfile and cupertino.gemspec for outdated dependencies. Run 'bundle audit' to identify known vulnerabilities. Pin secure versions of dependencies. Implement automated dependency scanning in CI/CD pipeline.
  • Medium · Potential HTTP/HTTPS Security Issues — lib/cupertino/provisioning_portal/agent.rb. The agent module (lib/cupertino/provisioning_portal/agent.rb) likely handles HTTP communication with Apple's servers. Without visible security configuration, SSL/TLS validation, certificate pinning, or secure transport mechanisms may be missing or misconfigured. Fix: Enforce HTTPS-only communication. Implement SSL/TLS certificate validation. Consider certificate pinning for added security. Ensure no insecure HTTP fallbacks exist. Validate server certificates properly.
  • Medium · Session Management Concerns — lib/cupertino/provisioning_portal/commands/login.rb, lib/cupertino/provisioning_portal/commands/logout.rb. The login/logout commands suggest session handling, but there is no visible mechanism for secure session storage, expiration, or invalidation. Sessions could persist unnecessarily or be stored insecurely. Fix: Implement secure session tokens with expiration. Store sessions securely (encrypted, inaccessible to other users). Implement proper logout that invalidates all sessions. Use secure cookies/tokens with HttpOnly and Secure flags.
  • Low · No Visible Security Testing — Rakefile, Testing Infrastructure. The file structure shows a Rakefile and Gemfile but no apparent security testing configuration (no rubocop, brakeman, bundle-audit, or security linters visible in directory structure). Fix: Implement automated security scanning tools: brakeman for Rails-style vulnerabilities, bundle-audit for dependency vulnerabilities, and rubocop with security plugins for code quality.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · nomad-cli/cupertino — RepoPilot