fix(honcho): address PR review findings

- Remove duplicate cmd_sync definition (kept version with error output)
- Fix from_env workspace to stay shared (hermes) not profile-derived
- Add docstring clarifying get_or_create is idempotent in status
- Remove unused import importlib in test
- Fix test assertion for shared workspace in from_env path
- Add 3 tests for sync_honcho_profiles_quiet
This commit is contained in:
Erosika
2026-03-30 17:21:38 -04:00
committed by Teknium
parent c146631e3b
commit a0eae33248
4 changed files with 65 additions and 45 deletions

View File

@@ -190,42 +190,6 @@ def cmd_sync(args) -> None:
print()
def cmd_sync(args) -> None:
"""Sync Honcho config to all existing profiles.
Scans all Hermes profiles and creates host blocks for any that don't
have one yet. Inherits settings from the default host block.
Also called automatically during `hermes update`.
"""
try:
from hermes_cli.profiles import list_profiles
profiles = list_profiles()
except Exception as e:
print(f" Could not list profiles: {e}\n")
return
cfg = _read_config()
if not cfg:
return
default_block = cfg.get("hosts", {}).get(HOST, {})
has_key = bool(cfg.get("apiKey") or os.environ.get("HONCHO_API_KEY"))
if not default_block and not has_key:
return
created = 0
for p in profiles:
if p.name == "default":
continue
if clone_honcho_for_profile(p.name):
print(f" Honcho: + {p.name} -> hermes.{p.name}")
created += 1
if created:
print(f" Honcho: {created} profile(s) synced.")
def sync_honcho_profiles_quiet() -> int:
"""Sync Honcho host blocks for all profiles. Returns count of newly created blocks.
@@ -600,12 +564,17 @@ def cmd_status(args) -> None:
def _show_peer_cards(hcfg, client) -> None:
"""Fetch and display peer cards for the active profile."""
"""Fetch and display peer cards for the active profile.
Uses get_or_create to ensure the session exists with peers configured.
This is idempotent -- if the session already exists on the server it's
just retrieved, not duplicated.
"""
try:
from honcho_integration.session import HonchoSessionManager
mgr = HonchoSessionManager(honcho=client, config=hcfg)
session_key = hcfg.resolve_session_name()
session = mgr.get_or_create(session_key)
mgr.get_or_create(session_key)
# User peer card
card = mgr.get_peer_card(session_key)

View File

@@ -166,12 +166,9 @@ class HonchoClientConfig:
resolved_host = host or resolve_active_host()
api_key = os.environ.get("HONCHO_API_KEY")
base_url = os.environ.get("HONCHO_BASE_URL", "").strip() or None
effective_workspace = workspace_id
if effective_workspace == HOST and resolved_host != HOST:
effective_workspace = resolved_host
return cls(
host=resolved_host,
workspace_id=effective_workspace,
workspace_id=workspace_id,
api_key=api_key,
environment=os.environ.get("HONCHO_ENVIRONMENT", "production"),
base_url=base_url,

View File

@@ -3,7 +3,7 @@
import json
from unittest.mock import patch
from honcho_integration.cli import _resolve_api_key, clone_honcho_for_profile
from honcho_integration.cli import _resolve_api_key, clone_honcho_for_profile, sync_honcho_profiles_quiet
class TestResolveApiKey:
@@ -115,3 +115,58 @@ class TestCloneHonchoForProfile:
assert cfg["hosts"]["hermes.coder"]["aiPeer"] == "hermes.coder"
assert cfg["hosts"]["hermes.coder"]["workspace"] == "hermes" # shared
class TestSyncHonchoProfilesQuiet:
def test_syncs_missing_profiles(self, tmp_path):
config_file = tmp_path / "config.json"
config_file.write_text(json.dumps({
"apiKey": "key",
"hosts": {"hermes": {"peerName": "alice", "memoryMode": "honcho"}},
}))
class FakeProfile:
def __init__(self, name):
self.name = name
self.is_default = name == "default"
profiles = [FakeProfile("default"), FakeProfile("coder"), FakeProfile("dreamer")]
with patch("honcho_integration.cli._config_path", return_value=config_file), \
patch("hermes_cli.profiles.list_profiles", return_value=profiles):
count = sync_honcho_profiles_quiet()
assert count == 2
cfg = json.loads(config_file.read_text())
assert "hermes.coder" in cfg["hosts"]
assert "hermes.dreamer" in cfg["hosts"]
def test_returns_zero_when_no_honcho(self, tmp_path):
config_file = tmp_path / "config.json"
config_file.write_text("{}")
with patch("honcho_integration.cli._config_path", return_value=config_file):
count = sync_honcho_profiles_quiet()
assert count == 0
def test_skips_already_synced(self, tmp_path):
config_file = tmp_path / "config.json"
config_file.write_text(json.dumps({
"apiKey": "key",
"hosts": {
"hermes": {"peerName": "alice"},
"hermes.coder": {"peerName": "existing"},
},
}))
class FakeProfile:
def __init__(self, name):
self.name = name
self.is_default = name == "default"
with patch("honcho_integration.cli._config_path", return_value=config_file), \
patch("hermes_cli.profiles.list_profiles", return_value=[FakeProfile("default"), FakeProfile("coder")]):
count = sync_honcho_profiles_quiet()
assert count == 0

View File

@@ -403,7 +403,6 @@ class TestResolveActiveHost:
assert resolve_active_host() == "hermes"
def test_profiles_import_failure_falls_back(self):
import importlib
import sys
with patch.dict(os.environ, {}, clear=False):
os.environ.pop("HERMES_HONCHO_HOST", None)
@@ -424,7 +423,7 @@ class TestProfileScopedConfig:
with patch.dict(os.environ, {"HONCHO_API_KEY": "key"}):
config = HonchoClientConfig.from_env(host="hermes.coder")
assert config.host == "hermes.coder"
assert config.workspace_id == "hermes.coder"
assert config.workspace_id == "hermes" # shared workspace
assert config.ai_peer == "hermes.coder"
def test_from_env_default_workspace_preserved_for_default_host(self):