mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
main's ratchet caps every >2000-line facade at its main value; the PR grew seven. - config.py: `hermes config show` rendering -> hermes_cli/config_show.py (reads config names via the module at call time so hermes_cli.config.<name> patch seams hold). - backup.py: the cron prompt-field safety net -> hermes_cli/backup_cron_prompts.py; also drops a dead duplicate _PROTECTED_CONFIG_PATHS left by an earlier merge (the later definition won). restore_config_model_settings_* stay in backup: they are on the frozen old-updater surface. - profiles.py: Honcho host migration on rename -> hermes_cli/profiles_honcho.py. - plugins.py: resolve_plugin_command_result -> plugins_dispatch.py (re-exported from plugins, the public import path for cli/tui_gateway/plugins). - main.py: --query-file reader -> hermes_cli/main_query_file.py. - kanban_db.py: worker-context section renderers (_ctx_* + caps) -> hermes_cli/kanban_db_context.py; build_worker_context stays in kanban_db. - config_defaults.py: drop the blank line the gateway block gained. Patch-target retargets (moved symbols only): test_plugins.py (asyncio / await timeout now in plugins_dispatch), test_managed_scope_surfacing.py (show_config import), test_backup.py (restore_cron_prompt_fields_if_degraded import). (cherry picked from commit 4079d422e0c2283c500c16885e959f5c170eb6cf)
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""Honcho host-block migration for ``hermes profile rename``.
|
|
|
|
Split out of ``hermes_cli.profiles``; the profiles root is late-imported from there so its
|
|
``_get_default_hermes_home`` seam holds.
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def _atomic_write_json(path: Path, data: dict) -> bool:
|
|
"""Atomic rewrite of a third-party JSON config; False on OSError (nothing partially written)."""
|
|
from utils import atomic_json_write
|
|
try:
|
|
atomic_json_write(path, data)
|
|
return True
|
|
except OSError:
|
|
return False
|
|
|
|
|
|
def migrate_honcho_profile_host(old_name: str, new_name: str, new_dir: Path) -> None:
|
|
"""Rename Honcho host blocks for a renamed profile without changing peers."""
|
|
from hermes_cli.profiles import _get_default_hermes_home
|
|
|
|
old_host = f"hermes_{old_name}"
|
|
legacy_old_host = f"hermes.{old_name}"
|
|
new_host = f"hermes_{new_name}"
|
|
candidates = [
|
|
new_dir / "honcho.json", _get_default_hermes_home() / "honcho.json", Path.home() / ".honcho" / "config.json"
|
|
]
|
|
seen: set[Path] = set()
|
|
for path in candidates:
|
|
try:
|
|
resolved = path.resolve()
|
|
except OSError:
|
|
resolved = path
|
|
if resolved in seen or not path.is_file():
|
|
continue
|
|
seen.add(resolved)
|
|
try:
|
|
raw = json.loads(path.read_text(encoding="utf-8-sig"))
|
|
except (OSError, json.JSONDecodeError):
|
|
continue
|
|
hosts = raw.get("hosts")
|
|
if not isinstance(hosts, dict):
|
|
continue
|
|
source_host = old_host if old_host in hosts else legacy_old_host
|
|
if source_host not in hosts:
|
|
continue
|
|
if new_host in hosts:
|
|
print(f"⚠ Honcho host block not migrated: {new_host} already exists in {path}")
|
|
continue
|
|
block = hosts[source_host]
|
|
if isinstance(block, dict) and "aiPeer" not in block:
|
|
block["aiPeer"] = old_name # source_host is ``hermes_<old>`` or legacy ``hermes.<old>``
|
|
hosts[new_host] = hosts.pop(source_host)
|
|
if _atomic_write_json(path, raw):
|
|
print(f"✓ Honcho host updated: {source_host} → {new_host}")
|