feat(tui): LoRA picker overlay with fuzzy search #109

Merged
claude-desktop merged 1 commit from tui/lora-picker-87 into main 2026-04-12 15:55:40 +00:00
Collaborator

Summary

  • Add a searchable LoRA picker overlay to the Generate screen's LoRA panel (a key)
  • Fetches available LoRAs from PluginBridge::list_loras() with loading/error states
  • Fuzzy search filtering via nucleo_matcher (same pattern as the command palette)
  • Shows LoRA name, base model compatibility, and checkmark for already-added entries
  • Enter adds the selected LoRA at weight 1.0; Esc closes without adding
  • Adds as_any_mut() to Screen and Overlay traits for downcast routing of async results

Test plan

  • cargo clippy -p loom-tui -- -D warnings clean
  • cargo test -p loom-tui passes (120 tests including new lora_picker tests)
  • Manual: open Generate screen, Tab to LoRA panel, press a — overlay opens with loading state
  • Manual: type to fuzzy-filter, arrow keys to navigate, Enter to add, Esc to cancel
  • Manual: already-added LoRAs show checkmark marker

Closes charles/loom#87

🤖 Generated with Claude Code

## Summary - Add a searchable LoRA picker overlay to the Generate screen's LoRA panel (`a` key) - Fetches available LoRAs from `PluginBridge::list_loras()` with loading/error states - Fuzzy search filtering via `nucleo_matcher` (same pattern as the command palette) - Shows LoRA name, base model compatibility, and checkmark for already-added entries - Enter adds the selected LoRA at weight 1.0; Esc closes without adding - Adds `as_any_mut()` to `Screen` and `Overlay` traits for downcast routing of async results ## Test plan - [x] `cargo clippy -p loom-tui -- -D warnings` clean - [x] `cargo test -p loom-tui` passes (120 tests including new lora_picker tests) - [ ] Manual: open Generate screen, Tab to LoRA panel, press `a` — overlay opens with loading state - [ ] Manual: type to fuzzy-filter, arrow keys to navigate, Enter to add, Esc to cancel - [ ] Manual: already-added LoRAs show checkmark marker Closes charles/loom#87 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add a searchable LoRA picker overlay to the Generate screen. Pressing
`a` in the LoRA panel opens a modal overlay that fetches available LoRAs
from PluginBridge::list_loras(), provides nucleo-based fuzzy filtering,
shows LoRA name and base model per entry, marks already-added LoRAs with
a checkmark, and adds the selected LoRA at weight 1.0 on Enter.

- New component: components/lora_picker.rs with LoraPickerState
- New overlay variant: OverlayKind::LoraPicker with async fetch
- New actions: AppAction::AddLora, AppAction::LoraListLoaded
- Screen/Overlay traits gain as_any_mut() for downcast routing

Closes charles/loom#87

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Collaborator

Excellent. nucleo_matcher is the right tool for fuzzy search. Clean state management, good async loading pattern, solid tests.

Concern: as_any_mut on both Screen and Overlay traits

This PR adds as_any_mut to both traits. PR #108 also adds it to Screen. These will conflict on merge. Suggest landing one first and rebasing the other.

Concern: Ctrl+k / Ctrl+j for navigation

These conflict with common terminal bindings (Ctrl+j = newline, Ctrl+k = kill line). In the picker context this is fine since it's modal and swallows all keys, but worth noting in the keybinds documentation.

Cross-PR: centered_rect duplication

Third copy (also in #103, #106). Extract to crate::components::layout::centered_rect or crate::util.

Cross-PR: test_ctx() helper duplication

PRs #101, #107, and #109 each define their own test_ctx() -> AppCtx in test modules. Extract to a #[cfg(test)] helper in crate::app or a crate::test_util module.

Minor

  • filter_loras returns Vec<(i32, usize)> — allocates on every call (every render frame via filtered()). For the typical LoRA list size (<1000) this is fine, but if performance matters, consider caching the filtered result and invalidating on query change.
  • current_as_weight defaults strength to 1.0. Consider letting the user adjust strength before confirming (e.g. +/- keys in the picker).
  • The marker for already-added LoRAs is a nice touch.

LGTM with the cross-PR coordination items addressed.

## Review — PR #109: LoRA picker overlay with fuzzy search **Excellent.** `nucleo_matcher` is the right tool for fuzzy search. Clean state management, good async loading pattern, solid tests. ### Concern: `as_any_mut` on both `Screen` and `Overlay` traits This PR adds `as_any_mut` to both traits. PR #108 also adds it to `Screen`. These will conflict on merge. Suggest landing one first and rebasing the other. ### Concern: `Ctrl+k` / `Ctrl+j` for navigation These conflict with common terminal bindings (`Ctrl+j` = newline, `Ctrl+k` = kill line). In the picker context this is fine since it's modal and swallows all keys, but worth noting in the keybinds documentation. ### Cross-PR: `centered_rect` duplication Third copy (also in #103, #106). Extract to `crate::components::layout::centered_rect` or `crate::util`. ### Cross-PR: `test_ctx()` helper duplication PRs #101, #107, and #109 each define their own `test_ctx() -> AppCtx` in test modules. Extract to a `#[cfg(test)]` helper in `crate::app` or a `crate::test_util` module. ### Minor - `filter_loras` returns `Vec<(i32, usize)>` — allocates on every call (every render frame via `filtered()`). For the typical LoRA list size (<1000) this is fine, but if performance matters, consider caching the filtered result and invalidating on query change. - `current_as_weight` defaults strength to `1.0`. Consider letting the user adjust strength before confirming (e.g. `+`/`-` keys in the picker). - The `✓` marker for already-added LoRAs is a nice touch. LGTM with the cross-PR coordination items addressed.
charles force-pushed tui/lora-picker-87 from 9cca104e77 to 4e215ef964 2026-04-12 14:48:00 +00:00 Compare
claude-desktop changed target branch from tui/image-ctx-85 to main 2026-04-12 15:36:28 +00:00
charles force-pushed tui/lora-picker-87 from 4e215ef964 to 9f0be8d60f
Some checks failed
QA / qa (pull_request) Has been cancelled
2026-04-12 15:55:34 +00:00
Compare
claude-desktop deleted branch tui/lora-picker-87 2026-04-12 15:55:40 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom!109
No description provided.