Skip to content

App Store Connect from your terminal & Agents. A Swift CLI for managing your iOS and macOS apps on App Store Connect. Submit versions, manage screenshots, track builds — with full AI-agent support via CAEOAS affordances.

Notifications You must be signed in to change notification settings

tddworks/asc-cli

Repository files navigation

asc-cli

CI codecov Swift Platform

A CLI for App Store Connect — automate builds, releases, TestFlight, subscriptions, and screenshots from your terminal or CI pipeline. Outputs structured JSON so AI agents can drive the full release workflow.

Quick Start

brew install tddworks/tap/asccli

asc auth login \
  --key-id YOUR_KEY_ID \
  --issuer-id YOUR_ISSUER_ID \
  --private-key-path ~/.asc/AuthKey_XXXXXX.p8

asc apps list          # find your app ID
asc init --app-id <id> # pin it — skip --app-id on every future command

Features

Category What you can do
Apps & Versions List apps, create versions, link builds, submit for App Store review
Builds Upload IPA/PKG, wait for processing, distribute to TestFlight, update beta notes
Metadata Update What's New, description, and keywords per locale
App Info Set per-locale name, subtitle, privacy policy; manage categories and age rating
Screenshots Create screenshot sets and upload images
App Previews Upload video previews (.mp4, .mov, .m4v) per locale and device size
App Shots AI-powered screenshot generation via Gemini; translate to any locale in one command
TestFlight Manage beta groups; add/remove/import/export testers
Monetization IAPs (consumable, non-consumable, non-renewing); subscriptions, offers, pricing
Code Signing Bundle IDs, certificates, devices, provisioning profiles
Project Init asc init pins app context to .asc/project.json; auto-detects from .xcodeproj
Plugins Install executable plugins in ~/.asc/plugins/ for custom event handlers
AI Agents JSON output with CAEOAS affordances — agents navigate without knowing the command tree

Requirements

  • macOS 13+
  • App Store Connect API key (create one here)
  • Swift 6.2+ (only needed when building from source)

Installation

Homebrew (recommended)

brew install tddworks/tap/asccli

Build from source

git clone https://github.com/tddworks/asc-cli.git
cd asc-cli
swift build -c release
cp .build/release/asc /usr/local/bin/

Authentication

Persistent login (recommended)

asc auth login \
  --key-id YOUR_KEY_ID \
  --issuer-id YOUR_ISSUER_ID \
  --private-key-path ~/.asc/AuthKey_XXXXXX.p8

asc auth check   # → shows source: "file"
asc auth logout  # remove saved credentials

Credentials are saved to ~/.asc/credentials.json. All asc commands pick them up automatically — no environment variables needed per session.

Environment variables (alternative)

export ASC_KEY_ID="YOUR_KEY_ID"
export ASC_ISSUER_ID="YOUR_ISSUER_ID"
export ASC_PRIVATE_KEY_PATH="~/.asc/AuthKey_XXXXXX.p8"
# or: export ASC_PRIVATE_KEY="<PEM content>"

Resolution order: ~/.asc/credentials.json → environment variables.

Command Reference

Auth & Project

asc auth login --key-id <id> --issuer-id <id> --private-key-path <path>
asc auth check
asc auth logout

asc init                     # auto-detect app from *.xcodeproj bundle ID
asc init --name "My App"     # search by name
asc init --app-id <id>       # pin directly — no API call needed

Apps & Versions

asc apps list
asc versions list --app-id <id>
asc versions create --app-id <id> --version <v> --platform ios
asc versions set-build --version-id <id> --build-id <id>
asc versions check-readiness --version-id <id>
asc versions submit --version-id <id>
asc version-review-detail get --version-id <id>
asc version-review-detail update --version-id <id> --contact-first-name Jane --contact-email dev@example.com

Builds & TestFlight

asc builds list [--app-id <id>]
asc builds upload --app-id <id> --file MyApp.ipa --version 1.0.0 --build-number 42
asc builds uploads list --app-id <id>
asc builds uploads get --upload-id <id>
asc builds uploads delete --upload-id <id>
asc builds add-beta-group --build-id <id> --beta-group-id <id>
asc builds remove-beta-group --build-id <id> --beta-group-id <id>
asc builds update-beta-notes --build-id <id> --locale en-US --notes "What's new"

