Skip to content

refactor(mobile): consolidate the prepareSession repository mapping - #6256

Merged
iscekic merged 1 commit into
mainfrom
kwf/janitor-2026-09-16-maintainability-0e6d
Sep 17, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/janitor-2026-09-16-maintainability-0e6d

Conversation

@iscekic

@iscekic iscekic commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • On Android, the session-list pull-to-refresh indicator no longer draws over the first row.
  • With reduced motion on, a no-match pull on Android draws one indicator, the centered empty state's, and the status line keeps Updating.
  • A failed pull shows Couldn't refresh with Retry, and the rows stay readable.
  • A Retry, and any pull whose body draws no progress, still shows the status line's own spinner.
  • Without reduced motion, the platform pull indicator and the status line behave as before.
  • Creating or cloning a Cloud Agent session sends the same repository and branch as before.

Changelog for maintainers

  • apps/mobile/src/components/agents/session-list-refresh-status.tsx:52 — accepted: under reduced motion the reserved band's ActivityIndicator duplicated the progress the mounted centered no-match body already draws, so one pull showed two indicators. The band now suppresses its spinner when that body owns the progress.
  • The suppression applies only while the platform control is inert and a pull is in flight over the centered no-match body; the band keeps the Updating copy there, and a Retry still shows the band's spinner because the body draws none.
  • progressInBody is threaded from the screen's pull state through the live feedback state to the reserved line and defaults to false, so band-only surfaces are unchanged; review the bodyDrawsProgress gate first, because a true value outside an in-flight no-match pull drops the band's only reduced-motion indicator.
  • New apps/mobile/src/components/agents/prepare-session-repository.ts is the single home of the prepareSession repository fields, the retry fingerprint, and the field writer; the duplicated copies in both hooks are removed, and a new suite pins the writer and fingerprint while the hook suites keep their per-provider field and branch assertions.
  • The create path runs setUpstreamBranch only when the shared writer reports it wrote a field, so a Bitbucket row missing its uuids sends neither the field nor the branch; the clone body still writes exactly one repository field and never upstreamBranch.
  • Provider rules are unchanged: GitHub writes the bare fullName to githubRepo (never a platform:fullName key), GitLab writes gitlabProject, and Bitbucket writes bitbucketRepo only with both uuids; review the writer's uuids guard and boolean return and the fingerprint's output shape and null case.
  • Android's floating pull disc is parked one viewport below the session rows while iOS keeps its inset native indicator; the rows control must forward the ScrollView's style and children or the Android list fails to mount.
  • The new mounted suite pins one indicator when the body owns the progress, the band's spinner when it does not, and the non-reduced-motion platform indicator, and the screen suite adds the Android/no-match/reduced-motion case.

E2E proof

The earlier empty E2E proof for this pull-to-refresh behavior is replaced by the Android reduced-motion capture below and the sanitized scenario logs appended under this heading (collected 2026-09-17). The request asked for Android and iOS; only Android was run, so the iOS scope is skipped and pending verification.

e2

Owner request

Surface: the mobile app (apps/mobile).

Consolidate the duplicated repository-to-prepareSession mapping in the mobile agent creators

Surface: the mobile app (apps/mobile). Both iOS and Android are in scope; the change is shared JS/TS.

Problem

