Files
fusion/MOBILE.md
gsxdsm bc38f0c842 FN-7209: require JDK 21 for Android CI builds
Align Android Gradle build environments with Capacitor's Java 21 source compatibility.

- Update mobile, release, and test-release workflows to provision Temurin JDK 21.
- Document Java 21 as the required Android Gradle build JDK.
- Add CI workflow coverage that checks Android build jobs satisfy @capacitor/android sourceCompatibility.

Files changed:
 .github/workflows/mobile.yml                   |  6 +-
 .github/workflows/release.yml                  |  6 +-
 .github/workflows/test-release.yml             |  6 +-
 MOBILE.md                                      |  4 +-
 packages/cli/src/__tests__/ci-workflow.test.ts | 99 +++++++++++++++++++++++++-
 5 files changed, 112 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7209

Fusion-Task-Lineage: d9e50bee-d7f8-4e87-b33e-136ffffc93af

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-28 16:56:35 -07:00

7.6 KiB

Mobile Development Guide

Fusion mobile builds package the dashboard web client into Capacitor shells via packages/mobile/.

Prerequisites

  • Node.js 22+
  • pnpm 10+
  • Xcode (iOS builds)
  • Android Studio (Android SDK + emulator tooling)
  • Java JDK 21+ (Android Gradle builds)

Quick Start

pnpm install
pnpm mobile:build
pnpm mobile:ios      # open iOS project in Xcode
# or
pnpm mobile:android  # open Android project in Android Studio

Development with Live Reload

Use the live-reload helpers in packages/mobile/scripts/live-reload.ts:

pnpm mobile:dev:ios
pnpm mobile:dev:android

These commands automatically set:

  • FUSION_LIVE_RELOAD=true
  • FUSION_SERVER_URL=http://localhost:5173 (default)

To target a different dev server URL, set FUSION_SERVER_URL before running (or pass --server-url directly to the script):

FUSION_SERVER_URL=http://192.168.1.50:5173 pnpm mobile:dev:android

Building for Production

pnpm mobile:build

This runs:

  1. pnpm --filter @fusion/dashboard build
  2. pnpm --filter @fusion/mobile cap sync

After sync, open native projects for release signing/distribution:

pnpm mobile:ios
pnpm mobile:android

PWA Installation

The dashboard includes a PWA manifest (packages/dashboard/app/public/manifest.json) and service worker (packages/dashboard/app/public/sw.js).

Standalone iOS home-indicator spacing

  • Installed standalone mode sets --standalone-bottom-gap via @media (display-mode: standalone) { :root { ... } }.
  • Bottom spacing must stay scoped to layout/component rules (for example mobile content padding and footer/nav offsets), not global #root padding.
  • Keep standalone spacing additive with existing safe-area handling (env(safe-area-inset-bottom, 0px)).
  • The .project-content wrapper is the single source of truth for mobile-nav/footer/standalone bottom reservation; inline dashboard tabs (for example Agents and Missions) must only apply their own content padding and must not re-add --mobile-nav-height or duplicate footer spacing.

Install from browser:

  • Chrome: three-dot menu → Install app
  • Safari (iOS): Share → Add to Home Screen

Service workers require HTTPS (or localhost). PWA install/offline behavior will not work on plain HTTP origins.

Mobile UX Behavior

Native shell onboarding and connection profiles

First launch in the mobile shell enters a shell-level remote connection onboarding flow before dashboard model onboarding.

For the canonical flow (QR/manual setup, saved profiles, active-profile behavior, and security caveats), see Native Shell Connection Guide.

Implementation notes:

  • Mobile shell profiles are persisted in shell-local storage (Capacitor Preferences), separate from Fusion project/global settings.
  • Active-profile deletion fallback is shell-owned: deleting the active profile promotes the first remaining profile, and deleting the final profile resets to a clean empty state.
  • The dashboard consumes this through the shared window.fusionShell connection APIs.

Planning Mode

