Commit 3b2f546
authored
feat: TUI UX improvements - marketplace autocomplete and dynamic filters (#9)
* feat: improve TUI UX with conservative polish (Option 1)
Implements foundational UX improvements to address user confusion
between plugin search and marketplace browser interfaces.
Key Changes:
- Unified terminology: "filter" → "view", "sort mode" → "order"
- Made @marketplace filtering discoverable with placeholder hints
- Added context breadcrumbs when returning from marketplace browser
- Enhanced help view with context-aware sections and annotations
- Fixed critical bugs: pointer stability, bounds checking, string parsing
- Simplified code with helper functions and reduced duplication
UX Improvements:
- Tab key now shows "next view" (plugin list) vs "change order" (marketplace)
- Search placeholder: "Search plugins (or @marketplace to filter)..."
- Status bar displays active marketplace filter: "@marketplace-name (N results)"
- Help view now groups shortcuts by context (plugin actions, marketplace actions, etc.)
- Breadcrumb appears briefly when returning to plugin list: "← from Marketplace Browser"
Bug Fixes:
- Fixed stale pointer reference when selecting marketplace (copy value instead of pointer to slice)
- Added final bounds check to prevent negative scroll offset
- Replaced broken string parsing with strings.SplitN for plugin@marketplace format
- Improved viewport height bounds checking for very small terminals
- Added URL validation before exec.Command calls (GitHub prefix check)
Code Quality:
- Extracted helper functions: formatPluginCount, formatGitHubStats, openURL, openPath
- Consolidated flash message clearing with unified clearFlashAfter function
- Extracted viewport initialization into dedicated functions
- Simplified status bar rendering with focused helper functions
- All tests passing, linter clean, build successful
Related: docs/research/2026-02-04-tui-ux-improvement-options.md
Tasks completed: #1-4 (Option 1 - Conservative Polish)
* refactor: remove breadcrumb feature based on user feedback
The breadcrumb was just a temporary text indicator that didn't provide
real navigation value. User feedback indicated expectation of a proper
navigation history stack (back/forward), which would be a larger feature.
Keeping the 3 core improvements:
- Unified terminology (next view vs change order)
- @marketplace filtering discoverability
- Contextual help view
* feat: add intelligent marketplace autocomplete with picker UI
Implements sophisticated @marketplace filtering with autocomplete UX
based on user feedback during testing.
Key Features:
- Marketplace picker appears when typing @ (replaces "no plugins found")
- Arrow keys navigate marketplace list
- Enter selects marketplace and autocompletes @marketplace-name
- Pattern: @marketplace-name [search terms] for fuzzy search within marketplace
- Example: "@claude-code-plugins test" searches for "test" in that marketplace
UX Improvements:
- Placeholder updated: "or @marketplace-name to filter" (more specific)
- Picker shows marketplace names with plugin counts
- Helpful hint: "↑↓ to navigate • Enter to select • Keep typing to filter"
- Autocomplete deactivates when user adds search terms after marketplace name
Implementation:
- Added marketplaceAutocompleteActive, marketplaceAutocompleteList, marketplaceAutocompleteCursor to Model
- UpdateMarketplaceAutocomplete() detects @ mode and filters marketplace list
- SelectMarketplaceAutocomplete() completes the marketplace name
- Enhanced filteredSearch() to parse "@marketplace-name search" pattern
- Arrow keys and Enter intercepted when autocomplete active
- renderMarketplaceAutocomplete() displays marketplace picker
Note: Syntax coloring for @marketplace deferred (requires textinput cursor customization)
Closes user feedback: confusing "no plugins found" when typing @
* fix: lazy-load marketplace items for autocomplete
Marketplace items weren't loaded at startup, causing 'No marketplaces found'
when typing @. Now lazy-loads marketplace data on first @ keypress.
* fix: autocomplete should exit on any space, not just non-empty search
When user types '@marketplace-name ' (with trailing space), should show
all plugins from that marketplace, not re-enter autocomplete mode.
* feat: add background color to @marketplace-name for visual separation
The @marketplace-name filter now displays with:
- Burnt orange background (PlumMedium)
- White text, bold
- Padding for breathing room
- Creates clear visual distinction from search terms
Example: '@claude-code-plugins test' shows the filter with background
and regular search text without, making the active filter obvious.
* feat: make filter tab counts dynamic based on search results
Filter tab counts now update in real-time as you type or change filters.
Before: All (527) | Discover (74) | Ready (444) | Installed (9)
(static, never changed)
After: All (15) | Discover (3) | Ready (10) | Installed (2)
(updates as you search for 'test')
Implementation:
- Added getDynamicFilterCounts() method
- Calculates count for each filter mode based on current query
- Runs filteredSearch() for each mode to get accurate counts
- Updates in real-time as user types
UX Benefit: Users can see at a glance how many results exist in each
filter without switching tabs.1 parent d58b94b commit 3b2f546
6 files changed
Lines changed: 1045 additions & 362 deletions
File tree
- docs/research
- internal/ui
0 commit comments