Files
Teknium a070a5be33 refactor(health): offset FILE_LINES growth by moving cohesive groups into topical siblings
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)
2026-10-07 10:57:35 -07:00

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}")