Skip to content

fix(mobile): offer every recent repository in the Agents session filter - #6458

Merged
iscekic merged 1 commit into
mainfrom
kwf/janitor-2026-09-21-features-and-workflows-9807
Sep 21, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/janitor-2026-09-21-features-and-workflows-9807

Conversation

@iscekic

@iscekic iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The Agents session filter now shows a project row for every recent repository the server returns, up to its ten-repository limit.
  • Previously the filter offered only the three most recent repositories, so older ones could not be selected.
  • A repository picked from an earlier list still appears after it drops out of the recent set.
  • The same repository never produces a duplicate row.
  • A longer list scrolls inside the sheet, keeping the Apply and Cancel buttons visible.
  • The chosen project filter returns when the sheet reopens and after an app restart.

Changelog for maintainers

  • use-agent-session-list-data.ts: removed the client-side .slice(0, 3) cap; the cliSessionsV2.recentRepositories procedure already bounds the list with LIMIT 10.
  • Selected projectFilter values absent from the recent list are still merged in and deduplicated by gitUrl.
  • platform-filter-modal.tsx: the sheet content gains max-h-[80%] and its single ScrollView gains shrink, so extra rows scroll instead of clipping.
  • Tests assert one row per recent repository, no duplicate rows, the retained stale selected row, and the single bounded scroll container.
  • No server procedure, schema, persistence key, or new copy changed; the projectOptions memo is the only product behavior change to review.

E2E proof

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates — Sheet rendered 10 PROJECT checkbox rows, distinct=10 total=10 with no duplicate gitUrl, matching the 10 rows the query returns out of 12 recent repositories (e1-rows.log, e1-repos.log); captures e1.png/e1b.png.

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates — e2e-cli/e1b.png (capture not retained)

[e4] Selected project row for a repository no longer recent still renders and toggles off and on — After golf-service was aged out of the recent window (e4-aged.log) and the app was relaunched, the reopened sheet rendered iscekic/golf-service checked="true" as the last row, then checked="false" with the row kept after a tap, then re-applied and narrowed the list (e4.log); captures e4e.png/e4f.png/e4g.png.

[e4] Selected project row for a repository no longer recent still renders and toggles off and on — e2e-cli/e4g.png (capture not retained)

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates — prior/e1b.png

[e4] Selected project row for a repository no longer recent still renders and toggles off and on

[e4] Selected project row for a repository no longer recent still renders and toggles off and on — prior/e4g.png