asc testflight groups list [--app-id <id>]
asc testflight testers list --beta-group-id <id>
asc testflight testers add --beta-group-id <id> --email user@example.com
asc testflight testers remove --beta-group-id <id> --tester-id <id>
asc testflight testers import --beta-group-id <id> --file testers.csv
asc testflight testers export --beta-group-id <id>

Metadata

# Version localizations (What's New, description, keywords)
asc version-localizations list --version-id <id>
asc version-localizations create --version-id <id> --locale zh-Hans
asc version-localizations update --localization-id <id> --whats-new "Bug fixes"

# App info localizations (name, subtitle, privacy policy)
asc app-infos list --app-id <id>
asc app-infos update --app-info-id <id> --primary-category GAMES --primary-subcategory-one GAMES_ACTION
asc app-categories list [--platform IOS]
asc app-info-localizations list --app-info-id <id>
asc app-info-localizations create --app-info-id <id> --locale zh-Hans --name "我的应用"
asc app-info-localizations update --localization-id <id> --name "My App" --subtitle "Do things faster"
asc app-info-localizations delete --localization-id <id>

# Age rating
asc age-rating get --app-info-id <id>
asc age-rating update --declaration-id <id> --violence-realistic NONE --gambling false --kids-age-band NINE_TO_ELEVEN

Screenshots & Previews

# Screenshots
asc screenshot-sets list --localization-id <id>
asc screenshot-sets create --localization-id <id> --display-type APP_IPHONE_67
asc screenshots list --set-id <id>
asc screenshots upload --set-id <id> --file ./screen.png

# Video previews
asc app-preview-sets list --localization-id <id>
asc app-preview-sets create --localization-id <id> --preview-type IPHONE_67
asc app-previews list --set-id <id>
asc app-previews upload --set-id <id> --file ./preview.mp4 [--preview-frame-time-code 00:00:05]

App Shots (AI screenshot generation)

asc app-shots config --gemini-api-key KEY               # save key once

asc app-shots generate                                   # iPhone 6.9" at 1320×2868 (default)
asc app-shots generate --device-type APP_IPHONE_67      # iPhone 6.7"
asc app-shots generate --device-type APP_IPAD_PRO_129   # iPad 13"
asc app-shots generate --style-reference ~/ref.png      # match visual style of reference image

asc app-shots translate --to zh --to ja                 # localize all screens in parallel
asc app-shots translate --to ko --device-type APP_IPHONE_67
asc app-shots translate --to zh --style-reference ~/ref.png

Monetization

# In-App Purchases
asc iap list --app-id <id>
asc iap create --app-id <id> --reference-name <n> --product-id <id> --type consumable
asc iap submit --iap-id <id>
asc iap price-points list --iap-id <id> [--territory USA]
asc iap prices set --iap-id <id> --base-territory USA --price-point-id <id>
asc iap-localizations list --iap-id <id>
asc iap-localizations create --iap-id <id> --locale en-US --name <n>

# Subscriptions
asc subscription-groups list --app-id <id>
asc subscription-groups create --app-id <id> --reference-name <n>
asc subscriptions list --group-id <id>
asc subscriptions create --group-id <id> --name <n> --product-id <id> --period ONE_MONTH
asc subscriptions submit --subscription-id <id>
asc subscription-localizations list --subscription-id <id>
asc subscription-localizations create --subscription-id <id> --locale en-US --name <n>
asc subscription-offers list --subscription-id <id>
asc subscription-offers create --subscription-id <id> --duration ONE_MONTH --mode FREE_TRIAL --periods 1
asc subscription-offers create --subscription-id <id> --duration THREE_MONTHS --mode PAY_AS_YOU_GO --periods 3 --price-point-id <id>

Code Signing

asc bundle-ids list [--platform ios|macos|universal] [--identifier com.example.app]
asc bundle-ids create --name "My App" --identifier com.example.app --platform ios
asc bundle-ids delete --bundle-id-id <id>

asc certificates list [--type IOS_DISTRIBUTION]
asc certificates create --type IOS_DISTRIBUTION --csr-content "$(cat MyApp.certSigningRequest)"
asc certificates revoke --certificate-id <id>

