feat: filter sessions by state with Tab/Shift+Tab in menu - #314
Conversation
Closes #310. The menu could only filter sessions by text (branch, path, session name); there was no way to narrow to the sessions that need attention (busy/waiting) versus those free for new work (idle). Add a state filter as an independent dimension that composes with the existing text search. Tab cycles it forward (All -> Busy -> Waiting -> Idle -> All) and Shift+Tab backward; the active filter is shown in the footer. The four internal session states collapse into three user-facing categories (pending_auto_approval folds into Waiting), mirroring the status display. Rows without a running session are excluded under any specific state. The filter logic lives in filterByQuery.ts alongside the text filter and is unit-tested; the Menu applies both filters in one pipeline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Show the active "Filtered: ..." (text search) and "State filter: ..." indicators directly above the list they narrow, instead of in the footer status block. The footer keeps only the controls/hints line, with the redundant "Filtered:" prefix dropped from it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kbwo
marked this pull request as ready for review
June 28, 2026 15:06
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.
Closes #310.
Problem
The menu could only filter sessions by text (branch, path, session name). There was no way to narrow the list to the sessions that need attention (busy/waiting) versus those free for new work (idle).
Approach
Issue #310 proposed two UX options (a
s-then-letter sub-mode, or a cycling toggle). This implements a refined version of the cycling option: a session-state filter as an independent dimension that composes with the existing text search, driven by a single keypress.Tabcycles the filter forward:All → Busy → Waiting → Idle → All;Shift+Tabcycles backward.Tab-State Filterhint in the controls line.Why this over the issue's options: a single keypress is fastest (the core need), it adds no separate keymap/mode to learn, and
Tab/Shift+Tabdon't collide with the existing top-level shortcuts.Details
pending_auto_approvalfolds into Waiting, mirroring the status display instatusIcons.ts.All).filterByQuery.tsnext to the existing text filter and is unit-tested.Known limitation
Tabdoes not cycle while the text-search input is active (/mode), matching the existing handler that early-returns in search mode. The query is preserved when leaving search mode, so both filters can still be combined; simultaneous "type and Tab" would need follow-up.Verification
npm run typecheck,npm run lintpass.src/utils/filterByQuery.test.ts(filter categories, pending→waiting folding, session-less exclusion, forward/backward cycling, labels) pass; full suite: 1760 passed. The 6 failing files are pre-existing*.submodule.testcases that fail in this sandbox becausegit config --globalcannot write~/.gitconfig— unrelated to this change.🤖 Generated with Claude Code