E2E proof — log excerpts

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no -> pass :: Sheet rendered 10 PROJECT checkbox rows, distinct=10 total=10 with no duplicate gitUrl, matching the 10 rows the query returns out of 12 recent repositories (e1-rows.log, e1-repos.log); captures e1.png/e1b.png.
[e4] Selected project row for a repository no longer recent still renders and to -> pass :: After golf-service was aged out of the recent window (e4-aged.log) and the app was relaunched, the reopened sheet rendered iscekic/golf-service checked="true" as the last row, then checked="false" with the row kept after a tap, then re-applied and narrowed the list (e4.log); captures e4e.png/e4f.png/e4g.png.
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-cli/e1-rows.log
# PROJECT checkbox rows rendered in the open filter sheet (e1b-scene.xml, scrolled to the bottom)
"kilo-org/missing-e2e-repo"
"iscekic/tax-report-generator"
"iscekic/alpha-service"
"iscekic/bravo-service"
"iscekic/charlie-service"
"iscekic/delta-service"
"iscekic/echo-service"
"iscekic/foxtrot-service"
"iscekic/golf-service"
"iscekic/hotel-service"
# distinct PROJECT rows:
10
# total PROJECT checkboxes:
10
# at e1 time the account had 12 distinct recent repositories (e1-repos.log); the server returns LIMIT 10,
# so the sheet renders exactly the 10 the query returns, with no duplicates.
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-cli/e1-repos.log
# distinct repos for the e2e account (updated within 30d)
https://github.com/kilo-org/missing-e2e-repo|2026-09-21 02:53:45.259+00
https://github.com/iscekic/tax-report-generator|2026-09-21 02:53:45.107+00
https://github.com/iscekic/alpha-service|2026-09-21 02:53:00.27373+00
https://github.com/iscekic/bravo-service|2026-09-21 02:52:00.27373+00
https://github.com/iscekic/charlie-service|2026-09-21 02:51:00.27373+00
https://github.com/iscekic/delta-service|2026-09-21 02:50:00.27373+00
https://github.com/iscekic/echo-service|2026-09-21 02:49:00.27373+00
https://github.com/iscekic/foxtrot-service|2026-09-21 02:48:00.27373+00
https://github.com/iscekic/golf-service|2026-09-21 02:47:00.27373+00
https://github.com/iscekic/hotel-service|2026-09-21 02:46:00.27373+00
https://github.com/iscekic/india-service|2026-09-21 02:45:00.27373+00
https://github.com/iscekic/juliet-service|2026-09-21 02:44:00.27373+00
# count of distinct recent repos
12
# server limit is 10 (LIMIT 10 in cli-sessions-v2-router)
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-cli/e4.log
# golf-service aged out of the recent window (db) - see e4-aged.log
# after a fresh app launch, the reopened filter sheet renders the selected-but-not-recent row last:
content-desc="iscekic/golf-service" checked="true" bounds=[101,1673][979,1765]
# project rows on the reopened sheet (e4e-scene.xml, platform rows excluded):
content-desc="kilo-org/missing-e2e-repo"
content-desc="iscekic/tax-report-generator"
content-desc="iscekic/alpha-service"
content-desc="iscekic/bravo-service"
content-desc="iscekic/charlie-service"
content-desc="iscekic/delta-service"
content-desc="iscekic/echo-service"
content-desc="iscekic/foxtrot-service"
content-desc="iscekic/hotel-service"
content-desc="iscekic/india-service"
content-desc="iscekic/golf-service"
# after tapping the golf row, it is still rendered but unchecked (e4f-scene.xml):
content-desc="iscekic/golf-service" checked="false" bounds=[101,1673][979,1765]
# tapping it again and applying narrows the list to that repository (e4g final digest):
android.widget.Button Filter sessions, 1 tappable [991,173][1043,226]
android.widget.Button golf-service session, GOLF-SERVICE, 16 minutes ago, and from CLI tappable [0,596][1080,756]
android.widget.TextView GOLF-SERVICE tappable [93,630][677,667]
android.widget.TextView golf-service session tappable [93,674][958,720]
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-cli/e4-aged.log
# golf aged out of the recent window (>30d); remaining recent repos:
https://github.com/kilo-org/missing-e2e-repo
https://github.com/iscekic/tax-report-generator
https://github.com/iscekic/tax-report-generator
https://github.com/iscekic/alpha-service
https://github.com/iscekic/bravo-service
https://github.com/iscekic/charlie-service
https://github.com/iscekic/delta-service
https://github.com/iscekic/echo-service
https://github.com/iscekic/foxtrot-service
https://github.com/iscekic/hotel-service
https://github.com/iscekic/india-service
https://github.com/iscekic/juliet-service
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-cli/cli-tests.log
error: Script not found "turbo"
  • proved live: In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — android emulator-5554. 4th project row iscekic/charlie-service + Apply left the history showing only content-desc="Charlie fixture, CHARLIE-SERVICE, 9 minutes ago, and from CLI" and content-desc="Filter sessions, 1" (e1-applied.txt); reopened sheet shows content-desc="iscekic/charlie-service" checkable="true" checked="true" (e1-reopen.txt); after force-quit+relaunch history still shows text="CHARLIE-SERVICE" and content-desc="Filter sessions, 1" (e1-restart.txt); no behavioral UX-DEFECT observed. In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — e1-applied.png
  • proved live: Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — android emulator-5554. Sheet bounded at android.view.ViewGroup Filter sessions tappable [55,216][1025,1963] with one scrollable="true" selected="false" bounds="[101,355][979,1765]" list (e2-run.log); with all 8 returned repositories rendered once each (incl. content-desc="kilo-org/missing-e2e-repo"), the pinned row stays content-desc="Apply" checkable="false" checked="false" clickable="true" ... bounds="[821,1802][979,1917]" and content-desc="Cancel" ... clickable="true" ... bounds="[613,1802][794,1917]" (e2-scrolled.txt); 'SCENE e2 OK' with the Cancel tap closing the sheet proves it is… Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — e2-scrolled.png

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates — prior/e1b.png

[e1] In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — e2e-mobile-app/e1-applied.png