Two mobile hooks that build a Cloud Agent prepareSession body each carry their own copy of the same repository-mapping logic, and both copies are annotated as mirroring the other:

  • resolveRepoFingerprint(repository) is duplicated byte-for-byte at apps/mobile/src/components/agents/use-new-session-creator.ts:338-356 and apps/mobile/src/components/agents/use-continue-cloud-create.ts:183-201 (the clone copy's doc comment says "Mirrors the ordinary create path").
  • setRepositoryField(input, repository) is duplicated at apps/mobile/src/components/agents/use-new-session-creator.ts:371-396 and apps/mobile/src/components/agents/use-continue-cloud-create.ts:211-233 (the clone copy's doc comment says it "Mirrors the ordinary create path's setRepositoryField").
  • The three repository body fields are declared twice: apps/mobile/src/components/agents/use-new-session-creator.ts:66-69 and apps/mobile/src/components/agents/use-continue-cloud-create.ts:167-170.

The two copies are the only writers of githubRepo/gitlabProject/bitbucketRepo for prepareSession in the mobile app, so a future provider-rule change must be made twice or the create and clone paths diverge (for example, a Bitbucket identity-key change applied to only one path would silently alter the retry fingerprint of the other).

Requested behavior

Extract one shared module and have both hooks use it:

  1. Create apps/mobile/src/components/agents/prepare-session-repository.ts exporting:
    • the shared repository-fields type used by a prepareSession body: githubRepo?: string, gitlabProject?: string, bitbucketRepo?: { fullName: string; workspaceUuid: string; repositoryUuid: string };
    • the single resolveRepoFingerprint(repository: NewSessionRepository | null) implementation (platform plus fullName, with workspaceUuid/repositoryUuid for Bitbucket), preserving the exact current output shape and null for a null repository;
    • a single repository-field writer that writes exactly one field matching the row's platform (GitHub -> githubRepo, GitLab -> gitlabProject, Bitbucket -> bitbucketRepo only when both uuids are present) and reports whether it wrote anything.
  2. In use-new-session-creator.ts, remove the local resolveRepoFingerprint, setRepositoryField, and duplicated field declarations; import the shared ones. Keep upstreamBranch behavior identical: apply setUpstreamBranch only when the shared writer actually wrote a repository field (so a Bitbucket row missing its uuids still writes no field and no branch, exactly as today).
  3. In use-continue-cloud-create.ts, remove the local resolveRepoFingerprint, its local setRepositoryField, and the duplicated field declarations; import the shared ones. The clone path must keep writing exactly one repository field and must keep not sending upstreamBranch.

Do not change prepareSession request semantics, field names, or the retry-fingerprint shape; this is a behavior-preserving refactor. Do not touch any kiloclaw or kilo-chat path, and do not fold in the sandbox-allocation work that open PR #6202 adds to use-new-session-creator.ts.

Acceptance checks

From apps/mobile/:

  • pnpm typecheck passes.
  • pnpm lint passes.
  • pnpm check:unused passes (the new module's exports are imported by both hooks; no new unused export is introduced).
  • pnpm test passes, with these focused suites green and their assertions unchanged: src/components/agents/use-new-session-creator.test.ts (pins githubRepo, gitlabProject, bitbucketRepo with workspace/repository uuids, and upstreamBranch per provider) and src/components/agents/use-continue-cloud-create.test.ts (pins the clone body has exactly one repo field and no prompt/initialMessageId).
  • Behavior-preservation checks that must hold after the refactor: a GitHub row writes the bare fullName (never a platform:fullName picker key); a GitLab row writes gitlabProject; a Bitbucket row with uuids writes bitbucketRepo; a Bitbucket row without uuids writes nothing; the create path writes upstreamBranch only when a repository field was written; the clone path never writes upstreamBranch.
  • git diff --check is clean and pnpm format leaves no diff.

E2E proof required

Run the mobile app through the normal workflow (dev build plus the repository dev runner's Metro; do not use Expo Go).

  1. Create a new Cloud Agent session from a repository with a non-default branch selected, and confirm the session is created.
  2. Open an existing session and use the Continue (clone) entry, and confirm the cloned session is created.

This refactor has no visible change, so provide decisive sanitized log lines captured at the prepareSession boundary for both flows (the repository field written and, for the create flow only, upstreamBranch), with no tokens, credentials, or PII. Provide a recording or screenshots of both flows reaching their created sessions.

Notes

E2E proof — log excerpts

[e1] Android, system Reduce Motion ON: on the Agents tab search/filter to the no -> pass :: Reduce Motion ON ('animator_duration_scale=0' in e1-reduced-motion.log) and the live session behind the search filter ('ses_f50cdda08ffe0sTj72oRSPlykh|idle' in e1-live-session.log); with the pull held in flight the band shows 'Updating' with no indicator ahead of it (e1-scene.log 'android.widget.TextView Updating tappable [58,506][1024,543]', whereas e3's spinner-led band starts at x=128) and the only indicator on screen is the body's pull progress ('e1-scene.xml [514,892][566,944] body(y1 860..1400)' in e1-indicators.log, absent from the idle no-match capture p5-idle-hierarchy.xml), so one pull draws exactly one indicator and never two; UX audit: no UX-DEFECT — the no-match body holds the s
[e3] Android, Reduce Motion ON: pull the full live rows list — the reserved band -> pass :: Reduce Motion ON; the full rows list (digest '1 LIVE' plus the row 'android.widget.Button Greeting, Idle, kwf/kwf-fix-review-29e9, CLOUD, and cost 1 cent, 6 minutes ago tappable [0,549][1080,755]' in e3-scene.log) pulled with the refetch held in flight shows the band's single indicator ('e3-scene.xml [58,497][110,549] band(y1 490..560)' in e3-indicators.log) beside 'android.widget.TextView Updating tappable [128,506][1023,543]' (e3-scene.log), with no indicator node in the body region and no ProgressBar or SwipeRefreshLayout node anywhere in e3-scene.xml, so the rows list keeps exactly the band's one spinner; UX audit: no UX-DEFECT — the band is a reserved line and the first row keeps its bo
[e2] Android, Reduce Motion ON: no-match pull with a failing refetch shows Could -> pass :: Android emulator-5604, reduce motion ON (device animation scales 0), no-match Agents body behind 1 LIVE row with nextjs faulted down: one scripted call (out/e2-scenes.json, out/e2-run.log 'SCENE e2 OK', replay out/e2.replay.json) asserted the pull's failure and 'Updating' after tapping Retry, out/e2-failed.xml carries text="Couldn't refresh" and text="RETRY", and out/e2-scene.xml carries the band line text="Updating" over the text="No sessions match" centered-state body; the element tree carries no indicator node in either state, so the literal no-spinner/one-spinner count is the visual reviewer's call from out/e2.png, not mine, and no functional UX defect was observed.
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e1-indicators.log
e1: no-match body, pull in flight, reduced motion ON (band must carry no indicator; the body carries the one pull indicator)
  e1-scene.xml [970,196][1022,248] other
  e1-scene.xml [97,371][144,419] other
  e1-scene.xml [941,374][983,416] other
  e1-scene.xml [514,892][566,944] body(y1 860..1400)
  e1-scene.xml [509,993][572,1056] body(y1 860..1400)
  e1-scene.xml [923,2048][986,2111] other
  e1-scene.xml [151,2216][209,2274] other
  e1-scene.xml [511,2216][569,2274] other
  e1-scene.xml [871,2216][929,2274] other
  p5-idle-hierarchy.xml [970,196][1022,248] other
  p5-idle-hierarchy.xml [97,371][144,419] other
  p5-idle-hierarchy.xml [941,374][983,416] other
  p5-idle-hierarchy.xml [509,993][572,1056] body(y1 860..1400)
  p5-idle-hierarchy.xml [923,2048][986,2111] other
  p5-idle-hierarchy.xml [151,2216][209,2274] other
  p5-idle-hierarchy.xml [511,2216][569,2274] other
  p5-idle-hierarchy.xml [871,2216][929,2274] other
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e1-reduced-motion.log
== reduce motion (Android 'Remove animations') setup 2026-09-17T11:45:24Z ==
animator_duration_scale=0
transition_animation_scale=0
window_animation_scale=0
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e1-live-session.log
ses_f50cdda08ffe0sTj72oRSPlykh|idle
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e1-scene.log
SCENE e1 OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.TextView 1 LIVE tappable [58,149][761,186]
android.view.View Agents tappable [58,190][761,296]
android.widget.Button See all tappable [787,203][933,242]
android.widget.TextView SEE ALL tappable [787,203][933,242]
android.widget.Button Filter sessions tappable [970,196][1022,248]
android.widget.EditText Search sessions tappable [163,340][924,449]
android.widget.Button Clear search tappable [941,374][983,416]
android.widget.TextView Updating tappable [58,506][1024,543]
android.widget.ScrollView centered-state tappable [0,549][1080,2400]
android.view.ViewGroup centered-state-content tappable [0,877][1080,1397]
android.widget.TextView No sessions match tappable [360,1125][720,1190]
android.widget.TextView Try a different search term. tappable [339,1199][741,1245]
android.widget.Button Clear search tappable [408,1282][672,1397]
android.widget.TextView Clear search tappable [447,1316][633,1362]
android.widget.Button New session tappable [881,2006][1028,2153]
android.view.View Home, tab, 1 of 3 tappable [0,2195][360,2337]
android.view.View Agents, tab, 2 of 3 tappable [360,2195][720,2337]
android.view.View Profile, tab, 3 of 3 tappable [720,2195][1080,2337]
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/p5-scene.log
SCENE p5 OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.TextView 1 LIVE tappable [58,149][761,186]
android.view.View Agents tappable [58,190][761,296]
android.widget.Button See all tappable [787,203][933,242]
android.widget.TextView SEE ALL tappable [787,203][933,242]
android.widget.Button Filter sessions tappable [970,196][1022,248]
android.widget.EditText Search sessions tappable [163,340][924,449]
android.widget.Button Clear search tappable [941,374][983,416]
android.widget.ScrollView centered-state tappable [0,549][1080,2400]
android.view.ViewGroup centered-state-content tappable [0,877][1080,1397]
android.widget.TextView No sessions match tappable [360,1125][720,1190]
android.widget.TextView Try a different search term. tappable [339,1199][741,1245]
android.widget.Button Clear search tappable [408,1282][672,1397]
android.widget.TextView Clear search tappable [447,1316][633,1362]
android.widget.Button New session tappable [881,2006][1028,2153]
android.view.View Home, tab, 1 of 3 tappable [0,2195][360,2337]
android.view.View Agents, tab, 2 of 3 tappable [360,2195][720,2337]
android.view.View Profile, tab, 3 of 3 tappable [720,2195][1080,2337]
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e3-indicators.log
e3: full live rows list, pull in flight, reduced motion ON (the reserved band carries the single indicator)
  e3-scene.xml [970,196][1022,248] other
  e3-scene.xml [97,371][144,419] other
  e3-scene.xml [58,497][110,549] band(y1 490..560)
  e3-scene.xml [559,586][590,617] other
  e3-scene.xml [986,583][1022,620] other
  e3-scene.xml [923,2048][986,2111] other
  e3-scene.xml [151,2216][209,2274] other
  e3-scene.xml [511,2216][569,2274] other
  e3-scene.xml [871,2216][929,2274] other
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e3-scene.log
SCENE e3 OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.TextView 1 LIVE tappable [58,149][761,186]
android.view.View Agents tappable [58,190][761,296]
android.widget.Button See all tappable [787,203][933,242]
android.widget.TextView SEE ALL tappable [787,203][933,242]
android.widget.Button Filter sessions tappable [970,196][1022,248]
android.widget.EditText Search sessions tappable [163,340][984,449]
android.widget.TextView Updating tappable [128,506][1023,543]
android.widget.Button Greeting, Idle, kwf/kwf-fix-review-29e9, CLOUD, and cost 1 cent, 6 minutes ago tappable [0,549][1080,755]
android.widget.TextView CLOUD tappable [93,583][560,620]
android.widget.TextView $0.01 · 6 MINUTES AGO tappable [604,583][957,620]
android.widget.TextView Greeting tappable [93,627][958,673]
android.widget.TextView kwf/kwf-fix-review-29e9 tappable [93,683][958,720]
android.widget.Button New session tappable [881,2006][1028,2153]
android.view.View Home, tab, 1 of 3 tappable [0,2195][360,2337]
android.widget.TextView HOME tappable [13,2281][347,2320]
android.view.View Agents, tab, 2 of 3 tappable [360,2195][720,2337]
android.widget.TextView AGENTS tappable [373,2281][707,2320]
android.view.View Profile, tab, 3 of 3 tappable [720,2195][1080,2337]
android.widget.TextView PROFILE tappable [733,2281][1067,2320]
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-review-29e9/e2e-mobile-app/e2-run.log
SCENE e2 OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.TextView 1 LIVE tappable [58,149][761,186]
android.view.View Agents tappable [58,190][761,296]
android.widget.Button See all tappable [787,203][933,242]
android.widget.TextView SEE ALL tappable [787,203][933,242]
android.widget.Button Filter sessions tappable [970,196][1022,248]
android.widget.EditText Search sessions tappable [163,340][924,449]
android.widget.Button Clear search tappable [941,374][983,416]
android.widget.TextView Updating tappable [128,506][1023,543]
android.widget.ScrollView centered-state tappable [0,549][1080,2400]
android.view.ViewGroup centered-state-content tappable [0,877][1080,1397]
android.widget.TextView No sessions match tappable [360,1125][720,1190]
android.widget.TextView Try a different search term. tappable [339,1199][741,1245]
android.widget.Button Clear search tappable [408,1282][672,1397]
android.widget.TextView Clear search tappable [447,1316][633,1362]
android.widget.Button New session tappable [881,2006][1028,2153]
android.view.View Home, tab, 1 of 3 tappable [0,2195][360,2337]
android.view.View Agents, tab, 2 of 3 tappable [360,2195][720,2337]
android.view.View Profile, tab, 3 of 3 tappable [720,2195][1080,2337]

@iscekic
iscekic marked this pull request as draft September 17, 2026 01:22
@iscekic iscekic added the kwf-janitor Nightly mobile janitor request label Sep 17, 2026
@kilo-code-bot

kilo-code-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The previous readStoredValue re-export finding is resolved (removed in a886e2a, restoring secure-store-read.ts to its main content, so the file is no longer part of this PR); the remaining 19 changed mobile files are unchanged since the last review and re-introduce no defects, including no new subscriptions, timers, or effect-cleanup paths that could leak.

Files Reviewed (19 files)
  • apps/mobile/src/components/agents/agents-tab-badge.test-helpers.ts
  • apps/mobile/src/components/agents/prepare-session-repository.test.ts
  • apps/mobile/src/components/agents/prepare-session-repository.ts
  • apps/mobile/src/components/agents/refresh-indicator.test.ts
  • apps/mobile/src/components/agents/refresh-indicator.ts
  • apps/mobile/src/components/agents/rows-refresh-control.mounted.test.tsx
  • apps/mobile/src/components/agents/rows-refresh-control.tsx
  • apps/mobile/src/components/agents/session-list-content.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.test.ts
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/components/home/agent-sessions-section.test.ts
  • apps/mobile/src/components/home/agent-sessions-section.tsx
  • apps/mobile/src/components/tour/tour-remote-step.mounted.test.tsx
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
Previous Review Summaries (4 snapshots, latest commit b906066)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit b906066)

Status: 1 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/lib/auth/secure-store-read.ts 7 Unused readStoredValue re-export whose comment no longer matches the import path used by start-agent-runtime.ts and platform-parity.test.ts
Files Reviewed (20 files)
  • apps/mobile/src/components/agents/agents-tab-badge.test-helpers.ts
  • apps/mobile/src/components/agents/prepare-session-repository.test.ts
  • apps/mobile/src/components/agents/prepare-session-repository.ts
  • apps/mobile/src/components/agents/refresh-indicator.test.ts
  • apps/mobile/src/components/agents/refresh-indicator.ts
  • apps/mobile/src/components/agents/rows-refresh-control.mounted.test.tsx
  • apps/mobile/src/components/agents/rows-refresh-control.tsx
  • apps/mobile/src/components/agents/session-list-content.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.test.ts
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/components/home/agent-sessions-section.test.ts
  • apps/mobile/src/components/home/agent-sessions-section.tsx
  • apps/mobile/src/components/tour/tour-remote-step.mounted.test.tsx
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
  • apps/mobile/src/lib/auth/secure-store-read.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 7102fd2)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files changed since the previous review)
  • apps/mobile/src/components/agents/code-block-chunks.tsx
  • apps/mobile/src/components/agents/code-block.tsx
  • apps/mobile/src/components/agents/prepare-session-repository.ts
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
  • apps/mobile/src/lib/auth/secure-store-read.ts

Previous review (commit 57b574d)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files changed since the previous review)
  • apps/mobile/src/components/agents/session-list-refresh-status.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/home/agent-sessions-section.tsx

Notes

  • progressInBody is exact: it is true only for the in-flight pull over the centered no-match body (hasLiveRows && visibleSessions.length === 0 && pull.refreshing), which is the only body that mounts RefreshProgress, so the band cannot stand down its spinner where no body draws one.
  • The band gates suppression on the same provided reduced-motion policy that RefreshProgress reads, so the platform control and the band stay mutually exclusive; a retry reports no pull and keeps the band's spinner.
  • No new subscriptions, timers, or effect-cleanup paths were added, and the new mounted suite unmounts its renderer, so the increment introduces no memory leaks.

Previous review (commit dd27e56)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (18 files)
  • apps/mobile/src/components/agents/agents-tab-badge.test-helpers.ts
  • apps/mobile/src/components/agents/prepare-session-repository.test.ts
  • apps/mobile/src/components/agents/prepare-session-repository.ts
  • apps/mobile/src/components/agents/refresh-indicator.test.ts
  • apps/mobile/src/components/agents/refresh-indicator.ts
  • apps/mobile/src/components/agents/rows-refresh-control.mounted.test.tsx
  • apps/mobile/src/components/agents/rows-refresh-control.tsx
  • apps/mobile/src/components/agents/session-list-content.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-refresh-status.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.test.ts
  • apps/mobile/src/components/agents/use-continue-cloud-create.ts
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/components/agents/use-new-session-creator.ts
  • apps/mobile/src/components/home/agent-sessions-section.test.ts
  • apps/mobile/src/components/tour/tour-remote-step.mounted.test.tsx

Notes

  • The shared writer and fingerprint preserve the previous provider rules exactly: GitHub writes the bare fullName, GitLab writes gitlabProject, Bitbucket writes bitbucketRepo only with both uuids, and the create path gates setUpstreamBranch on the writer's boolean so a Bitbucket row without uuids sends neither field nor branch. The clone path still writes at most one repository field and never upstreamBranch.
  • refreshControl remains in use in both session-list-content.tsx and session-list-screen.tsx (error/empty surfaces), so no unused-binding break.
  • No new subscriptions, listeners, timers, or effect cleanup paths were added, so the diff introduces no memory leaks.

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as ready for review September 17, 2026 01:30
@iscekic

iscekic commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

kilo-review — independent audit of the published diff.

Status: 1 Issues

File Line Issue
apps/mobile/src/components/agents/session-list-refresh-status.tsx 52 On Android under reduced motion the new band ActivityIndicator duplicates the spinner that the mounted CenteredState body already draws, so one pull shows two loading indicators.

@iscekic
iscekic marked this pull request as draft September 17, 2026 11:14
@iscekic

iscekic commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Accepted. Pushed 95b8f40 (kwf kwf-fix-review-29e9).

What changed:

  • apps/mobile/src/components/agents/session-list-refresh-status.tsx:52 — accepted: the reserved band's ActivityIndicator duplicated the reduced-motion progress the mounted centered no-match body already draws, so one pull showed two indicators. The band now suppresses its spinner when that body owns the progress.
  • The suppression applies only while the platform control is inert and the pull is in flight over the centered no-match body. The band keeps the Updating copy in that case.
  • A Retry reports no pull, so the band keeps the spinner the body does not draw.
  • progressInBody is threaded from the screen's pull state through the live feedback state to the reserved line. It defaults to false, so band-only surfaces are unchanged.
  • Review the bodyDrawsProgress gate and the progressInBody computation first. A true value outside an in-flight no-match pull would drop the band's only indicator under reduced motion.
  • The new mounted suite pins one indicator when the body owns progress, the band keeping its spinner without it, and the non-reduced-motion platform indicator. The screen suite adds the Android/no-match/reduced-motion case.

@iscekic
iscekic force-pushed the kwf/janitor-2026-09-16-maintainability-0e6d branch from 95b8f40 to 57b574d Compare September 17, 2026 13:27
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 13:37
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 17, 2026
@iscekic iscekic self-assigned this Sep 17, 2026
@iscekic
iscekic enabled auto-merge (squash) September 17, 2026 14:34
@iscekic
iscekic force-pushed the kwf/janitor-2026-09-16-maintainability-0e6d branch from 7102fd2 to b906066 Compare September 17, 2026 17:12
Comment thread apps/mobile/src/lib/auth/secure-store-read.ts Outdated
@iscekic
iscekic force-pushed the kwf/janitor-2026-09-16-maintainability-0e6d branch from 0d2928c to a886e2a Compare September 17, 2026 18:14
@iscekic
iscekic merged commit 3099cdf into main Sep 17, 2026
28 checks passed
@iscekic
iscekic deleted the kwf/janitor-2026-09-16-maintainability-0e6d branch September 17, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review. kwf-janitor Nightly mobile janitor request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants