--- # claudbg-gf58 title: 'TUI: filter panel with persistent history' status: completed type: task priority: normal created_at: 2026-03-31T00:33:21Z updated_at: 2026-03-31T16:49:05Z parent: claudbg-2vwx blocked_by: - claudbg-4bms --- Add a filter text box panel at the bottom of the TUI screen (visible on sessions list and agents list screens). **Behavior:** - Press `t` to focus the filter input directly; Tab cycles to it among panels - Type a filter query and press Enter to apply it to the current list - Escape clears the text input - Up/Down arrow keys cycle through scroll-back history of previous queries - After pressing Enter, focus returns to the main list panel - The filter does not apply to transcript screens (transcripts cannot be filtered) **History persistence:** - History is saved to and loaded from `~/.claude/claudbg.tui.history` (one query per line) - History persists across TUI sessions Depends on the filter query parser. ## Summary of Changes ### Files Modified **`src/tui/state.rs`** - Added `FilterInput` variant to the `Focus` enum - Added filter state fields to `AppState`: `filter_input`, `filter_active`, `filter_history`, `filter_history_pos` - Added `history_file_path()` helper (resolves to `~/.claude/claudbg.tui.history`) - Added `load_history()` to load history lines from disk at TUI startup - Added `append_history_to_disk()` to append a single query in append mode (no full rewrite) - Updated `AppState::new()` to load history and initialize filter fields **`src/tui/screens/session_list.rs`** - Added imports for `Direction`, `Layout`, `Color`, `Span`, `Line`, `Paragraph`, `Focus`, `Filter` - Rewrote `render_session_list` to split area: top for table, bottom 3 rows for filter bar - Added `render_filter_bar` function: shows "Filter: " label + input text + cursor when focused - Filter bar highlights border in yellow when focused, shows placeholder hint when unfocused/empty - Sessions table applies active filter via `Filter::parse` + `Filter::matches` - Table title shows active filter query when one is set - Added `filtered_session_indices` helper for navigation with filtered rows - Updated `handle_session_list_event`: when `Focus::FilterInput`, dispatches to `handle_filter_input_event` - Added `t` key and Tab to focus filter input; Tab from filter returns focus to list - Updated Down/Enter to work with filtered session indices - Added `handle_filter_input_event` handling: char input, Backspace, Enter (apply + return focus), Escape (clear input, stay focused), Up/Down for history browsing, Tab (cycle focus) **`src/tui/screens/transcript.rs`** - Added `Focus::FilterInput` to Tab and Up/Down match arms (treated same as ChatLog on transcript screen) **`src/cli.rs`** - Fixed pre-existing clippy warning: replaced `map_or(false, ...)` with `is_ok_and(...)`