[e2] Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — e2e-mobile-app/e2-scrolled.png

[e4] Selected project row for a repository no longer recent still renders and toggles off and on — prior/e4g.png

[e1] In that sheet tap the fourth repository row and Apply: the session list nar -> pass :: android emulator-5554. 4th project row iscekic/charlie-service + Apply left the history showing only content-desc="Charlie fixture, CHARLIE-SERVICE, 9 minutes ago, and from CLI" and content-desc="Filter sessions, 1" (e1-applied.txt); reopened sheet shows content-desc="iscekic/charlie-service" checkable="true" checked="true" (e1-reopen.txt); after force-quit+relaunch history still shows text="CHARLIE-SERVICE" and content-desc="Filter sessions, 1" (e1-restart.txt); no behavioral UX-DEFECT observed.
[e2] Scroll the sheet with the server's full set of repositories (up to ten) and -> pass :: android emulator-5554. Sheet bounded at android.view.ViewGroup Filter sessions tappable [55,216][1025,1963] with one scrollable="true" selected="false" bounds="[101,355][979,1765]" list (e2-run.log); with all 8 returned repositories rendered once each (incl. content-desc="kilo-org/missing-e2e-repo"), the pinned row stays content-desc="Apply" checkable="false" checked="false" clickable="true" ... bounds="[821,1802][979,1917]" and content-desc="Cancel" ... clickable="true" ... bounds="[613,1802][794,1917]" (e2-scrolled.txt); 'SCENE e2 OK' with the Cancel tap closing the sheet proves it is tappable; no behavioral UX-DEFECT observed.
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-mobile-app/e1-applied.txt
<redacted>
                                        </com.horcrux.svg.GroupView>
                                      </com.horcrux.svg.SvgView>
<redacted>
                                    </android.view.View>
                                  </android.view.ViewGroup>
                                </android.view.ViewGroup>
                              </android.view.ViewGroup>
                            </android.widget.ScrollView>
                          </android.view.ViewGroup>
                        </android.view.ViewGroup>
                      </android.view.ViewGroup>
<redacted>
                    </android.view.ViewGroup>
                  </android.view.ViewGroup>
                </android.view.ViewGroup>
              </android.widget.FrameLayout>
            </android.widget.FrameLayout>
          </android.widget.FrameLayout>
        </android.widget.LinearLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-mobile-app/e1-reopen.txt
<redacted>
<redacted>
                      </android.widget.CheckBox>
<redacted>
<redacted>
<redacted>
                      </android.widget.CheckBox>
                    </android.view.ViewGroup>
                  </android.widget.ScrollView>
<redacted>
<redacted>
                  </android.widget.Button>
<redacted>
<redacted>
                  </android.widget.Button>
                </android.view.ViewGroup>
              </android.view.ViewGroup>
            </android.view.ViewGroup>
          </android.view.ViewGroup>
        </android.widget.FrameLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-mobile-app/e1-restart.txt
<redacted>
                                        </com.horcrux.svg.GroupView>
                                      </com.horcrux.svg.SvgView>
<redacted>
                                    </android.view.View>
                                  </android.view.ViewGroup>
                                </android.view.ViewGroup>
                              </android.view.ViewGroup>
                            </android.widget.ScrollView>
                          </android.view.ViewGroup>
                        </android.view.ViewGroup>
                      </android.view.ViewGroup>
<redacted>
                    </android.view.ViewGroup>
                  </android.view.ViewGroup>
                </android.view.ViewGroup>
              </android.widget.FrameLayout>
            </android.widget.FrameLayout>
          </android.widget.FrameLayout>
        </android.widget.LinearLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-mobile-app/e2-scrolled.txt
<redacted>
<redacted>
                      </android.widget.CheckBox>
<redacted>
<redacted>
<redacted>
                      </android.widget.CheckBox>
                    </android.view.ViewGroup>
                  </android.widget.ScrollView>
<redacted>
<redacted>
                  </android.widget.Button>
<redacted>
<redacted>
                  </android.widget.Button>
                </android.view.ViewGroup>
              </android.view.ViewGroup>
            </android.view.ViewGroup>
          </android.view.ViewGroup>
        </android.widget.FrameLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-mobile-app/e2-run.log
