command reference · v0.4.1

Every command.
One page.

Grouped by what you're trying to do. Each command tells you when to reach for it, what it runs, and every flag it takes.

Start here

I want to…

Match your goal to a command, then jump to its full reference.

Before anything

First-time setup

Three things, once. After that every command works from any directory.

  1. Install — one paste, then open a new terminal:
    $ curl -fsSL https://gist.githubusercontent.com/itsTowhid/b3480287bb8c243360f6802f9efd261a/raw/install.sh | bash
  2. Point it at the project — first run asks for the folder holding pubspec.yaml with name: gcpay and remembers it (~/.config/tahweel). Run any command from inside the project and it saves automatically.
  3. Tools per commandfirebase + jq for builds, shorebird for production, python3 for taskboard listing. Each command checks and tells you what's missing before doing anything.

Alias: twl works everywhere tahweel does.

Category 01

Build & release

The release cycle in three commands: test build → store release → force update.

$ tahweel build FIREBASE

Builds a test version and gets it to testers. Android uploads straight to Firebase App Distribution; iOS builds for TestFlight (upload via Transporter).

Use it when a tester, manager, or QA needs the latest changes on a device — not when you're shipping to the stores (that's production).
$ tahweel build android --notes "<release note>" # non-interactive
$ tahweel build ios                          # non-interactive
$ tahweel build                              # interactive: asks platform, flavor, sharing, note
Option What it does
-n, --notes "<text>" Release note for this build. Required on Android — no mystery APKs.
-b, --boss Share with BOSS + MANAGER tester groups.
-m, --manager Share with MANAGER only.
-u, --upload-only Skip the build; upload the APK already on disk.
-p, --prod Build the prod flavor (default: stage).
-f, --flavor <name> Explicit flavor: stage | prod.
-c, --clean Run flutter clean first (deep clean on iOS).
--dry-run Print the plan; build and upload are skipped.
$ tahweel build android --notes "Fixed OTP retry crash"
$ tahweel build android --prod --boss --notes "Card freeze fix"
$ tahweel build ios --prod

Build numbers live in Firebase RTDB per flavor + version and advance only after a successful upload — a failed build never burns a number. iOS tracks its own ios key; no notes or tester flags apply there.

$ tahweel lazy_build REMOTE QUEUE

Runs the whole Android build on the VPS. Zips the current project, uploads it to the build server, and an Ubuntu box builds the APK and pushes it to Firebase App Distribution — exactly like build, but nothing runs on your machine.

Use it when you don't have (or don't want to wait on) a local Flutter / Android / Firebase toolchain — a teammate on any laptop, a quick fix between meetings, or a machine that just can't build. Android only for now (the build server is Ubuntu).
$ tahweel lazy_build --notes "<release note>"        # queue and return immediately
$ tahweel lazy_build --notes "<note>" --watch      # stay attached, stream the log
$ tahweel lazy_build --cancel 42                 # cancel by id (queued OR running)
$ tahweel lazy_build --status                   # your recent builds, or one + its log
Option What it does
-n, --notes "<text>" Release note for this build. Required.
-p, --prod Build the prod flavor (default: stage).
-b, --boss Share with BOSS + MANAGER tester groups.
-m, --manager Share with MANAGER only.
-w, --watch Stay attached and stream the build log (default: detach right after upload).
--cancel <id> Cancel a queued or running build; the server kills it and cleans up the uploaded code.
--status [id] List recent builds, or show one build with its log tail.
--dry-run Print the plan (flavor / sharing / notes); nothing is uploaded.
$ tahweel lazy_build --notes "Fixed OTP retry crash"
$ tahweel lazy_build --prod --boss --notes "Card freeze fix"
$ tahweel lazy_build --notes "Quick fix" --watch

One-time setup: tahweel config set TAHWEEL_QUEUE_URL https://twl.towhid.space and tahweel config set TAHWEEL_QUEUE_TOKEN <your-token>. Each teammate gets their own token — builds run on the VPS, and nobody needs SSH access to it. You must also be signed in via firebase login with an authorized team account, or the build is refused. Every build gets a simple numeric id (e.g. 42) you can cancel or check any time; cancelling wipes the uploaded code from the server. Status changes are announced in the team Telegram group, and --status shows your own recent builds.

