Some checks failed
relay-tripwire / cross-tenant-tripwire (push) Has been cancelled
ios / package-tests (APIClient) (push) Has been cancelled
ios / package-tests (HostRegistry) (push) Has been cancelled
ios / package-tests (SessionCore) (push) Has been cancelled
ios / package-tests (WireProtocol) (push) Has been cancelled
ios / testsupport-tests (push) Has been cancelled
ios / app-tests (push) Has been cancelled
ios / ipad-tests (push) Has been cancelled
ios / integration-tests (push) Has been cancelled
ios / ui-test (push) Has been cancelled
ios / ios17-floor-tests (push) Has been cancelled
Mirror the iOS P0+P1 client as a Gradle multi-module app. Pure-JVM (Kover ≥80% gated): :wire-protocol (frozen contract + HostEndpoint CSWSH origin + byte-exact codec), :session-core (SessionEngine + reconnect/ping/gate/digest reducers), :api-client, :client-tls (pure PKCS12/keymanager), :transport-okhttp (OkHttp WS+REST). Framework: :app (Compose M3 Adaptive, Hilt, FCM, 11 screens + NavGraph), :terminal-view (Termux terminal-emulator/-view via JitPack, Apache-2.0 — the renderer seam proven headless), :host-registry (DataStore), :client-tls-android (AndroidKeyStore + Tink). Highlights: single-key-home mTLS (non-exportable AndroidKeyStore key + re-reading X509KeyManager + connectionPool.evictAll on rotation, ping-pong single-commit so a failed rotation never clobbers the prior identity); FCM Allow/Deny trust split (Deny=BroadcastReceiver, Allow=trampoline Activity hosting BiometricPrompt); per-consumer-Channel EventBus (R10); config-surviving RetainedSessionHolder; byte-exact KeyByteMap; §5.4 pairing warning tiers. Verified: ~484 JVM tests + Kover ≥80% on the pure modules + :app assembles to an APK; all framework modules assemble. Device behaviors (rendering/IME/FCM/biometric/camera, E2E A34/A35, S2 real-handset FCM spike) deferred to android/DEVICE_QA_CHECKLIST.md per plan §7 (no emulator/Firebase here). Built via multi-agent orchestration (TDD builders → adversarial cross-review → fix → re-verify → independent gate); progress in android/PROGRESS_ANDROID.md.
181 lines
11 KiB
TOML
181 lines
11 KiB
TOML
## Version catalog — single source of truth for plugin & dependency versions.
|
|
## Pure JVM modules only (this env has NO Android SDK). See android/README.md.
|
|
## Kotlin pinned to 2.3.21 to match the Kotlin embedded in Gradle 9.6.1 (best
|
|
## compatibility with the Kotlin Gradle Plugin on Gradle 9.6).
|
|
|
|
[versions]
|
|
agp = "9.2.1"
|
|
kotlin = "2.3.21"
|
|
kotlinxSerialization = "1.9.0"
|
|
kotlinxCoroutines = "1.10.2"
|
|
junit = "5.13.4"
|
|
junitPlatform = "1.13.4"
|
|
turbine = "1.2.1"
|
|
mockk = "1.14.2"
|
|
# Kover — coverage gate on the pure JVM modules (plan A36 / section 7: >=80%).
|
|
kover = "0.9.1"
|
|
# OkHttp 4.x — plain JVM/Kotlin (NO Android SDK); used by :transport-okhttp (A7).
|
|
# MockWebServer (same version) drives A7's JVM tests. Okio arrives transitively.
|
|
okhttp = "4.12.0"
|
|
|
|
# ── Android UI stack (A13 — the :app-stack baseline; resolved against Gradle) ────
|
|
# The Compose BOM pins ALL Compose + Material3 + Material3-Adaptive artifacts, so
|
|
# those libraries below carry NO explicit version (BOM-managed → guaranteed mutual
|
|
# compatibility). BOM 2025.11.01 → material3 1.4.0 · ui/foundation 1.9.5 ·
|
|
# material3.adaptive 1.2.0 · material3-adaptive-navigation-suite 1.4.0.
|
|
#
|
|
# CEILING = compileSdk 36. The env's cmdline-tools cannot fetch platform 37, and
|
|
# the 2026 androidx line (BOM 2026.x, core 1.19, activity 1.13, lifecycle 2.11)
|
|
# requires compiling against SDK 37. So the stack is capped at the newest SDK-36
|
|
# releases. Bump these together with compileSdk 37 once the platform is installable.
|
|
composeBom = "2025.11.01"
|
|
androidxCoreKtx = "1.17.0"
|
|
androidxActivityCompose = "1.12.4"
|
|
androidxLifecycle = "2.10.0"
|
|
# Hilt 2.60.1 — its Gradle plugin references kotlin-bom 2.3.21 (matches Kotlin here).
|
|
hilt = "2.60.1"
|
|
hiltNavigationCompose = "1.2.0"
|
|
# KSP2 — the post-2.3.0 unified scheme tracks Kotlin 2.3.x (Hilt's annotation processor).
|
|
ksp = "2.3.9"
|
|
|
|
# ── Android storage + crypto (A11 :client-tls-android · A12 :host-registry) ─────
|
|
# Tink AEAD encrypts the cert-chain+metadata blob at rest (private key stays
|
|
# non-exportable in AndroidKeyStore). DataStore = host list / last-session / prefs.
|
|
tink = "1.15.0"
|
|
datastore = "1.1.1"
|
|
# ── Terminal renderer (A16 :terminal-view) ──────────────────────────────────────
|
|
# Termux terminal-emulator + terminal-view — Apache-2.0 (plan §9 R2). Consumed from
|
|
# JitPack, which builds the two Apache-2.0 submodules of github.com/termux/termux-app
|
|
# on demand. Version is the git TAG (v-prefixed). Pinned to v0.118.0 (the plan's
|
|
# default). NEVER pull termux-shared / the app module (GPLv3). terminal-view's only
|
|
# transitive deps are terminal-emulator + androidx.annotation (no guava → the R2
|
|
# listenablefuture conflict dep is unnecessary here).
|
|
termux = "v0.118.0"
|
|
# androidx-test — lets androidTest (instrumented) sources COMPILE here; they only
|
|
# RUN on a device (no emulator installed → deferred to device QA, plan §7).
|
|
androidxTestExtJunit = "1.2.1"
|
|
androidxTestCore = "1.6.1"
|
|
androidxTestRunner = "1.6.2"
|
|
# QR pairing (A19): CameraX preview/analysis + on-device ML Kit barcode scanning.
|
|
camerax = "1.4.1"
|
|
mlkitBarcode = "17.3.0"
|
|
# Push (A30) + nav/deep-links (A32). FCM via the Firebase BOM (no google-services plugin here —
|
|
# runtime init needs google-services.json, which is device-QA; classes compile without it).
|
|
firebaseBom = "33.7.0"
|
|
biometric = "1.1.0"
|
|
navigationCompose = "2.8.5"
|
|
|
|
[libraries]
|
|
# Serialization
|
|
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
|
|
|
|
# Coroutines
|
|
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
|
|
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
|
|
# The Android Main-dispatcher provider — REQUIRED at runtime by any Android module that
|
|
# references Dispatchers.Main(.immediate) (else "Module with the Main dispatcher is missing").
|
|
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
|
|
|
|
# Test — JUnit5 (Jupiter)
|
|
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
|
|
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junitPlatform" }
|
|
|
|
# Test — Flow assertions + mocking
|
|
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
|
|
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
|
|
|
# OkHttp (WS + REST) — :transport-okhttp (A7). Pure JVM.
|
|
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
|
okhttp-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" }
|
|
|
|
# ── Android UI stack (A13) — SDK-gated modules (:app etc.) only ──────────────────
|
|
# AndroidX foundation
|
|
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxCoreKtx" }
|
|
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" }
|
|
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
|
|
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
|
|
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
|
|
|
|
# Compose — the BOM governs every version below (do NOT pin these individually).
|
|
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
|
|
androidx-compose-ui = { module = "androidx.compose.ui:ui" }
|
|
androidx-compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
|
|
androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
|
|
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
|
|
androidx-compose-foundation = { module = "androidx.compose.foundation:foundation" }
|
|
androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
|
|
# Material 3 Adaptive (size-class split — SwiftUI-adaptive analogue, plan §"iPad-equivalent")
|
|
androidx-compose-material3-adaptive = { module = "androidx.compose.material3.adaptive:adaptive" }
|
|
androidx-compose-material3-adaptive-layout = { module = "androidx.compose.material3.adaptive:adaptive-layout" }
|
|
androidx-compose-material3-adaptive-navigation = { module = "androidx.compose.material3.adaptive:adaptive-navigation" }
|
|
androidx-compose-material3-adaptive-navigation-suite = { module = "androidx.compose.material3:material3-adaptive-navigation-suite" }
|
|
|
|
# Hilt (Dagger) — one shared OkHttpClient singleton + testable seams (plan §2 DI row).
|
|
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
|
|
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
|
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
|
|
|
# Storage + crypto (A11/A12)
|
|
tink-android = { module = "com.google.crypto.tink:tink-android", version.ref = "tink" }
|
|
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
|
|
|
|
# Terminal renderer (A16) — Apache-2.0 Termux libs via JitPack (see [versions].termux).
|
|
termux-terminal-view = { module = "com.github.termux.termux-app:terminal-view", version.ref = "termux" }
|
|
termux-terminal-emulator = { module = "com.github.termux.termux-app:terminal-emulator", version.ref = "termux" }
|
|
|
|
# Instrumented-test deps (androidTest source sets; compile here, run on device)
|
|
androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidxTestExtJunit" }
|
|
androidx-test-core = { module = "androidx.test:core", version.ref = "androidxTestCore" }
|
|
androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidxTestRunner" }
|
|
|
|
# QR pairing camera (A19)
|
|
androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }
|
|
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }
|
|
androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camerax" }
|
|
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }
|
|
mlkit-barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "mlkitBarcode" }
|
|
|
|
# Push (A30) + nav (A32)
|
|
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
|
|
firebase-messaging = { module = "com.google.firebase:firebase-messaging" }
|
|
androidx-biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" }
|
|
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
|
|
|
|
[bundles]
|
|
# Convenience bundle wired into every pure module's testImplementation.
|
|
unit-test = ["junit-jupiter", "kotlinx-coroutines-test", "turbine", "mockk"]
|
|
|
|
# CameraX (A19 QR pairing) — preview + analysis + PreviewView.
|
|
camerax = ["androidx-camera-core", "androidx-camera-camera2", "androidx-camera-lifecycle", "androidx-camera-view"]
|
|
|
|
# Compose UI + Material 3 (+ Adaptive) — wired into :app implementation. All
|
|
# BOM-managed; add ui-tooling separately as a debugImplementation.
|
|
compose = [
|
|
"androidx-compose-ui",
|
|
"androidx-compose-ui-graphics",
|
|
"androidx-compose-ui-tooling-preview",
|
|
"androidx-compose-foundation",
|
|
"androidx-compose-material3",
|
|
"androidx-compose-material3-adaptive",
|
|
"androidx-compose-material3-adaptive-layout",
|
|
"androidx-compose-material3-adaptive-navigation",
|
|
"androidx-compose-material3-adaptive-navigation-suite",
|
|
]
|
|
|
|
[plugins]
|
|
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
|
android-library = { id = "com.android.library", version.ref = "agp" }
|
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
|
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
|
|
# NOTE: AGP 9+ has BUILT-IN Kotlin support — Android modules apply only the
|
|
# android plugin, NOT a separate org.jetbrains.kotlin.android (it errors out).
|
|
#
|
|
# Compose compiler plugin — REQUIRED for Kotlin 2.x Compose; version MUST equal the
|
|
# Kotlin version (the compiler ships inside the Kotlin release since 2.0).
|
|
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
|
# KSP — Hilt's annotation processor runs through it.
|
|
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
|
# Hilt Gradle plugin (component-tree codegen); version tracks the hilt libraries.
|
|
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|