e8399b7c94
* feat(tui): implement completion popup rendering and windowing logic * feat(tui): enhance completion popup with dynamic row budgeting and CSS adjustments * Refactor picker widgets to use shared base class for improved code reuse - Introduced `picker_base.py` to encapsulate common functionality for picker widgets. - Updated `ModelPickerWidget`, `SkillBrowserWidget`, and `ThreadPickerWidget` to inherit from `PickerWidgetBase`. - Implemented selection helpers (`first_selectable_index`, `move_selection`) in `picker_base.py` for consistent item navigation. - Refactored rendering and selection logic in each widget to utilize the new base class methods. - Added tests for picker functionality to ensure behavior remains consistent post-refactor.
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Inline skill browser widget for /evoskills in TUI.
|
|
|
|
Two-phase keyboard-driven widget built on the shared picker engine
|
|
(``picker_base.TagCheckboxBrowserBase``):
|
|
Phase 1 — tag picker (arrow keys + Enter to select, or Esc for all)
|
|
Phase 2 — skill checkbox (arrow keys to navigate, Space to toggle, Enter to confirm)
|
|
|
|
Posts ``SkillBrowserWidget.Confirmed`` with selected install sources,
|
|
or ``SkillBrowserWidget.Cancelled`` on Esc.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, ClassVar
|
|
|
|
from textual.message import Message
|
|
|
|
from .picker_base import TagCheckboxBrowserBase
|
|
|
|
|
|
class SkillBrowserWidget(TagCheckboxBrowserBase):
|
|
"""Inline skill browser — mounts in chat, keyboard-driven."""
|
|
|
|
_INSTALLED_SUFFIX: ClassVar[str] = " (installed)"
|
|
_PHASE2_TITLE: ClassVar[str] = "Select skills to install"
|
|
_PHASE2_CONFIRM_LABEL: ClassVar[str] = "install"
|
|
|
|
class Confirmed(Message):
|
|
"""Posted when user confirms skill selection."""
|
|
|
|
def __init__(self, install_sources: list[str]) -> None:
|
|
super().__init__()
|
|
self.install_sources = install_sources
|
|
|
|
class Cancelled(Message):
|
|
"""Posted when user cancels."""
|
|
|
|
def _item_name(self, item: Any) -> str:
|
|
return item["name"]
|
|
|
|
def _item_tags(self, item: Any) -> list[str]:
|
|
return item.get("tags", [])
|
|
|
|
def _item_desc(self, item: Any) -> str:
|
|
return item["description"]
|
|
|
|
def _post_confirmed(self, items: list[Any]) -> None:
|
|
self.post_message(self.Confirmed([s["install_source"] for s in items]))
|
|
|
|
def _post_cancelled(self) -> None:
|
|
self.post_message(self.Cancelled())
|