Commit Graph

6 Commits

Author SHA1 Message Date
Xi Zhang e8399b7c94 fix(tui): window slash-command completions to terminal height (#362)
* 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.
2026-07-16 16:17:58 +01:00
Xi Zhang 372a6272b7 fix(onboard): Windows npx detection & rename /install-skills to /evoskills (#79)
* fix: improve npx detection on Windows using shutil.which

* fix: rename /install-skills command to /evoskills for consistency
2026-03-20 10:42:56 +00:00
Jan Piotrowski 81316ffb2d chore: resolve all ruff linting and static analysis errors in EvoScientist/
- Fix RUF006: Implement background task tracking in Discord, iMessage, WeChat, and TUI to prevent premature GC of fire-and-forget tasks.
- Fix B904: Add explicit exception chaining (raise ... from) across all exception handlers.
- Fix RUF012: Annotate mutable class attributes with ClassVar for command arguments and media maps.
- Fix B008: Refactor Typer commands in cli/commands.py to use Annotated for argument and option defaults.
- Fix B023/B018: Resolve late-binding issues in lambdas and remove useless expressions.
- Fix syntax errors in retry.py docstrings and models.py lambda parameter ordering.
2026-03-19 17:04:03 +01:00
Jan Piotrowski 4a3d6c0318 chore: add ruff lint rules and turn on formatting 2026-03-19 17:04:02 +01:00
dinos 7ebaa2cec0 feat: implement command to browse and install MCP servers (#65)
* refactor(mcp): extract MCP server registry from onboard into shared module

Move _RECOMMENDED_MCP_SERVERS, _install_pip_package, and
_pip_install_hint from config/onboard.py into mcp/registry.py as a
shared MCPServerEntry dataclass and registry functions. This enables
reuse by the new /install-mcp command and marketplace integration.

* feat(mcp): add /install-mcp command for browsing and installing MCP servers

Interactive browser for MCP servers (built-in registry + EvoSkills
marketplace), supporting three modes:
- /install-mcp         — interactive tag filter + checkbox selection
- /install-mcp <name>  — direct install by name or tag pre-filter
- /install-mcp file.yaml — import servers from arbitrary YAML file

Also available as /mcp install and EvoSci mcp install. Includes TUI
browser widget (MCPBrowserWidget) mirroring the skill browser UX.

* chore(tavily): conditionally pass tavily_search when TAVILY_API_KEY is set

* fix(tui): Enter key detection for /install-mcp

- Fix message handler names: Textual converts MCPBrowserWidget to
  mcpbrowser_widget (not mcp_browser_widget), so Confirmed/Cancelled
  messages were never received by the app
- Distinguish empty selection from cancel in result handling

* chore(widgets): stop auto-advancing cursor on Space toggle in browser widgets

* style: linter

* refactor(mcp): simplify MCP registry to marketplace-only

Remove built-in server list and arbitrary YAML import — all server
definitions now come from the EvoSkills marketplace (mcp/*.yaml).
Onboarding filters by the `onboarding` tag instead of a hardcoded list.

* refactor(mcp): consolidate /install-mcp into /mcp install

Remove standalone /install-mcp command — use /mcp install as the
single entry point. CLI adapter now delegates logic to the shared
InstallMCPCommand class, keeping only the questionary UI layer.

* chore(cli): rm reference to yaml import
2026-03-19 12:45:32 +00:00
dinos 2f855c07c7 feat: add /install-skills command with tag-based skill browsing (#48)
* feat: add tag support to skill metadata parser

- Add `tags` field to `SkillInfo` dataclass
- Extend `_parse_skill_md` to return `SkillInfo` directly (instead of
  dict), extracting tags from top-level `tags` or `metadata.tags`
fallback
- Accept `source` as keyword argument in `_parse_skill_md` to avoid
  post-hoc mutation
- Add `_normalize_tags` helper (handles list, comma-string, missing)
- Add `list_skills_by_tag()` for filtering installed skills by tag
- Add `get_all_tags()` returning tags sorted by count then
alphabetically
- Add `fetch_remote_skill_index()` with shallow-clone and 10-min cache
- Add 12 new tests covering tag parsing, filtering, and remote index

* feat: add /install-skills command and browse action to skill_manager tool

CLI:
- Add `/install-skills` slash command with interactive tag picker and
  skill checkbox (questionary-based, for CLI mode)
- Accepts optional tag argument for pre-filtering: `/install-skills
core`
- Update `/skills` listing to show tags per skill
- Register command in interactive.py dispatch

LangChain tool:
- Add `browse` action to `skill_manager` tool with optional `tag` filter
- Update `list` and `info` actions to include tags in output

* feat: add interactive skill browser widget for TUI

New widget (skill_browser.py):
- Two-phase keyboard-driven widget mounted inline in chat
- Phase 1: tag picker (arrow keys + Enter, Esc to cancel)
- Phase 2: skill checkbox (Space to toggle, Enter to install, Esc back)
- Width-aware description truncation with ellipsis
- Installed skills shown as non-toggleable with checkmark

TUI integration (tui_interactive.py):
- Register /install-skills command with async widget flow
- Echo executed commands in cyan before output
- Add SkillBrowserWidget keyboard delegation (up/down/esc)
- Refocus prompt input after any widget dismissal (also fixes
  pre-existing /resume and /delete focus bug)
- Show tags as bulleted newlines in /skills table
- Dynamic autocomplete padding based on longest item
2026-03-17 12:04:23 +00:00