KasyKasy

Run the app

Use kasy run day to day. Simulator, physical device, web on port 5555, and kasy reset to test from scratch.

Implementation

  1. Recommended: always use kasy run (or the MCP). It's the complete path: loads credentials, shows the Kasy brand, and warns you when a CLI update is available.

    Via MCP: ask "run the app". The assistant asks for the platform (iOS, Android, or web) and, on web, whether you want only the URL, the default browser (openBrowser), or Flutter's isolated Chrome (flutterChrome). For a fresh onboarding test on web, use freshStorage or clear_web_storage. See Kasy MCP.

    Via terminal:

    cd your_app
    kasy run                 # first available device
    kasy run --ios           # iOS simulator
    kasy run --android       # Android emulator
    kasy run --web           # web at localhost:5555
    kasy run --web --open-browser --fresh   # default browser, storage cleared
    kasy run --web --open    # Flutter's isolated Chrome
    kasy clear-web           # clear storage only (app must already be running)
    kasy run --prod          # uses launch.json's production config
  2. To validate the first-open flow (push, onboarding, ATT, Face ID), run:

    Via MCP: "reset the app on iOS" (reset_app).

    Via terminal:

    kasy reset               # detects the device, asks if there's more than one
    kasy reset --ios
    kasy reset --android
    kasy reset --web         # clears dev storage in the browser (needs kasy run --web running)
    kasy reset -d <device-id>   # specific device (ID from flutter devices)
    kasy reset --no-reinstall   # only uninstalls

    Uninstalls the app from the simulator/emulator and reinstalls it right after. A plain flutter run keeps the data and permissions already granted, so it doesn't work for this test (details in Information).

  3. When you're ready for a release build:

    flutter build ipa --release --dart-define=ENV=prod
    # or simply:
    kasy ios release   # already injects ENV=prod and bumps the build

    Via MCP: "publish iOS" (release_ios). See Kasy MCP.

Next step: see the app running.

Information

Why not just flutter run?

kasy runflutter run
Reads the .envYesYes
Injects --dart-define from launch.jsonYesNo
Picks the right RevenueCat key (simulator vs physical)YesNo
Kasy logo + update noticeYesNo

Automatic RevenueCat key

RevenueCat has three key types, and each one only works in one place:

KeyWorks on
test_xxxiOS simulator and Android emulator
appl_xxxPhysical iPhone
goog_xxxPhysical Android

kasy run detects the device and injects the right key from the .env. You don't have to remember which one goes where.

RC_TEST_KEY=test_xxx
RC_IOS_PROD_KEY=appl_xxx
RC_ANDROID_PROD_KEY=goog_xxx

Web: which variant to pick

All of them run the same build and show the same screen, with the device preview frame included. The difference is only which window hosts the page:

CommandWhat opensWhen to use it
kasy run --web --open-browserOpens localhost:5555 in the system default browser (Chrome, Safari, Firefox, Edge…)Day to day with a saved Google account, extensions, etc.
kasy run --web --open-browser --freshSame, but clears dev storage first (localStorage, sessionStorage, IndexedDB)Test the native-like preview flow without an incognito tab
kasy clear-webOnly opens the clear URL (app already running)Quick reset without restarting Flutter
kasy run (pick Chrome in the picker) or kasy run --web --openA new, isolated Chrome window: clean profile, no extensions or saved accountsQuick QA, no leftover sessions or old data
kasy run --web (no open flags)Doesn't open anything on its own. Prints the URL (localhost:5555) in the terminalCopy the URL, open manually, or let the MCP return the link only

On the web, login stores the session by origin (domain + port), whether Supabase Auth or Firebase Auth. That's why the port is pinned at 5555: if it changed on every run, the login would seem to vanish.

If 5555 is already in use: kasy run --web --web-port 6000.

Initial screen in debug

kasy run may open on the last screen you were on (e.g., admin, components). This helps day-to-day work and hot restart (R). This isn't production behavior: in release, the app starts at Home (native) or at the URL the user opened (web). Details in Navigation → debug vs production.

Other ways (they work)

make run           # without the CLI installed globally
flutter run        # faster; uses the .env but without kasy run's extras

In VS Code, F5 uses .vscode/launch.json (with a graphical debugger).

Full log for debugging errors

kasy run records all of Flutter's output to .kasy/run.log. Paste that file to an AI when you need help.

To see the raw output directly in the terminal:

kasy run --raw           # raw output, no spinner
kasy run | tee out.log   # any pipe already falls back to raw mode automatically

What kasy reset clears on each platform

iOS simulatorPhysical iPhoneAndroid (emu/device)
SharedPreferences and local databaseYesYesYes
Push / ATT / camera permissionYesMay persist a few minutesYes
Firebase Auth (Keychain)NoNoYes

iOS Keychain persists by Apple's design, the same way WhatsApp "remembers" you after a reinstall. To test without an account on a physical device: sign out inside the app itself.

How to test "from scratch" on a physical iPhone

I want to testWhat to do
Onboarding / login flowSign out in the app. A fresh login lands on the initial flow
Push permission from scratchSettings → app → Notifications → turn off
ATT permissionSettings → Privacy → Tracking → toggle for the app
Face IDSettings → biometrics → turn the switch off and back on

Where kasy reset shines: on the iOS simulator and Android emulator, where it wipes everything (including permissions) in seconds.

Last updated on 08/02/2026