$ tahweel production SHOREBIRD

Builds the store release: an AAB for Google Play or an IPA for the App Store, via Shorebird — then opens the Play Console or Transporter plus the output folder for you.

Use it when the version in pubspec.yaml is final and you're publishing to the stores. Flavor is always prod; version + build number are taken from pubspec.yaml as-is — nothing is incremented.
$ tahweel production          # interactive platform picker (default android)
$ tahweel production android  # AAB → opens Play Console + output folder
$ tahweel production ios      # IPA → opens Transporter + output folder
Option What it does
android / -a, --android Build the Android AAB.
ios / -i, --ios Build the iOS IPA. Deep-cleans (DerivedData, Pods) and resets CocoaPods first.
$ tahweel production android

$ tahweel patch SHOREBIRD OTA

Pushes an over-the-air code patch to a version that's already released — a hotfix that skips store review and lands on users' next app launch. Same Shorebird toolchain as production.

Use it when a bug is live and you need the fix out now without a full store release. Only Dart code ships in a patch — native or dependency changes still need production. Patches the release matching pubspec.yaml, so cut that release first.
$ tahweel patch          # interactive platform picker (default android)
$ tahweel patch android  # OTA patch to the current Android release
$ tahweel patch ios      # OTA patch to the current iOS release
Option What it does
android / -a, --android Patch the Android release.
ios / -i, --ios Patch the iOS release. Deep-cleans (DerivedData, Pods) and resets CocoaPods first.
$ tahweel patch android

Flavor is always prod; version + build come from pubspec.yaml as-is. Because a patch reaches production users immediately, it confirms before pushing. Flutter version is 3.44.3 unless overridden via tahweel config set TAHWEEL_FLUTTER_VERSION.

$ tahweel force_update REMOTE CONFIG

Sets the minimum required app version and/or the release note in Firebase Remote Config — the thing that pops the “please update” screen on users' phones.

Use it when a release is live in the stores and old versions must upgrade. It's safe by default: edits only the local template (remoteconfig.template.json) — nothing goes live without --deploy. Review first with changes.
$ tahweel force_update <platform> <flavor> -v <version>  # set minimum_version
$ tahweel force_update <platform> <flavor> --current     # use pubspec.yaml's version
$ tahweel force_update <platform> <flavor> -n "note"      # set release note
$ tahweel force_update changes [flavor]                  # preview local vs. live
$ tahweel force_update changes --reset                   # discard local, re-fetch live
Option What it does
<platform> <flavor> android | ios, then prod | stage. Required (except changes).
-v, --version <X.Y.Z> Minimum version to enforce (semver).
--current Use the version name from pubspec.yaml instead of typing one.
-n, --note <text> Release note. \n or real newlines become “• ” bullets; auto-translated to fr, ar, tr via the agy CLI.
--deploy Publish live. Without it, changes stay in the local template.
--reset Discard the local template and re-fetch from live Remote Config.
$ tahweel force_update android prod --current --deploy
$ tahweel force_update android stage -n "Fixed login bug\nFaster startup"
$ tahweel force_update changes

Parameter mapping: prodandroid_config / ios_config; stagestg_android_config / stg_ios_config. The safe workflow: edit locally → changes to diff against live → re-run with --deploy.

Category 02

Project & maintenance

When the build is haunted, or the CLI needs to know where the project lives.

$ tahweel clean DEEP CLEAN

From a quick flutter clean to the full exorcism: DerivedData, Pods, pod reinstall on iOS; Gradle cache + gradlew clean on Android.

Use it when a build fails for no reason, behaves stale, or “works on my machine” strikes. Start with plain clean; escalate to ios / android / all when the quick one doesn't cure it.
$ tahweel clean          # flutter clean (default)
$ tahweel clean ios      # + DerivedData, Pods, pods reset
$ tahweel clean android  # + Gradle cache, gradlew clean
$ tahweel clean all      # everything above
Target What gets cleaned
flutter (default) flutter clean only.
ios flutter clean + DerivedData, Pods removal, pods reset.
android flutter clean + Gradle cache, gradlew clean.
all flutter + iOS deep clean + Android deep clean.
$ tahweel clean all
Category 03

Taskboard

The GCB Status board without leaving the terminal. Log in once — only the session cookie is stored, never your password.

$ tahweel login / logout TASKBOARD

Signs in to the taskboard and saves the session so tasks and status just work. logout clears it.

Use it once before any taskboard command, or again when the session expires (expired sessions prompt a re-login and resume your command automatically). Prefer --browser if password login hits a reCAPTCHA.
$ tahweel login [email]     # password prompt in the terminal (never stored)
$ tahweel login --browser   # sign in on the site, paste its cookies — no password in the CLI
$ tahweel logout            # clear the saved session
Option What it does
[email] Pre-fill the email; you'll only type the password.
--browser Log in on the real site; the browser handles the CDN bot-check and you paste the session cookies. Handy when credential login is reCAPTCHA-blocked.
$ tahweel login --browser

$ tahweel tasks TASKBOARD

Lists your tasks, starts one, or marks one done — with a completion note, because “done” without context helps no one.

Use it for the daily loop: check the board in the morning, start what you pick up, end it with a note when it ships.
$ tahweel tasks [--completed] [--page N]  # list tasks
$ tahweel tasks start <id>                # start a task
$ tahweel tasks end <id> [note]           # finish a task (note required)
Option What it does
(default) Active / pending / running tasks.
--completed Completed (done) tasks instead.
--page N Page N of results (default 1).
--json Raw task rows as TSV (id, status, title, project, deadline) — for scripting.
$ tahweel tasks
$ tahweel tasks start 6949
$ tahweel tasks end 6949 "Shipped in 1.2.0"

$ tahweel status TASKBOARD

Shows or sets your availability on the board.

Use it at the start and end of your working block — no need to open the site just to flip a toggle.
$ tahweel status            # show current availability
$ tahweel status available  # go online
$ tahweel status offline    # go offline
$ tahweel status available
Category 04

The CLI itself

Settings, staying current — or removing it cleanly.

$ tahweel config

View and edit every saved setting in one place, instead of hunting through separate commands. All settings live in one file under ~/.config/tahweel.

Use it to check the current project directory, set the build-queue URL/token, or set a notification webhook — without editing files by hand.
$ tahweel config                 # show all settings + where they live
$ tahweel config get <key>        # print one value
$ tahweel config set <key> <val>  # change a setting
$ tahweel config unset <key>      # clear a setting
$ tahweel config path            # print the config file path
$ tahweel config edit            # open it in $EDITOR
Key What it controls
SAVED_PROJECT_DIR Project root (also set by tahweel setup).
TAHWEEL_WEBHOOK_URL Slack/Discord webhook to notify after a build/release.
TAHWEEL_QUEUE_URL Remote build server base URL for lazy_build (e.g. https://twl.towhid.space).
TAHWEEL_QUEUE_TOKEN Your personal API token for the remote build queue.
TAHWEEL_ANALYTICS Set to off to disable the anonymous usage ping.
$ tahweel config set TAHWEEL_QUEUE_TOKEN <token>

$ tahweel update

Re-runs the installer to pull the latest version — or pins an exact Gist revision.

Use it whenever a new version ships. Pin a SHA if you need to roll back or stay on a known-good revision.
$ tahweel update         # latest
$ tahweel update <sha>   # exact gist commit
$ tahweel update

$ tahweel uninstall

Removes tahweel, the twl symlink, all installed files, and the PATH entry the installer added.

$ tahweel uninstall                # remove everything
$ tahweel uninstall --keep-config  # keep ~/.config/tahweel (project dir, session)

$ tahweel version / help

version prints the installed version and warns if a newer one is published (best-effort, silent offline). help shows the top-level usage — and every major command answers --help with its own detailed page:

$ tahweel build --help
$ tahweel production --help
$ tahweel force_update --help
$ tahweel clean --help
$ tahweel tasks --help