feat(ios,android): P2 wave, git panel, token UX, per-host WS token, docs
App layer, four sequential slices (a shared .xcodeproj means adding files regenerates it, so these could not run in parallel): - token UX end to end: pairing prompts for a token when a host 401s, POST /auth validates it, and 204-without-Set-Cookie is correctly read as "this server has auth disabled" rather than "authenticated". A host paired before the token was turned on recovers by re-pairing in place. Remove-host now exists and finally gives PushRegistrar.handleHostRemoved a caller. - project git panel + worktree lifecycle (T-iOS-32) + claude --resume history — the parity gap with Android and the web front end. - terminal search (T-iOS-33) and voice PTT (T-iOS-31) with an epoch guard so a session switch between dictation and confirm cannot inject into the wrong session. - theme + Dynamic Type (T-iOS-34) and web ?join= interop (T-iOS-35). RootView no longer hard-locks .preferredColorScheme(.dark). Also unpins SwiftTerm to 1.15.0 by dropping the local hasActiveSelection that collided with the upstream one, verified green from a fresh derivedDataPath. Includes the two HIGH fixes the security review found: - iOS resolved the WS token host-independently, so a token-gated host sitting next to an open one could never open a terminal and no on-screen remedy could fix it. Now one transport per host; cross-host leakage is structurally impossible since both read paths return only that host's own value. - Android reported the host's own git-credential 401 (git-ops.ts:108, "Push authentication required on the host.") as "your access token is wrong", because a blanket 401 mapping ran ahead of the per-route one. Git-write routes are now ROUTE_DEFINED and keep the server's message. And the doc sync: README/ios README no longer claim the client is unmerged on feat/ios-client, the Clients section finally lists Android, and the plan checkboxes reflect what is actually built. iOS 534 app tests + 452 package tests; Android 687 tests.
This commit is contained in:
@@ -37,10 +37,13 @@ Setup: `local.properties` → `sdk.dir=/usr/local/share/android-commandlinetools
|
||||
| HostRegistry | `:host-registry` | Android (DataStore) | ✅ built |
|
||||
| SwiftTerm host view | `:terminal-view` | Android (Termux wrap) | ✅ built |
|
||||
| App/WebTerm | `:app` | Android app (Compose/Hilt/FCM)| ✅ built |
|
||||
| `URLSession*Transport` | `:transport-okhttp` | pure Kotlin/JVM (OkHttp) | ✅ built |
|
||||
|
||||
> Not yet scaffolded: `:transport-okhttp` (OkHttp `TermTransport`/`HttpTransport`
|
||||
> impls, JVM) is owned by task **A7** and will be added then. The iOS
|
||||
> `URLSession*Transport`s consolidate into it (plan §3 framing note).
|
||||
> `:transport-okhttp` (A7) holds the OkHttp `TermTransport`/`HttpTransport`
|
||||
> implementations that the two iOS `URLSession*Transport`s consolidate into
|
||||
> (plan §3 framing note). OkHttp is a plain JVM library, so the module builds and
|
||||
> unit-tests (MockWebServer) with **no** Android SDK — including the
|
||||
> access-token cookie on the WS upgrade (`OkHttpAccessTokenTest`).
|
||||
|
||||
### Dependency graph (arrows = "depends on")
|
||||
|
||||
@@ -121,8 +124,29 @@ JUnit Platform (`tasks.test { useJUnitPlatform() }`).
|
||||
```
|
||||
|
||||
> Testing target: **≥80% Kover coverage** on the pure modules (`:wire-protocol`,
|
||||
> `:session-core`, `:api-client`, `:client-tls` pure half). TDD, immutable data,
|
||||
> small focused files — same discipline as the rest of the repo.
|
||||
> `:session-core`, `:api-client`, `:client-tls` pure half — the four that apply
|
||||
> the Kover plugin). TDD, immutable data, small focused files — same discipline as
|
||||
> the rest of the repo.
|
||||
|
||||
### Status & what is NOT verified here
|
||||
|
||||
- **Green gate**: `./gradlew test :app:assembleDebug koverVerify` — JVM unit
|
||||
tests, a debug APK, and the 80 % coverage floor on the four gated modules.
|
||||
- **Emulator**: the app has been built, installed and launched on an
|
||||
android-35 arm64 emulator (pairing screen rendered, no crash). See the
|
||||
`PROGRESS_LOG.md` entry for that run.
|
||||
- **DEFERRED — real device**: hardware-backed keys (StrongBox falls back to
|
||||
software keys on an emulator), FCM push delivery and the lock-screen
|
||||
Allow/Deny walkthrough, and general hand-on-glass QA.
|
||||
- **DEFERRED — instrumented tests**: everything under `src/androidTest/`
|
||||
(`TinkAccessTokenStoreTest`, DataStore stores, AndroidKeyStore importer,
|
||||
hardware-key checks) needs a connected device/emulator and is therefore **not**
|
||||
part of the `./gradlew test` gate; run them with `connectedAndroidTest` on a
|
||||
booted emulator.
|
||||
- **DEFERRED — end-to-end access token**: the `WEBTERM_TOKEN` path is covered by
|
||||
unit tests (`OkHttpAccessTokenTest`, the `:api-client` route tests, the
|
||||
`AuthCookie` derivation tests), but no automated leg here starts a real server
|
||||
with `WEBTERM_TOKEN` set and completes a cookie-gated WS upgrade.
|
||||
|
||||
## Android SDK setup (proven working)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user