refactor(hermes_cli): group D — AST-neutral bracket hugging / arg packing

This commit is contained in:
Teknium
2026-09-02 20:33:47 -07:00
parent 268ccf8616
commit be5654efb2
5 changed files with 17 additions and 50 deletions
+5 -19
View File
@@ -63,18 +63,13 @@ def _slot_action(
profile: str, profile_dir: Path, prior_state: str | None, start: bool,
) -> ReconcileAction:
return ReconcileAction(
profile=profile,
prior_state=prior_state,
action="started" if start else "registered",
profile=profile, prior_state=prior_state, action="started" if start else "registered",
prior_exit=_read_prior_exit_label(profile_dir),
)
def reconcile_profile_gateways(
*,
hermes_home: Path,
scandir: Path,
dry_run: bool = False,
*, hermes_home: Path, scandir: Path, dry_run: bool = False,
container_argv: Sequence[str] | None = None,
) -> list[ReconcileAction]:
"""Recreate s6 service registrations for every persistent profile.
@@ -150,10 +145,7 @@ def reconcile_profile_gateways(
def _maybe_migrate_legacy_gateway_run_state(
hermes_home: Path,
*,
container_argv: Sequence[str] | None,
dry_run: bool,
hermes_home: Path, *, container_argv: Sequence[str] | None, dry_run: bool
) -> str | None:
"""Seed root gateway_state for pre-s6 `gateway run` containers.
@@ -405,20 +397,14 @@ def main() -> int:
# logs/gateways/<profile>/lock → "Resource busy" restart storm. The role is detected from
# PID 1 argv, not an operator flag — a flag can be forgotten in a hand-written manifest.
if _is_dashboard_container(_read_container_argv()):
print(
"reconcile: skipping (dashboard container — does not need "
"per-profile gateways)"
)
print("reconcile: skipping (dashboard container — does not need per-profile gateways)")
return 0
hermes_home = Path(os.environ.get("HERMES_HOME", "/opt/data"))
scandir = Path(os.environ.get("S6_PROFILE_GATEWAY_SCANDIR", "/run/service"))
actions = reconcile_profile_gateways(hermes_home=hermes_home, scandir=scandir)
for a in actions:
print(
f"reconcile: profile={a.profile} "
f"prior_state={a.prior_state} action={a.action}"
)
print(f"reconcile: profile={a.profile} prior_state={a.prior_state} action={a.action}")
return 0
+1 -3
View File
@@ -100,9 +100,7 @@ def _gh_cli_candidates() -> list[str]:
"""Candidate ``gh`` binary paths, including common Homebrew installs."""
candidates: list[str] = [c for c in (shutil.which("gh"),) if c]
for candidate in (
"/opt/homebrew/bin/gh",
"/usr/local/bin/gh",
str(Path.home() / ".local" / "bin" / "gh"),
"/opt/homebrew/bin/gh", "/usr/local/bin/gh", str(Path.home() / ".local" / "bin" / "gh")
):
if (candidate not in candidates and os.path.isfile(candidate)
and os.access(candidate, os.X_OK)):
+6 -15
View File
@@ -400,9 +400,7 @@ def _print_ticker_health(pids: list) -> None:
the liveness heartbeat and the last-successful-tick marker before saying "will fire".
"""
from cron.jobs import (
get_ticker_heartbeat_age,
get_ticker_last_error,
get_ticker_success_age,
get_ticker_heartbeat_age, get_ticker_last_error, get_ticker_success_age,
TICKER_INTERVAL_SECONDS,
)
from cron.scheduler import _is_fd_exhaustion_text as _cron_is_fd_exhaustion_text
@@ -706,13 +704,10 @@ def cron_create(args):
# job-creation path (CLI AND the agent's `cronjob` tool); a block surfaces as
# result["error"] and is printed in red below.
result = _cron_api(
action="create",
schedule=args.schedule,
prompt=args.prompt,
action="create", schedule=args.schedule, prompt=args.prompt,
skill=getattr(args, "skill", None),
skills=_normalize_skills(getattr(args, "skill", None), getattr(args, "skills", None)),
no_agent=getattr(args, "no_agent", False) or None,
**_job_api_kwargs(args),
no_agent=getattr(args, "no_agent", False) or None, **_job_api_kwargs(args),
)
if not result.get("success"):
print(color(f"Failed to create job: {result.get('error', 'unknown error')}", Colors.RED))
@@ -759,13 +754,9 @@ def cron_edit(args):
final_skills.append(skill)
result = _cron_api(
action="update",
job_id=args.job_id,
schedule=getattr(args, "schedule", None),
prompt=getattr(args, "prompt", None),
skills=final_skills,
no_agent=getattr(args, "no_agent", None),
**_job_api_kwargs(args),
action="update", job_id=args.job_id, schedule=getattr(args, "schedule", None),
prompt=getattr(args, "prompt", None), skills=final_skills,
no_agent=getattr(args, "no_agent", None), **_job_api_kwargs(args),
)
if not result.get("success"):
print(color(f"Failed to update job: {result.get('error', 'unknown error')}", Colors.RED))
+4 -9
View File
@@ -56,8 +56,7 @@ def _scan_dashboard_processes(*, exclude_pids: set[int] | None = None) -> list[t
from hermes_cli._subprocess_compat import bounded_probe_run
result = bounded_probe_run(
["wmic", "process", "get", "ProcessId,CommandLine", "/FORMAT:LIST"],
timeout=10,
["wmic", "process", "get", "ProcessId,CommandLine", "/FORMAT:LIST"], timeout=10,
errors="ignore",
)
if result is None or result.returncode != 0 or result.stdout is None:
@@ -219,9 +218,7 @@ def _profile_key_for_respawn(argv: list[str], hermes_home: str | None = None) ->
def _filter_dashboard_respawn_candidates(
candidates: list[tuple[int, list[str], str | None]],
*,
own_home: str | None = None,
candidates: list[tuple[int, list[str], str | None]], *, own_home: str | None = None
) -> list[list[str]]:
"""Select which killed manual backends to respawn after ``hermes update``.
@@ -346,10 +343,8 @@ def _kill_pids_posix(pids: list[int], killed: list[int], failed: list[tuple[int,
def _kill_stale_dashboard_processes(
reason: str = "the running backend no longer matches the updated frontend",
*,
restart_managed: bool = False,
already_restarted_units: "set[str] | None" = None,
reason: str = "the running backend no longer matches the updated frontend", *,
restart_managed: bool = False, already_restarted_units: "set[str] | None" = None,
) -> dict[str, list]:
"""Kill running ``hermes dashboard`` / ``hermes serve`` processes.
+1 -4
View File
@@ -646,10 +646,7 @@ def _run_debug_share_nous(args, *, log_lines: int, redact: bool) -> None:
if not _confirm_upload(args):
return
if not redact:
print(
"⚠️ --no-redact is set: secrets in your logs will NOT be redacted "
"before upload.\n"
)
print("⚠️ --no-redact is set: secrets in your logs will NOT be redacted before upload.\n")
print("Collecting debug report...")
_best_effort_sweep_expired_pastes()