feat(android): Projects/Diff/Worktree/git-write parity with web+iOS (W5)
Brings the native Android client to parity with the web/iOS Projects + git surface, consuming the existing server endpoints — ZERO server change. (The "SDK-gated modules" premise was stale; they were already online.) - :api-client (pure Kotlin/JVM): PrStatus/GitLog/GitWrite models (tolerant decoders, safe-error), ProjectInfo + ahead/behind/lastCommitMs; 8 new Endpoints builders (projectPr/projectLog read-only; createWorktree/removeWorktree/prune/gitStage/ gitCommit/gitPush guarded w/ Origin) + ApiClient methods (PR/log degrade in body; writes 200→Ok / 429→RateLimited / 4xx-5xx→Rejected(safe msg)). - :app presenters (JVM-tested): DiffViewModel base-compare + git stage/commit/push; new WorktreeViewModel (create/remove/prune + client branch validation + isMain block); ProjectDetailViewModel failure-isolated PR-chip + recent-commits. - Compose screens wired: ProjectDetail (PR chip tappable only for https, recent commits, worktree create/remove-with-force/prune, view-diff), Diff (base input, per-file stage/unstage, commit/push bar), Projects (ahead/behind sync chip). Nav closes the pre-existing "no inbound link to the diff screen" gap. Verified independently: `./gradlew :app:assembleDebug test :api-client:koverVerify` BUILD SUCCESSFUL; 348 unit tests pass (api-client 102 / app 246); coverage gate held; git status android-only. Compose rendering/interaction deferred to on-device QA (android/DEVICE_QA_CHECKLIST.md), as prior Android waves did.
This commit is contained in:
@@ -9,22 +9,20 @@ This directory is a **Gradle multi-module** project. The module set mirrors the
|
||||
SPM package set and inherits its rule: *dependencies only flow down; nothing points
|
||||
upward* (ARCHITECTURE §1).
|
||||
|
||||
## ⚠️ No-SDK constraint (why only 5 modules build here)
|
||||
## Build environment (SDK installed — all modules build)
|
||||
|
||||
The current build environment has **no Android SDK**. Everything that can be pure
|
||||
**Kotlin/JVM** (`kotlin("jvm")`) is built and unit-tested now; anything that needs the
|
||||
Android framework (`com.android.*` plugins) is **scaffolded but disabled**.
|
||||
The Android SDK **is installed** and every module — pure Kotlin/JVM and Android-framework
|
||||
alike — builds and unit-tests here. AGP 9.2.1 (built-in Kotlin) + Gradle 9.6.1 build
|
||||
against SDK 35/36.
|
||||
|
||||
- **Enabled now (pure Kotlin/JVM, `./gradlew test`-able):**
|
||||
`:wire-protocol`, `:session-core`, `:api-client`, `:client-tls`, `:test-support`.
|
||||
- **Scaffolded but COMMENTED OUT** in [`settings.gradle.kts`](settings.gradle.kts)
|
||||
(dirs + a `build.gradle.kts` stub exist, marked `// TODO(android-sdk)`):
|
||||
- **Pure Kotlin/JVM (`./gradlew test`):** `:wire-protocol`, `:session-core`, `:api-client`,
|
||||
`:client-tls`, `:test-support`, `:transport-okhttp`.
|
||||
- **Android-framework (online in [`settings.gradle.kts`](settings.gradle.kts)):**
|
||||
`:app`, `:terminal-view`, `:host-registry`, `:client-tls-android`.
|
||||
|
||||
To bring the Android modules online later: install an SDK, add
|
||||
`local.properties` → `sdk.dir`, add the Android Gradle Plugin + `google()` to
|
||||
`pluginManagement`, then uncomment the `include(...)` lines and the plugin blocks in
|
||||
each stub.
|
||||
Setup: `local.properties` → `sdk.dir=/usr/local/share/android-commandlinetools`;
|
||||
`google()` is in `pluginManagement`/`dependencyResolutionManagement`. Green gate:
|
||||
`./gradlew test :app:assembleDebug koverVerify`.
|
||||
|
||||
## Module map (mirror of the iOS SPM packages — plan §3)
|
||||
|
||||
@@ -35,10 +33,10 @@ each stub.
|
||||
| APIClient | `:api-client` | pure Kotlin/JVM | ✅ built |
|
||||
| ClientTLS (pure half) | `:client-tls` | pure Kotlin/JVM | ✅ built |
|
||||
| TestSupport | `:test-support` | pure Kotlin/JVM (fakes) | ✅ built |
|
||||
| ClientTLS (fwk half) | `:client-tls-android` | Android (AndroidKeyStore/Tink)| ⏸ SDK-gated |
|
||||
| HostRegistry | `:host-registry` | Android (DataStore) | ⏸ SDK-gated |
|
||||
| SwiftTerm host view | `:terminal-view` | Android (Termux wrap) | ⏸ SDK-gated |
|
||||
| App/WebTerm | `:app` | Android app (Compose/Hilt/FCM)| ⏸ SDK-gated |
|
||||
| ClientTLS (fwk half) | `:client-tls-android` | Android (AndroidKeyStore/Tink)| ✅ built |
|
||||
| HostRegistry | `:host-registry` | Android (DataStore) | ✅ built |
|
||||
| SwiftTerm host view | `:terminal-view` | Android (Termux wrap) | ✅ built |
|
||||
| App/WebTerm | `:app` | Android app (Compose/Hilt/FCM)| ✅ built |
|
||||
|
||||
> Not yet scaffolded: `:transport-okhttp` (OkHttp `TermTransport`/`HttpTransport`
|
||||
> impls, JVM) is owned by task **A7** and will be added then. The iOS
|
||||
@@ -47,16 +45,16 @@ each stub.
|
||||
### Dependency graph (arrows = "depends on")
|
||||
|
||||
```
|
||||
:app (SDK-gated)
|
||||
:app
|
||||
┌───────────────┬───┴────┬──────────────┬───────────────┐
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
:terminal-view :session-core :api-client :host-registry :client-tls-android
|
||||
(SDK-gated) │ │ (SDK-gated) │
|
||||
│ │ │ │
|
||||
│ │ │ ▼
|
||||
│ │ │ :client-tls (pure)
|
||||
└──────┬───────┴──────────┴──────────────┬────────────────┘
|
||||
▼ ▼
|
||||
:wire-protocol ◀──────────── :transport-okhttp (A7, not yet)
|
||||
:wire-protocol ◀──────────── :transport-okhttp
|
||||
▲
|
||||
└──────── :test-support → test source sets only
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user