feat(mobile): unify session filtering across the live and history pages - #5631
Merged
Conversation
The live Agents list showed every running session with no way to narrow it. Add the same filter affordance the history screen uses: a filter button in the header, removable chips, and the shared filter modal. - Filter by repository and by origin bucket (cloud agent, extension, CLI, Slack, GitHub, Linear, other). - Build both option sets from the live rows themselves, so the picker never offers a value with nothing running. - Filter in memory. The live set is already fully loaded, so no refetch. - Show a clearable no-match empty state when a filter hides every row. - Reuse the existing translations. No new i18n keys. The filter modal now hides its sort section when no sort is given, and takes the platform rows to offer. `PLATFORM_FILTERS` and `ProjectFilterOption` move to `session-list-helpers` so pure modules can read them without pulling in React Native.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryIncremental commit 7b7aa5d fixes the prior sign-out cleanup, filter-load flash, and no-match CTA issues; no new findings on current HEAD. Files Reviewed (10 files)
Previous Review Summaries (3 snapshots, latest commit d09783e)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit d09783e)Status: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (18 files)
Fix these issues in Kilo Cloud Previous review (commit 7db57e8)Status: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous review (commit 05e662d)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
Files Reviewed (6 files)
Reviewed by grok-4.6 · Input: 102.4K · Output: 12.9K · Cached: 319.5K Review guidance: REVIEW.md from base branch |
Hermes does not implement Array.prototype.toSorted. The map already copies, so sort() mutates nothing shared.
Both session-list pages now share one filtering UI. The pages stay separate: each keeps its own list, its own persisted filter record, and its own screen. - Add a count badge to the filter button while filters are applied. The count is spoken as the button's accessibility value, so no new string is needed. - Persist the live page's filters under their own SecureStore key. - Add search to the live page. The live set is in memory, so it matches the title and the repository locally, with no debounce and no refetch. - Remove the sort control. Both pages order by creation time; Home and the Share gate keep `updated_at`, which they already pass explicitly. `AgentSessionFilters` loses `sortBy`, so `clearBroadly` takes a plain clear callback instead of a filter transform. The persisted-filters hook now takes its storage key as a parameter. Sort strings are dropped from all 88 locales.
scripts/lint-all.sh runs a stricter type-aware config than the mobile package's own lint script. Use vi.fn().mockResolvedValue so the mocks trip neither prefer-await-to-then nor require-await.
- Delete the live filter record on sign-out. Without it, User A's repository and origin filters loaded for User B and hid B's running sessions. - Hold the live skeletons until the stored filter record resolves. The list painted unfiltered first, then dropped rows when the record arrived. - Make the no-match CTA do exactly what its label says. It read "Clear search" while also dropping the persisted filters. Both pages now clear only the one the label names, which leaves `clearBroadly` with no caller.
RSO
approved these changes
Aug 28, 2026
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.
What
Both session-list pages get one shared filtering UI. The pages stay separate — each keeps its own list, its own persisted filter record, and its own screen.
How
SessionFilterButton— the sliders icon plus a count badge while filters are applied. The count is spoken as the button'saccessibilityValue, so it needs no new translated string.expandPlatformFilterrather than duplicating the mapping.usePersistedAgentSessionFiltersnow takes its SecureStore key as a parameter. The live page usesLIVE_SESSION_FILTERS_KEY; history keepsSESSION_FILTERS_KEY. Separate records, because the pages filter separate lists.SESSION_LIST_SORT). Home and the Share gate are unaffected — they already passupdated_atexplicitly.Follow-on cleanup
Dropping the sort control let a few things collapse:
AgentSessionFilterslosessortBy, soclearAgentSessionNarrowingFiltersis gone andclearBroadlytakes a plain clear callback instead of a filter transform.AgentSessionListContentanduseAgentSessionListDatano longer thread asortByprop, and theSectionListno longer remounts on sort change.sortBy/sortLastUpdated/sortCreatedare removed from all 88 locales.PLATFORM_FILTERSandProjectFilterOptionmove tosession-list-helpersso pure modules can read them without pulling in React Native.Legacy persisted records that still carry
sortByparse fine — the field is ignored.Tests
live-session-filters.test.ts— bucket folding, option building, AND-combined filtering, title and repository search, whitespace-only query, unknown-origin and no-repository rows.session-list-screen.mounted.test.tsx— filter button visibility and badge count, repository filtering, search narrowing, search-header visibility, clearable no-match state.agent-session-filters.test.ts— filter counting, legacysortBytolerance.pnpm format && pnpm typecheck && pnpm lint && pnpm check:unusedclean.pnpm test6402 passed. Rootpnpm typecheckclean.