diff --git a/hermes_cli/copilot_auth.py b/hermes_cli/copilot_auth.py index fca2f96b70..f7b0066389 100644 --- a/hermes_cli/copilot_auth.py +++ b/hermes_cli/copilot_auth.py @@ -96,11 +96,10 @@ def resolve_copilot_token() -> tuple[str, str]: 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")): - if (candidate not in candidates and os.path.isfile(candidate) - and os.access(candidate, os.X_OK)): - candidates.append(candidate) + candidates += [ + c for c in ("/opt/homebrew/bin/gh", "/usr/local/bin/gh", str(Path.home() / ".local/bin/gh")) + if c not in candidates and os.path.isfile(c) and os.access(c, os.X_OK) + ] return candidates diff --git a/hermes_cli/dashboard_procs.py b/hermes_cli/dashboard_procs.py index afde2e30dc..c0f61950a3 100644 --- a/hermes_cli/dashboard_procs.py +++ b/hermes_cli/dashboard_procs.py @@ -243,13 +243,8 @@ def _exclude_pids_from_env() -> set[int]: """PIDs Desktop marks as live backends (``HERMES_DESKTOP_CHILD_PID``, comma-separated).""" out: set[int] = set() for part in os.environ.get("HERMES_DESKTOP_CHILD_PID", "").split(","): - part = part.strip() - if not part: - continue - try: + with contextlib.suppress(ValueError): out.add(int(part)) - except ValueError: - continue return out @@ -265,18 +260,17 @@ def _kill_pids_windows(pids: list[int], killed: list[int], failed: list[tuple[in expected_start_time = pid_start_times.get(pid) if expected_start_time is None: failed.append((pid, "could not verify process identity")) - continue - if not pid_is_hermes(pid, expected_start_time=expected_start_time): + elif not pid_is_hermes(pid, expected_start_time=expected_start_time): failed.append((pid, "not hermes-owned or process identity changed")) - continue - result = subprocess.run(["taskkill", "/PID", str(pid), "/F"], stdout=subprocess.PIPE, - stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, text=True, - encoding="utf-8", errors="replace", timeout=10, - creationflags=windows_hide_flags()) - if result.returncode == 0: - killed.append(pid) else: - failed.append((pid, (result.stderr or result.stdout or "").strip())) + result = subprocess.run( + ["taskkill", "/PID", str(pid), "/F"], stdout=subprocess.PIPE, + stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, text=True, encoding="utf-8", + errors="replace", timeout=10, creationflags=windows_hide_flags()) + if result.returncode == 0: + killed.append(pid) + else: + failed.append((pid, (result.stderr or result.stdout or "").strip())) except (FileNotFoundError, subprocess.TimeoutExpired, OSError) as e: failed.append((pid, str(e))) @@ -552,17 +546,15 @@ def _valid_lockfile_payload(parsed: object, ownership_id: str) -> bool: or not _is_hex(parsed.get("tokenFingerprint"), 32) ): return False - pid = parsed.get("pid") - port = parsed.get("port") - if not isinstance(pid, int) or not 0 < pid <= 4194304: + pid, port = parsed.get("pid"), parsed.get("port") + if not (isinstance(pid, int) and 0 < pid <= 4194304): return False - if not isinstance(port, int) or not 0 <= port <= 65535: + if not (isinstance(port, int) and 0 <= port <= 65535): return False # String fields must be present and bounded (the writer enforces <=1024). - for field in ("profile", "hermesPath", "hermesHome", "logPath", "startedAt"): - value = parsed.get(field) - if not isinstance(value, str) or len(value) > 1024: - return False + if any(not isinstance(parsed.get(f), str) or len(parsed[f]) > 1024 + for f in ("profile", "hermesPath", "hermesHome", "logPath", "startedAt")): + return False # logPath is ``{lock_root}/{ownershipId}/{spawnNonce}.log``; only the suffix is checked so a # relocated HERMES_HOME can't falsely reject a legitimate backend (= re-introduce the kill). return parsed["logPath"].endswith(f"/{ownership_id}/{parsed['spawnNonce']}.log") @@ -576,10 +568,8 @@ def _lock_owned_serve_pids(base_dir: Path | None = None) -> set[int]: import json root = base_dir if base_dir is not None else _hermes_home_dir() / _REMOTE_LOCK_SUBDIR owned: set[int] = set() - if not root.is_dir(): - return owned try: - entries = list(root.iterdir()) + entries = list(root.iterdir()) if root.is_dir() else [] except OSError: return owned for entry in entries: diff --git a/hermes_cli/debug.py b/hermes_cli/debug.py index 436e10614f..f2edfb3003 100644 --- a/hermes_cli/debug.py +++ b/hermes_cli/debug.py @@ -56,11 +56,8 @@ def _pending_file() -> Path: def _load_pending() -> list[dict]: - path = _pending_file() - if not path.exists(): - return [] try: - data = json.loads(path.read_text(encoding="utf-8")) + data = json.loads(_pending_file().read_text(encoding="utf-8")) except (OSError, ValueError): return [] if not isinstance(data, list): @@ -265,10 +262,8 @@ def _missing_log_note(log_name: str) -> str: reason = _CLIENT_SIDE_LOGS.get(log_name) if reason is None: return "(file not found)" - primary = _primary_log_path(log_name) - where = f" — expected at {primary}" if primary else "" - return f"(not on this host: {reason}{where})" + return f"(not on this host: {reason}{f' — expected at {primary}' if primary else ''})" def _resolve_log_path(log_name: str) -> Optional[Path]: