From 333e4abe30327eae769a10a559baf3acb5ca8cf8 Mon Sep 17 00:00:00 2001 From: Verne <1783491278@qq.com> Date: Mon, 9 Mar 2026 01:43:59 +0800 Subject: [PATCH] fix: Initialize Skills Hub on list Call ensure_hub_dirs() at the start of hermes skills list so the\nSkills Hub directory structure is created before reading hub\nmetadata.\n\nAdd a regression test covering the empty-home path where\ndoctor recommends running the list command.\n\nRefs: #703 --- hermes_cli/skills_hub.py | 3 ++- tests/hermes_cli/test_skills_hub.py | 31 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/hermes_cli/test_skills_hub.py diff --git a/hermes_cli/skills_hub.py b/hermes_cli/skills_hub.py index 32a0bab1..8b72fe4f 100644 --- a/hermes_cli/skills_hub.py +++ b/hermes_cli/skills_hub.py @@ -408,10 +408,11 @@ def do_inspect(identifier: str, console: Optional[Console] = None) -> None: def do_list(source_filter: str = "all", console: Optional[Console] = None) -> None: """List installed skills, distinguishing builtins from hub-installed.""" - from tools.skills_hub import HubLockFile, SKILLS_DIR + from tools.skills_hub import HubLockFile, ensure_hub_dirs from tools.skills_tool import _find_all_skills c = console or _console + ensure_hub_dirs() lock = HubLockFile() hub_installed = {e["name"]: e for e in lock.list_installed()} diff --git a/tests/hermes_cli/test_skills_hub.py b/tests/hermes_cli/test_skills_hub.py new file mode 100644 index 00000000..7b1165be --- /dev/null +++ b/tests/hermes_cli/test_skills_hub.py @@ -0,0 +1,31 @@ +from io import StringIO + +from rich.console import Console + +from hermes_cli.skills_hub import do_list + + +def test_do_list_initializes_hub_dir(monkeypatch, tmp_path): + import tools.skills_hub as hub + import tools.skills_tool as skills_tool + + hub_dir = tmp_path / "skills" / ".hub" + monkeypatch.setattr(hub, "SKILLS_DIR", tmp_path / "skills") + monkeypatch.setattr(hub, "HUB_DIR", hub_dir) + monkeypatch.setattr(hub, "LOCK_FILE", hub_dir / "lock.json") + monkeypatch.setattr(hub, "QUARANTINE_DIR", hub_dir / "quarantine") + monkeypatch.setattr(hub, "AUDIT_LOG", hub_dir / "audit.log") + monkeypatch.setattr(hub, "TAPS_FILE", hub_dir / "taps.json") + monkeypatch.setattr(hub, "INDEX_CACHE_DIR", hub_dir / "index-cache") + monkeypatch.setattr(skills_tool, "_find_all_skills", lambda: []) + + console = Console(file=StringIO(), force_terminal=False, color_system=None) + + assert not hub_dir.exists() + + do_list(console=console) + + assert hub_dir.exists() + assert (hub_dir / "lock.json").exists() + assert (hub_dir / "quarantine").is_dir() + assert (hub_dir / "index-cache").is_dir()