Native Android client for chepherd-rc. Kotlin 2.0+, Jetpack Compose, Material 3.
Privacy by default — pairs to your bastion daemon over WebRTC DataChannel. Relay only sees the signaling handshake. Your data is your data.
chepherd-rc-android/
├── settings.gradle.kts # root settings
├── build.gradle.kts # root build
├── gradle.properties
├── core/
│ ├── protocol/ # wire shapes (kotlinx.serialization)
│ │ └── src/main/kotlin/io/chepherd/rc/protocol/
│ │ ├── Envelope.kt
│ │ ├── SequenceCounter.kt
│ │ └── Payloads.kt
│ ├── transport/ # Transport interface + impls
│ │ └── src/main/kotlin/io/chepherd/rc/transport/
│ │ ├── Transport.kt
│ │ ├── WSTransport.kt
│ │ ├── WebRTCTransport.kt
│ │ ├── SignalingClient.kt
│ │ └── Factory.kt
│ ├── auth/ # OAuth2 PKCE flow
│ │ └── src/main/kotlin/io/chepherd/rc/auth/
│ │ ├── PKCE.kt
│ │ ├── Auth.kt # AppAuth-based flow
│ │ └── TokenStore.kt # EncryptedSharedPreferences
│ └── style/ # Design system tokens
│ └── src/main/kotlin/io/chepherd/rc/style/
│ ├── Palette.kt
│ ├── Typography.kt
│ └── Spacing.kt
└── app/ # Compose UI + entry point
└── src/main/kotlin/io/chepherd/rc/
├── ChepherdApplication.kt
├── ui/
│ ├── ChepherdTheme.kt
│ ├── SignInScreen.kt
│ ├── DashboardScreen.kt
│ ├── SessionDetailScreen.kt
│ ├── SessionRow.kt
│ ├── BandDot.kt
│ ├── ScorecardView.kt
│ └── Sparkline.kt
└── viewmodel/
└── SessionStore.kt # MutableStateFlow<List<SessionState>>
# Requires JDK 17+ and Android SDK 34+
# One-time wrapper bootstrap (fresh clone only):
gradle wrapper --gradle-version 8.10.2 --distribution-type bin
# Subsequent builds:
./gradlew :app:assembleDebug # debug APK
./gradlew :app:installDebug # install on connected device/emulator
./gradlew :app:assembleRelease # release APK (needs signing config)The wrapper-properties + gradlew script are committed; only the
gradle-wrapper.jar is generated by the bootstrap step above. After
the one-time bootstrap, any clone of this repo (CI, contributors,
fresh laptops) runs ./gradlew directly.
Sideloading to a real device:
- JDK 17+ on PATH; Android SDK 34+ installed via Android Studio or
cmdline-tools+sdkmanager. - Plug in an Android device with USB debugging on.
./gradlew :app:installDebug→ app installs aschepherdon the home screen.- Tap to launch → sign-in (AppAuth + Keystore-backed TokenStore) → dashboard.
The OAuth2 callback scheme io.chepherd.rc://callback is pre-registered
in app/src/main/AndroidManifest.xml.
Same as the web client + the TUI: WebRTC DataChannel is the default; the user can opt into relayed mode for low-trust networks. Tokens stored in EncryptedSharedPreferences (AES-256-GCM backed by Android Keystore).
Mirrors chepherd/docs/DESIGN-SYSTEM.md. The Kotlin palette tokens live in core/style/src/main/kotlin/io/chepherd/rc/style/Palette.kt — every hex value comes from the canon mirror in chepherd/internal/style/palette.go.
v0.2.0-rc3 — buildable Android app with full sign-in (AppAuth custom-tab + EncryptedSharedPreferences TokenStore backed by Android Keystore) + WSTransport relayed-mode session list + Material 3 Compose dashboard mirroring the chepherd TUI palette. WebRTC P2P mode + Wear OS companion + Play Store metadata are the Wave 8+ follow-ups.
Play Store submission pending:
- App icon (XML + density buckets)
- Privacy policy URL
- Phone + tablet screenshot bundles
- Internal-track beta cycle