Planning Mode opens directly into the composer pane on mobile when no planning sessions exist, avoiding an empty-sidebar dead end. On desktop/tablet the split view is unaffected. Once sessions are saved, mobile shows the session list as usual and the user can navigate between list and detail panes.

Chat and Quick Chat mobile scroll/readability behavior

  • Chat and Quick Chat must keep scrolling container-scoped (.chat-messages / .quick-chat-panel-messages) and must not switch to page-level scroll APIs (including scrollIntoView()) to avoid mobile Safari viewport drift.
  • Full Chat direct-thread mobile headers include a title-triggered quick session switcher; preserve one-pane behavior (back-to-list still works) and keep the switcher scoped to direct sessions only (room threads keep existing room header/back behavior).
  • Both surfaces now pause live-tail autoscroll when the user scrolls away from bottom, show a temporary Latest jump control, and resume tail-follow only after jumping back.
  • Mobile bubble widths are intentionally slightly wider for readability, but safe-area padding, full-screen Quick Chat bounds, and compact mobile tool-call summaries must remain intact.

CI/CD Pipeline

Mobile CI is defined in .github/workflows/mobile.yml.

  • Trigger manually via GitHub Actions → Mobile Builds → Run workflow
  • Also runs on push to main when files under packages/mobile/** or packages/dashboard/** change
  • Jobs:
    • build-web (build dashboard and upload dist/client)
    • build-ios (sync/build iOS when packages/mobile/ios/ exists)
    • build-android (sync/build Android when packages/mobile/android/ exists)

Artifacts from the Mobile Builds workflow are retained for 30 days. Tagged binary releases also run the Android build leg in .github/workflows/release.yml; .github/workflows/test-release.yml mirrors that path in its tag-less rehearsal artifact.

When the repository has Android signing secrets configured (ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD), the release pipeline publishes signed fusion-android-release.apk and fusion-android-release.aab assets plus .sha256 checksums. Without those secrets, the pipeline preserves the secret-free fallback and publishes the unsigned debug APK as fusion-android.apk plus fusion-android.apk.sha256.

Install the signed APK by enabling Install unknown apps for the transfer source on the device, then sideloading it:

adb install fusion-android-release.apk

Verify the APK signer before distribution when Android SDK build-tools are available:

apksigner verify --print-certs fusion-android-release.apk

The .aab file is for Play distribution and is not directly sideloadable with adb install. Automated Play Store / Play Console upload remains out of scope for now because it needs a Google service-account JSON secret, a published Play listing, and fastlane or r0adkll/upload-google-play wiring; that work is tracked separately in FN-7043 from the sideload-first release assets.

Replacing PWA Icons

Current icons are placeholders:

  • packages/dashboard/app/public/icons/icon-192.png
  • packages/dashboard/app/public/icons/icon-512.png

Generate production icons from logo.svg (example with sharp-cli):

npx sharp-cli -i packages/dashboard/app/public/logo.svg -o packages/dashboard/app/public/icons/icon-192.png resize 192 192
npx sharp-cli -i packages/dashboard/app/public/logo.svg -o packages/dashboard/app/public/icons/icon-512.png resize 512 512

You can also use ImageMagick if preferred.

Troubleshooting

cap sync fails

  • Confirm dependencies are installed: pnpm install
  • Ensure platform projects have been added (packages/mobile/ios / packages/mobile/android)
  • Re-run: pnpm mobile:sync

iOS build fails

  • Verify Xcode version/toolchain compatibility
  • Open packages/mobile/ios/App/App.xcworkspace in Xcode and resolve signing settings

Android build fails

  • Verify Java 21+ (java -version)
  • Confirm Android SDK and Gradle tooling are installed via Android Studio

PWA does not install

  • Verify HTTPS (or localhost)
  • Confirm manifest.json and sw.js are served from the built app
  • Clear old service worker/cache and reload

Script Reference

Root scripts (package.json):

  • mobile:build
  • mobile:ios
  • mobile:android
  • mobile:dev:ios
  • mobile:dev:android
  • mobile:sync

Mobile package scripts (packages/mobile/package.json):

  • cap
  • dev:ios
  • dev:android
  • build:mobile