asc devices list [--platform ios|macos]
asc devices register --name "My iPhone" --udid <udid> --platform ios

asc profiles list [--bundle-id-id <id>] [--type IOS_APP_STORE]
asc profiles create --name "My Profile" --type IOS_APP_STORE --bundle-id-id <id> --certificate-ids <id>
asc profiles delete --profile-id <id>

Plugins

asc plugins list
asc plugins install ./my-plugin
asc plugins uninstall --name slack-notify
asc plugins enable --name slack-notify
asc plugins disable --name slack-notify
asc plugins run --name slack-notify --event build.uploaded

Output & TUI

asc apps list                        # JSON (default)
asc apps list --output table         # aligned table
asc apps list --output markdown      # markdown table
asc apps list --output json --pretty # pretty-printed JSON

asc tui   # interactive browser — arrow keys, Enter to drill in, Escape to go back

Release Workflow

A full App Store release from build upload to review submission:

# 1. Upload build and wait for processing
asc builds upload --app-id APP_ID --file ./MyApp.ipa --version 1.2.0 --build-number 55 --wait

# 2. Distribute to TestFlight
GROUP_ID=$(asc testflight groups list --app-id APP_ID | jq -r '.data[0].id')
BUILD_ID=$(asc builds list --app-id APP_ID | jq -r '.data[0].id')
asc builds add-beta-group --build-id "$BUILD_ID" --beta-group-id "$GROUP_ID"
asc builds update-beta-notes --build-id "$BUILD_ID" --locale en-US --notes "What's new in 1.2.0"

# 3. Prepare the App Store version
VERSION_ID=$(asc versions list --app-id APP_ID | jq -r '.data[0].id')
asc versions set-build --version-id "$VERSION_ID" --build-id "$BUILD_ID"

# 4. Update What's New
LOC_ID=$(asc version-localizations list --version-id "$VERSION_ID" | jq -r '.data[0].id')
asc version-localizations update --localization-id "$LOC_ID" --whats-new "Bug fixes and performance improvements"

# 5. Pre-flight check, then submit
asc versions check-readiness --version-id "$VERSION_ID" --pretty
asc versions submit --version-id "$VERSION_ID"

Feature Guides

Detailed documentation for each feature:

Design: CAEOAS

REST has HATEOAS — responses embed URLs so clients navigate without knowing the API. This CLI has CAEOAS (Commands As the Engine Of Application State): responses embed ready-to-run CLI commands so agents navigate without memorising the command tree.

$ asc versions list --app-id app-abc
{
  "id": "v1",
  "versionString": "2.1.0",
  "state": "PREPARE_FOR_SUBMISSION",
  "isEditable": true,
  "affordances": {
    "listLocalizations": "asc version-localizations list --version-id v1",
    "checkReadiness":    "asc versions check-readiness --version-id v1",
    "submitForReview":   "asc versions submit --version-id v1"  // only when isEditable == true
  }
}

Affordances are state-aware — submitForReview only appears when isEditable == true. See docs/design.md for the full pattern.

Development

swift build          # build
swift test           # run tests (Chicago School TDD)
swift format --in-place --recursive Sources Tests

Architecture:

Sources/
├── Domain/          # Pure value types, @Mockable protocols — zero I/O
├── Infrastructure/  # SDK adapters (appstoreconnect-swift-sdk), parent ID injection
└── ASCCommand/      # CLI commands, output formatting, TUI

Unidirectional dependency: ASCCommand → Infrastructure → Domain

Dependencies:

See CHANGELOG.md for version history.

Sponsors

Apps that use and support asc-cli development:

AppNexus
AppNexus for App Store Connect

App Wall

Apps built and published using asc-cli. To add yours, edit homepage/apps.json and open a pull request — see docs/features/app-wall.md for the format.

View the live wall at asccli.app/#app-wall.

License

MIT

About

App Store Connect from your terminal & Agents. A Swift CLI for managing your iOS and macOS apps on App Store Connect. Submit versions, manage screenshots, track builds — with full AI-agent support via CAEOAS affordances.

Topics

Resources

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors