Merge branch 'main' of github.com:NousResearch/hermes-agent into bb/gui
This commit is contained in:
@@ -173,3 +173,78 @@ class TestCmdUpdateBranchFallback:
|
||||
mock_input.assert_not_called()
|
||||
captured = capsys.readouterr()
|
||||
assert "Non-interactive session" in captured.out
|
||||
|
||||
|
||||
class TestCmdUpdateProfileSkillSync:
|
||||
"""cmd_update syncs bundled skills to all profiles, including the active one.
|
||||
|
||||
Regression guard for #16176: previously the active profile was excluded
|
||||
from the seed_profile_skills loop, leaving it on stale skill content.
|
||||
"""
|
||||
|
||||
@patch("shutil.which", return_value=None)
|
||||
@patch("subprocess.run")
|
||||
def test_active_profile_included_in_skill_sync(
|
||||
self, mock_run, _mock_which, mock_args, capsys
|
||||
):
|
||||
from pathlib import Path
|
||||
|
||||
mock_run.side_effect = _make_run_side_effect(
|
||||
branch="main", verify_ok=True, commit_count="1"
|
||||
)
|
||||
|
||||
default_p = SimpleNamespace(name="default", path=Path("/fake/.hermes"))
|
||||
active_p = SimpleNamespace(name="bit", path=Path("/fake/.hermes/profiles/bit"))
|
||||
other_p = SimpleNamespace(name="work", path=Path("/fake/.hermes/profiles/work"))
|
||||
all_profiles = [default_p, active_p, other_p]
|
||||
|
||||
synced_paths = []
|
||||
|
||||
def fake_seed(path, quiet=False):
|
||||
synced_paths.append(path)
|
||||
return {"copied": [], "updated": [], "user_modified": []}
|
||||
|
||||
empty_sync = {"copied": [], "updated": [], "user_modified": [], "cleaned": []}
|
||||
|
||||
with (
|
||||
patch("hermes_cli.profiles.list_profiles", return_value=all_profiles),
|
||||
patch("hermes_cli.profiles.seed_profile_skills", side_effect=fake_seed),
|
||||
patch("tools.skills_sync.sync_skills", return_value=empty_sync),
|
||||
):
|
||||
cmd_update(mock_args)
|
||||
|
||||
assert active_p.path in synced_paths, (
|
||||
f"Active profile 'bit' must be included in skill sync; got: {synced_paths}"
|
||||
)
|
||||
assert set(synced_paths) == {p.path for p in all_profiles}, (
|
||||
f"All profiles must be synced; got: {synced_paths}"
|
||||
)
|
||||
|
||||
@patch("shutil.which", return_value=None)
|
||||
@patch("subprocess.run")
|
||||
def test_single_profile_default_is_synced(
|
||||
self, mock_run, _mock_which, mock_args, capsys
|
||||
):
|
||||
from pathlib import Path
|
||||
|
||||
mock_run.side_effect = _make_run_side_effect(
|
||||
branch="main", verify_ok=True, commit_count="1"
|
||||
)
|
||||
|
||||
default_p = SimpleNamespace(name="default", path=Path("/fake/.hermes"))
|
||||
synced_paths = []
|
||||
|
||||
def fake_seed(path, quiet=False):
|
||||
synced_paths.append(path)
|
||||
return {"copied": [], "updated": [], "user_modified": []}
|
||||
|
||||
empty_sync = {"copied": [], "updated": [], "user_modified": [], "cleaned": []}
|
||||
|
||||
with (
|
||||
patch("hermes_cli.profiles.list_profiles", return_value=[default_p]),
|
||||
patch("hermes_cli.profiles.seed_profile_skills", side_effect=fake_seed),
|
||||
patch("tools.skills_sync.sync_skills", return_value=empty_sync),
|
||||
):
|
||||
cmd_update(mock_args)
|
||||
|
||||
assert default_p.path in synced_paths
|
||||
|
||||
Reference in New Issue
Block a user