android.widget.TextView Slack tappable [202,727][952,773]
android.widget.CheckBox GitHub tappable [101,806][979,898]
android.widget.TextView GitHub tappable [202,828][952,874]
android.widget.CheckBox Linear tappable [101,907][979,998]
android.widget.TextView Linear tappable [202,929][952,975]
android.widget.CheckBox Other tappable [101,1008][979,1100]
android.widget.TextView Other tappable [202,1030][952,1076]
android.widget.TextView PROJECT tappable [101,1137][979,1174]
android.widget.CheckBox iscekic/tax-report-generator tappable [101,1183][979,1274]
android.widget.TextView iscekic/tax-report-generator tappable [202,1205][952,1251]
android.widget.CheckBox iscekic/alpha-service tappable [101,1284][979,1376]
android.widget.TextView iscekic/alpha-service tappable [202,1306][952,1352]
android.widget.CheckBox iscekic/bravo-service tappable [101,1385][979,1477]
android.widget.TextView iscekic/bravo-service tappable [202,1407][952,1453]
android.widget.CheckBox iscekic/charlie-service tappable [101,1487][979,1579]
android.widget.TextView iscekic/charlie-service tappable [202,1509][952,1555]
android.widget.CheckBox iscekic/delta-service tappable [101,1588][979,1680]
android.widget.TextView iscekic/delta-service tappable [202,1610][952,1656]
android.widget.CheckBox iscekic/hotel-service tappable [101,1689][979,1765]
android.widget.TextView iscekic/hotel-service tappable [202,1711][952,1757]
android.widget.Button Cancel tappable [613,1802][794,1917]
android.widget.TextView Cancel tappable [652,1836][754,1882]
android.widget.Button Apply tappable [821,1802][979,1917]
android.widget.TextView Apply tappable [857,1836][941,1882]
  • proved live: In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — android emulator-5554. 4th project row iscekic/charlie-service + Apply left the history showing only content-desc="Charlie fixture, CHARLIE-SERVICE, 9 minutes ago, and from CLI" and content-desc="Filter sessions, 1" (e1-applied.txt); reopened sheet shows content-desc="iscekic/charlie-service" checkable="true" checked="true" (e1-reopen.txt); after force-quit+relaunch history still shows text="CHARLIE-SERVICE" and content-desc="Filter sessions, 1" (e1-restart.txt); no behavioral UX-DEFECT observed. In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — e1-applied.png
  • proved live: Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — android emulator-5554. Sheet bounded at android.view.ViewGroup Filter sessions tappable [55,216][1025,1963] with one scrollable="true" selected="false" bounds="[101,355][979,1765]" list (e2-run.log); with all 8 returned repositories rendered once each (incl. content-desc="kilo-org/missing-e2e-repo"), the pinned row stays content-desc="Apply" checkable="false" checked="false" clickable="true" ... bounds="[821,1802][979,1917]" and content-desc="Cancel" ... clickable="true" ... bounds="[613,1802][794,1917]" (e2-scrolled.txt); 'SCENE e2 OK' with the Cancel tap closing the sheet proves it is… Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — e2-scrolled.png

[e1] Open Agents → filter sheet lists one checkbox row per recent repository, no duplicates — prior/e1b.png

[e1] In that sheet tap the fourth repository row and Apply: the session list narrows to that repository; reopen the sheet and the row is still checked; force-quit and relaunch the app and the filter is… — e2e-mobile-app/e1-applied.png

[e2] Scroll the sheet with the server's full set of repositories (up to ten) and confirm the Apply/Cancel row stays visible and tappable inside the bounded sheet. — e2e-mobile-app/e2-scrolled.png

[e4] Selected project row for a repository no longer recent still renders and toggles off and on — prior/e4g.png

