// ───────────────────────────────────────────────────────────────────────────── // :app — the Android application (Compose Material 3 + Adaptive design system, // Hilt DI skeleton, launcher MainActivity). Mirrors iOS App/WebTerm. // // A13 establishes the Android UI-stack version matrix for every later Android task // (the app-stack baseline, analogous to how A1 established the JVM catalog). All // UI versions are resolved in gradle/libs.versions.toml. // // Plugins (AGP 9 has BUILT-IN Kotlin → never apply org.jetbrains.kotlin.android): // com.android.application · kotlin.plugin.compose · ksp · dagger.hilt.android // ───────────────────────────────────────────────────────────────────────────── plugins { alias(libs.plugins.android.application) alias(libs.plugins.compose.compiler) alias(libs.plugins.ksp) alias(libs.plugins.hilt) } android { namespace = "wang.yaojia.webterm" // compileSdk 36 (Android 16): the contemporaneous androidx/Compose line for // Kotlin 2.3.21 requires compiling against SDK 36+ (BOM 2025.11 → ui 1.9.5). // targetSdk stays 35 per plan §2 (compileSdk ≥ targetSdk is the normal rule). compileSdk = 36 defaultConfig { applicationId = "wang.yaojia.webterm" minSdk = 29 targetSdk = 35 versionCode = 1 versionName = "0.1.0" } buildFeatures { compose = true } buildTypes { debug { // No applicationId suffix — keep it stable for deep-link testing (A32). } release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } } kotlin { jvmToolchain(17) } dependencies { // Modules A15 wires into the DI graph. implementation(project(":wire-protocol")) implementation(project(":session-core")) implementation(project(":api-client")) implementation(project(":transport-okhttp")) implementation(project(":client-tls")) // A15: bridge the mTLS device identity (:client-tls-android) onto the shared client, and // provide the DataStore-backed stores (:host-registry). :client-tls-android exposes // :client-tls via `api`, but the explicit dep above is kept for clarity. implementation(project(":client-tls-android")) implementation(project(":host-registry")) // Terminal render (A16): RemoteTerminalSession/RemoteTerminalView for the live terminal (A21) and // the raw Termux TerminalEmulator for A18's off-screen thumbnail rasterisation (§6.7). :terminal-view // scopes Termux as `implementation`, so :app names the emulator directly for the off-screen path. implementation(project(":terminal-view")) implementation(libs.termux.terminal.emulator) // QR pairing (A19): CameraX + on-device ML Kit barcode scanning. implementation(libs.bundles.camerax) implementation(libs.mlkit.barcode.scanning) // Push (A30) + nav/deep-links (A32). implementation(platform(libs.firebase.bom)) implementation(libs.firebase.messaging) implementation(libs.androidx.biometric) implementation(libs.androidx.navigation.compose) // OkHttp is `implementation` (not `api`) in :transport-okhttp, so :app names OkHttpClient / // ConnectionPool directly in NetworkModule/TlsModule. implementation(libs.okhttp) // Coroutines are used directly by the wiring (EventBus fan-out, engine confinement scope). implementation(libs.kotlinx.coroutines.core) // Preferences DataStore is named in StorageModule's @Provides return types. implementation(libs.androidx.datastore.preferences) // AndroidX foundation implementation(libs.androidx.core.ktx) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.lifecycle.viewmodel.compose) // Compose (the BOM governs every version below) implementation(platform(libs.androidx.compose.bom)) implementation(libs.bundles.compose) debugImplementation(libs.androidx.compose.ui.tooling) // Hilt (Dagger) — KSP annotation processing implementation(libs.hilt.android) ksp(libs.hilt.compiler) implementation(libs.androidx.hilt.navigation.compose) // JVM unit tests (no device) — the frozen design-token spec, EventBus fan-out, and the // RetainedSessionHolder lifecycle invariant driven by a fake transport under virtual time. testImplementation(libs.bundles.unit.test) testImplementation(project(":test-support")) // FakeTermTransport for the holder lifecycle test (FIX 6) testRuntimeOnly(libs.junit.platform.launcher) } // Local (JVM) unit tests run on the JUnit 5 platform, matching the pure modules. tasks.withType().configureEach { useJUnitPlatform() }