imux · 龍imux
AI workbench for macOS

Mobile update channel

Mobile uses a first-class release channel, not ad-hoc APK links. Clients poll a versioned JSON manifest, compare integer build numbers, and prompt (or force) install. This is separate from imux macOS Sparkle updates.

Manifest

Canonical URL:

  • version — semver string (display)
  • versionCode — Android integer; primary upgrade key
  • iosBuildNumber / downloads.ios.buildNumber — iOS CFBundleVersion
  • downloads.android.apk — HTTPS APK URL
  • downloads.ios.appStore / testFlight — when published
  • downloads.ios.ipa — App Store signed archive URL (not sideload)
  • forceUpdate / minVersionCode — block dismiss when required
  • changelog[] — modal and download page copy
  • packageId — com.clavue.xw
GET https://www.clavue.com/downloads/mobile/latest-mobile.json
# Cache-bust query: ?_=<timestamp> (app always appends)

Client behavior

  • Cold start: force network check
  • App resume: throttled (default 6h, overridable via checkIntervalHours)
  • Settings → Check for updates: force network, ignore dismiss
  • Local notification channel app-updates (once per remote versionCode)
  • Dismiss stores dismissedVersionCode until a higher remote code appears

Publish a build

versionCode must strictly increase for same package id. Changing package id (e.g. com.clavue.mobile → com.clavue.xw) is a new app — users reinstall.
cd clavue-mobile
./scripts/publish-android-release.sh --bump patch --deploy \
  --notes "修复说明;第二条 changelog"

# Force users below a floor:
./scripts/publish-android-release.sh --bump patch --deploy --force-update

iOS releases

Archive + export App Store IPA (sync CFBundleShortVersionString / CFBundleVersion with app.json first). Upload with Transporter. Host a copy under /downloads/mobile/clavue-mobile-vX.Y.Z-ios.ipa and set downloads.ios.ipa + buildNumber + status ready_for_app_store. After the listing is live, set downloads.ios.appStore and status published. See clavue-mobile/IOS_RELEASE.md.

Next