/home/igor_kilocode_ai/.local/share/kwf/sections/janitor-2026-09-21-features-and-workflows-9807/e2e-web/web-e2e.log
    Error: expect(locator).toBeVisible() failed
    Locator: getByRole('region', { name: 'User profile' })
    Expected: visible
    Error: element(s) not found
    Call log:
      - Expect "toBeVisible" with timeout 30000ms
      - waiting for getByRole('region', { name: 'User profile' })
      58 |
      59 |     const profileCard = page.getByRole('region', { name: 'User profile' });
    > 60 |     await expect(profileCard).toBeVisible({ timeout: 30_000 });
         |                               ^
      61 |     await expect(page.getByRole('link', { name: 'Your Profile' })).toBeVisible();
      62 |     await expect(profileCard.getByRole('button', { name: 'Edit profile' })).toBeVisible();
      63 |     await expect(profileCard.getByText(testEmail, { exact: true })).toBeVisible();
        at /home/igor_kilocode_ai/.local/share/kwf/wt/janitor-2026-09-21-features-and-workflows-9807/apps/web/tests/setup-smoke/profile.spec.ts:60:31
    attachment #1: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/setup-smoke/profile-local-setup-smoke--f6e7e-nd-renders-the-profile-page-chromium/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────
    Error Context: test-results/setup-smoke/profile-local-setup-smoke--f6e7e-nd-renders-the-profile-page-chromium/error-context.md
  1 failed
    [chromium] › tests/setup-smoke/profile.spec.ts:10:7 › local setup smoke › signs in with fake auth and renders the profile page
undefined
/home/igor_kilocode_ai/.local/share/kwf/wt/janitor-2026-09-21-features-and-workflows-9807/apps/web:
[ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL] Command failed with exit code 1: playwright test '--config=playwright.evidence.config.ts'
Owner request

Surface: the mobile app (apps/mobile).

Title: fix(mobile): offer every recent repository in the Agents session filter

Problem

The Agents session filter modal cannot filter by repositories beyond the three most recent ones.

apps/mobile/src/components/agents/use-agent-session-list-data.ts:130-147 builds the modal's project options from recentRepositories?.repositories.slice(0, 3) ?? [], then adds only the currently selected projectFilter values. The backing procedure returns up to ten repositories (apps/web/src/routers/cli-sessions-v2-router.ts:1297-1306 selects with LIMIT 10), so entries 4-10 are dropped by the client. apps/mobile/src/components/agents/platform-filter-modal.tsx:102-108,163-179 renders exactly those options (plus selected values), and both the Agents tab and the session-history screen pass this projectOptions, so there is no other way to add a project filter. A user with four or more recently used repositories cannot filter sessions or search results down to the older ones.

This is a filtering/relevance defect in the session list, not a cosmetic one: the dropped rows are unreachable controls, not just hidden text.

Requested behaviour

The session filter must offer a project row for every repository the cliSessionsV2.recentRepositories query returns (up to the server's own limit), not only the first three, while keeping:

  • the currently selected project values merged in even when they are absent from the recent list (existing behaviour);
  • no duplicate rows (keyed by gitUrl);
  • the sheet's existing single scroll container so a longer list scrolls rather than clipping;
  • the persisted projectFilter round-trip on apply, reopen, and restart.

Do not add a new screen, a repository search endpoint, or a schema change. The smallest correct change is to stop arbitrarily truncating the server list in use-agent-session-list-data.ts (e.g. drop the .slice(0, 3)); if a cap is deliberate, make it match the server contract with a named constant and a comment explaining the bound.

Files in scope

  • apps/mobile/src/components/agents/use-agent-session-list-data.ts (the only product change).

Exclusions / non-goals

  • No change to the cliSessionsV2.recentRepositories server procedure or its LIMIT.
  • No change to platform filtering, sort, search debounce, pagination, or the filter persistence key.
  • No change to Kilo Claw or Kilo Chat surfaces.
  • No new copy is expected; if any label is added, edit src/i18n/locales/en.json only and run pnpm check:i18n.

Prerequisites

  • A test account with at least four sessions across four distinct repositories updated within 30 days, so recentRepositories returns four or more rows.
  • Backend and Metro running through the repository dev runner (never pnpm start).

Acceptance checks

  1. With four or more repositories returned by cliSessionsV2.recentRepositories, open the Agents filter sheet: it lists one checkbox row per returned repository (today it lists three), with no duplicates.
  2. Tap the fourth repository row and Apply: the session list narrows to that repository, the row stays checked on reopen, and the filter survives an app restart.
  3. Tapping a project row for a repository that is selected but no longer in the recent list still renders and toggles it (unchanged merge behaviour).
  4. pnpm test in apps/mobile/, plus pnpm format && pnpm typecheck && pnpm lint && pnpm check:unused from apps/mobile/, all pass; git diff --check is clean.
  5. Local end-to-end proof on the normal workflow: a screenshot of the open filter sheet showing the project rows (at least four visible or scrollable), and a sanitized log excerpt naming each rendered project row label and the applied projectFilter value.

Owner-manual checks

None assigned for this request; all checks above are automatic except the visual judgement of the screenshot, which is covered by check 5.

Notes for the reviewer

Confirm first that the three-row cap is not intentional (there is no comment or test asserting three; the server's LIMIT 10 and the modal's scroll container suggest a longer list was expected). If it is intentional, stop and revise the bound constant instead of removing it.

Follow-ups (not changed here)

  • not proved live: Open Agents → filter sheet on an account with at least four recent repositories: it lists one checkbox row per repository (scroll to see them all) with no duplicate rows. (no capture cited it)
  • not proved live: Select a project filter for a repository, reopen the sheet after that repository is no longer recent: its row still renders and toggles off and on. (no capture cited it)
  • not proved live: iOS: not run — the diff forks on no platform, so Android proves both

Surface: the mobile app (apps/mobile).

Title: fix(mobile): offer every recent repository in the Agents session filter

## Problem

The Agents session filter modal cannot filter by repositories beyond the three most recent ones.

`apps/mobile/src/components/agents/use-agent-session-list-data.ts:130-147` builds the modal's project options from `recentRepositories?.repositories.slice(0, 3) ?? []`, then adds only the currently selected `projectFilter` values. The backing procedure returns up to ten repositories (`apps/web/src/routers/cli-sessions-v2-router.ts:1297-1306` selects with `LIMIT 10`), so entries 4-10 are dropped by the client. `apps/mobile/src/components/agents/platform-filter-modal.tsx:102-108,163-179` renders exactly those options (plus selected values), and both the Agents tab and the session-history screen pass this `projectOptions`, so there is no other way to add a project filter. A user with four or more recently used repositories cannot filter sessions or search results down to the older ones.

This is a filtering/relevance defect in the session list, not a cosmetic one: the dropped rows are unreachable controls, not just hidden text.

## Requested behaviour

The session filter must offer a project row for every repository the `cliSessionsV2.recentRepositories` query returns (up to the server's own limit), not only the first three, while keeping:

- the currently selected project values merged in even when they are absent from the recent list (existing behavio
@iscekic iscekic added the kwf-janitor Nightly mobile janitor request label Sep 21, 2026
@kilo-code-bot

kilo-code-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The session-history filter now offers every repository the server returns (up to its LIMIT 10) instead of truncating to three, with the sheet bounded and its single list scrollable so Apply/Cancel stays reachable; the changed code and tests are correct.

Files Reviewed (4 files)
  • apps/mobile/src/components/agents/use-agent-session-list-data.ts
  • apps/mobile/src/components/agents/platform-filter-modal.tsx
  • apps/mobile/src/components/agents/platform-filter-modal.mounted.test.tsx
  • apps/mobile/src/components/agents/session-history-screen.mounted.test.tsx

Verification Notes

  • Confirmed the removed .slice(0, 3) was the only client-side truncation of recentRepositories in apps/mobile/src; the server procedure bounds the list at 10 (apps/web/src/routers/cli-sessions-v2-router.ts:1306).
  • Confirmed gitUrl dedupe (Map) and the selected-but-not-recent merge still hold, so no duplicate rows and no dropped stale selection.
  • Confirmed the max-h-[80%] + shrink pattern matches existing usages (question-card.tsx, permission-card.tsx) and that percentage arbitrary values are already used in this app.
  • No new subscriptions, listeners, or timers were introduced, so no memory-leak risk.

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

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

This description names a scenario the proof did not capture:

  • not proved live: Open Agents → filter sheet on an account with at least four recent repositories: it lists one checkbox row per repository (scroll to see them all) with no duplicate rows. (no capture cited it)

A repeated proof run rebuilds the same evidence, so no proof run is dispatched for a named gap. Merging with this gap open is your decision.

@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 21, 2026
@iscekic iscekic self-assigned this Sep 21, 2026

@eshurakov eshurakov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after a shallow triage pass. No blocking findings.

@iscekic
iscekic merged commit 07db89e into main Sep 21, 2026
29 checks passed
@iscekic
iscekic deleted the kwf/janitor-2026-09-21-features-and-workflows-9807 branch September 21, 2026 15:26
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