NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
AppFlight CLI — upload APKs from your terminal or CI pipelines without the Play Store.
Last release 8 days ago
29 Sep 2026
Ships fairly regularly
a new release about every 2 months
Nearly every release is documented
notes for 14 of 14 stable releases
Nothing withdrawn
no release was ever pulled
5 months old
14 releases · first in 2026
One column per month.
`appflight signup` (#28) — create an AppFlight account from the terminal: full name, email, and a password with echo off, confirmed once. Creates the
appflight signup (#28) — create an AppFlight account from the terminal: full name, email, and a password with echo off, confirmed once. Creates the Firebase Auth user through the Identity Toolkit REST API, registers it with the backend, and sends the verification email. Individual accounts only — organizations still onboard in the app. Terms and privacy are captured explicitly (#69): both URLs are printed and an explicit y/N is required, with --accept-terms as the documented non-interactive path — a refusal happens before any account is created. signup mints no API key and writes no credentials file; the flow ends at "check your inbox, then appflight login". --resend <email> re-sends the verification link (it prompts for the password too, since the resend needs a fresh sign-in).
appflight login with email and password — signs in against the Identity Toolkit REST API and mints a per-machine cli:<hostname> API key server-side, so a CI key no longer requires the mobile app. A second login on the same machine rotates that key (revokes the old one, mints a fresh one); --key <raw> keeps the existing paste flow, minting and rotating nothing. login now hard-gates on email verification and mustChangePassword before touching any key.
appflight logout revokes server-side before deleting the local credentials file — the stored keyId, or a prefix match against GET /auth/api-keys for a file written by an older CLI.
appflight keys create / list / revoke — a CI key can now be minted, inspected, and revoked entirely from the terminal (#29). keys create --name <label> prints the raw key once, along with its prefix and the exact keys revoke <prefix> command — the prefix is what keys revoke takes, and is otherwise invisible until the next keys list; labels can't contain whitespace (matching the app's own rule), and the refusal suggests a hyphenated fix instead of applying one. keys list shows label, prefix, created, and last-used. keys revoke <label-or-prefix> accepts an exact label or a partial prefix (rejecting an ambiguous one) and confirms before revoking — refuses without a terminal unless --yes is passed, and refuses to revoke the key currently in use unless --force.
login --key no longer silently orphans a live cli:<hostname> key (#74) — if a password-login key is still active under a different value than the one just pasted, login now warns after saving and names the exact keys revoke <prefix> command.
appflight apps create --package <pkg> --name <name> (#30) — create a new app on AppFlight from the terminal, backed by a new GET /v1/app/list route. Derives ownerType/organizationId from your account (via whoami), so an already-onboarded, verified organization's developer can create an organization app too — previously phone-only. Organization apps require an admin or developer role, matching what the app has always offered — a plain org member is refused with exit code 9, enforced in the backend so the app and the CLI cannot diverge. 403 PLAN_LIMIT echoes the backend's own ceiling and prints how to upgrade, exiting 8.
appflight apps list (#30) — lists apps you can push to (with the N of M apps ceiling for your plan) and apps you only receive builds for, each tagged with your role and APK count.
appflight upgrade (#30) — prints where to upgrade to First Class. Works with no credentials and no network.
init offers to create an unknown package (#30) — logged in and the typed package isn't registered yet? init asks once whether to create it. Skips the prompt entirely under CI or with no terminal, and never fails init if the check itself fails.
Messages that point at the app now say where to get it (#81) — the three walls that used to end at "the AppFlight app" (no account for this email, an account that must set a password first, and an email belonging to an organization) now carry a link: the landing page when there is no account yet, the Play Store listing when the account already exists.
New exit code 9 — forbidden — a role or capability refusal, distinct from authRejected (6). Today that means an org member running apps create. CI scripts that switch on exit codes should treat it as "this account may not do that", not as a bad key.
Smaller published package — the CLI's internal CLAUDE.md is no longer shipped to pub.dev (it documented AppFlight-internal environments and release process, not anything a user needs), and the Firebase web API key is declared as a known-public identifier so pub publish stops flagging it. No behaviour change.
Native Android (Kotlin) support — appflight init now prompts for Kotlin as a third stack option (or accepts --project-type kotlin) alongside Flutter a
appflight init now prompts for Kotlin as a third stack option (or accepts --project-type kotlin) alongside Flutter and React Native. Native Android projects are validated against app/build.gradle(.kts) at the project root (no android/ wrapper).GradleParser.resolvePath resolves app/build.gradle(.kts) for Kotlin projects and android/app/build.gradle(.kts) for React Native, .kts-first in both../gradlew assemble...Release from the project root (no cd android).versionName + versionCode from root app/build.gradle(.kts), same as React Native.`project_type` added to analytics events — upload, init, and plan-limit events now include project_type: "flutter"|"react-native" so CLI usage can be
project_type added to analytics events — upload, init, and plan-limit events now include project_type: "flutter"|"react-native" so CLI usage can be segmented by framework in GA4.Anonymous usage analytics — the CLI now optionally collects anonymous usage data via GA4 to help improve the tool. You are prompted once on first run;
appflight analytics enable — opt in to analytics.appflight analytics disable — opt out at any time.appflight analytics status — show current opt-in status.Kotlin DSL support in `appflight upload` — version resolution now checks build.gradle.kts before build.gradle, and the regexes handle both Groovy (ver
appflight upload — version resolution now checks build.gradle.kts before build.gradle, and the regexes handle both Groovy (versionName "x") and Kotlin DSL (versionName = "x") syntax. Fixes React Native 0.77+ projects that use build.gradle.kts by default.React Native bare workflow support — appflight init now prompts for your framework (Flutter or React Native) or accepts --project-type flutter|react-n
appflight init now prompts for your framework (Flutter or React Native) or accepts --project-type flutter|react-native to skip the prompt. React Native projects are validated against package.json + android/app/build.gradle.android/app/build/outputs/apk/<flavor>/release/); Flutter paths are unchanged.versionName + versionCode from android/app/build.gradle and combine them as 1.2.0+7. Override with --version or --build-number as usual.upload now walks up looking for appflight.json instead of pubspec.yaml, so it works from any subdirectory in both Flutter and React Native projects.flutter build apk vs ./gradlew assemble...).projectType defaults to flutter and no changes to existing appflight.json files are required.Two-segment package names now allowed in `appflight init` — the validator previously required at least 3 dot-separated segments (e.g. com.mycompany.my
appflight init — the validator previously required at least 3 dot-separated segments (e.g. com.mycompany.myapp). Names like dev.mhmz are now accepted, matching the AppFlight mobile app and backend.Rollover uploads — First Class (pro) uploads at the APK cap now auto-drop the oldest build instead of blocking. When a rollover happens, the CLI print
Rolled over oldest build (vX.Y.Z) to stay at your plan cap.8 with the existing PLAN_LIMIT message.Default environment is now `prod` (was stage). Pasted keys from the AppFlight mobile app now work out of the box without any APPFLIGHT_ENV override. s
prod (was stage). Pasted keys from the AppFlight mobile app now work out of the box without any APPFLIGHT_ENV override. stage and local remain available via APPFLIGHT_ENV / --env for contributors hacking on the CLI or Cloud Functions.Fix appflight --version crashing with PathNotFoundException — version is now read from an embedded Dart constant instead of pubspec.yaml (which is not
appflight --version crashing with PathNotFoundException — version is now read from an embedded Dart constant instead of pubspec.yaml (which is not shipped to ~/.pub-cache/global_packages/).Added Paywall guard in cli operations
6e5e541: Fix release pipeline: use PAT for tag push to correctly trigger pub.dev publish
- --version and --docs flags
--version and --docs flagsinit — scaffold appflight.json in a Flutter project
init — scaffold appflight.json in a Flutter projectlogin — authenticate with an AppFlight API keylogout — remove saved credentialswhoami — display the authenticated userupload — upload an APK and notify testers automaticallyYour coding agent can read these notes before it upgrades. Set up the MCP server →