Merge branch 'main' of github.com:NousResearch/hermes-agent into bb/gui

This commit is contained in:
Brooklyn Nicholson
2026-05-04 16:08:48 -05:00
58 changed files with 6334 additions and 277 deletions
+75
View File
@@ -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