Conversation
The Android clone bar showed "no GitHub credentials" on every host while the web dashboard cloned fine. GithubInfo decoded the availability flag as `ok`; the agent's collect_github() has always named it `available` and sends no `ok` key at all, so with ignoreUnknownKeys it silently defaulted to false everywhere and the bar rendered its greyed-out note instead of the picker. Rename the field to the wire key, and guard it with a decode test pinned to a payload captured verbatim from a live agent. With the bar reachable again, catch it up with index.html's cloneBar/cloneBody (the P1 parity line this closes): collapsible header naming the gh login, a search box, a multi-select list marking private repos and ones already on the host, free-text owner/repo, a "Clone N" button firing one POST per spec, and the agent's clone-job rows (cloning / cloned / failed + reason) — which stay visible while collapsed, since without them a queued clone gave no feedback at all until the repo silently appeared. Offline hosts browse but can't fire. The list/spec/job-row logic lives in core/Clone.kt so it is JVM-tested against the web behavior rather than eyeballed on a phone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
In the Android app every host reported "Cloning unavailable — this host reports no GitHub credentials", while the same hosts cloned fine from the web dashboard.
It is a wire-shape mismatch, not a credentials problem.
GithubInfodecoded the availability flag asok; the agent'scollect_github()has always named itavailableand sends nookkey at all:{"available": true, "login": "xerhab", "repos": [{"nameWithOwner": "xerktech/Turma", ...}]}TurmaJsonsetsignoreUnknownKeys = true, soavailablewas dropped andokfell to itsfalsedefault on every host — the clone bar rendered its greyed-out note and nothing else. The hub passes thegithubblock through untouched, so the web UI (which readsgh.available) was unaffected.Fix: rename the field to the wire key.
While in there
With the bar reachable again it was clear it had never really been used, so it now matches
index.html'scloneBar/cloneBody— closing thePARITY.mdP1 line "Clone bar: collapse + search + multi-select + 🔒 private marker + clone-job status rows":Clone from GitHub · as <login>)🔒private marker and an "already here" row for repos the host already has (kept listed rather than hidden — a missing row reads as a lost repo)owner/repobox, and a Clone N button firing one POST per specCloning X…/✓ Cloned X/⚠ Clone of X failed: <reason>), which stay visible while the panel is collapsed. Without these a queued clone gave no feedback whatsoever until the repo silently appeared in the tree — so even with the decode fixed, cloning was indistinguishable from still-broken.The list/spec/job-row logic is extracted to
core/Clone.kt(cloneCandidates/cloneSpecs/cloneRepoName/cloneJobRow), per the repo's pure-core convention, leaving the Compose widget a thin renderer.How it was verified
collect_github()on a live host and pinned its verbatim output intoCloneTestas a decode regression test — that payload is where theavailable/okmismatch above comes from, so the bug is reproduced and closed against real agent output rather than a hand-written fixture.CloneTestadds 12 cases (decode incl. thelogin: nullunconfigured-host path, candidate list + search, spec parsing/dedupe, the three job-row states).gradle testDebugUnitTest assembleDebug— 151 tests, 0 failures.Not verified on a device. The Compose changes compile and assemble, but the agent image ships no emulator or system image and the project has no JVM UI-test harness (only instrumented
androidTest, which CI doesn't run), so the rendered bar has not been driven on hardware. That is why the widget's logic was pushed down intocore/Clone.kt— the behavior is tested even though the pixels are not.Parity / docs
android/PARITY.md: the clone-bar P1 line moves to Done; the one remaining gap (the web's optimistic pre-echo clone row — Android shows a "clone queued" snackbar and the real row a beat later) is recorded as P2.CLAUDE.md: one line under "GitHub block and cloning" namingavailableas the key every client must gate on, so this doesn't get re-broken.