fix(update-check): stop reporting phantom "N commits behind" inside Docker (#39559)
Inside the published Docker image, both the `--tui` banner and the dashboard-embedded TUI report `1 commit behind — run docker pull nousresearch/hermes-agent:latest to update` even though the container has no git repo and no way to compute a commit delta. Root cause: two independent update-detection paths, only one of which knows it's running in Docker. - `recommended_update_command()` → `detect_install_method()` reads the `.install_method` stamp that `docker/stage2-hook.sh` writes at boot → returns "docker", so the *command string* correctly says `docker pull`. - `banner.check_for_updates()` (the source of the "N commits behind" *count*) has no notion of the docker install method. It only detects a build via `HERMES_REVISION` (nix-only, unset in the image) or a `.git` dir (excluded from the image by .dockerignore). Neither matches, so it silently falls through to `check_via_pypi()`, whose PyPI-version mismatch flag (1) is then rendered verbatim by the CLI banner (build_welcome_banner), the Ink TUI badge (branding.tsx), and `hermes version` as "1 commit behind" — a phantom count, no commit math involved. `hermes update` already refuses to run in-place in the container. The dashboard's REST `/api/hermes/update/check` endpoint already short-circuits docker (returns behind=None + the docker guidance). This mirrors that guard inside `check_for_updates()` so the banner/TUI/version surfaces agree: when `detect_install_method() == "docker"`, return None before any git/pypi probe (and before writing a cache entry). None makes the render guards (`typeof === 'number' && > 0`, `behind and behind > 0`) stay false, so the badge/line disappears entirely — matching the System page. Fix is in one place (check_for_updates) because all three consumers route through it via get_update_result()/_update_result. Tests: test_check_for_updates_docker_returns_none asserts None + no git/pypi probe + no cache write; test_check_for_updates_non_docker_still_checks guards against over-broadening (pip still version-checks). Mutation-tested: removing the guard fails the docker test. Verified against a real `docker build` of the image — see PR description.
This commit is contained in:
@ -225,6 +225,25 @@ def check_for_updates() -> Optional[int]:
|
||||
cache_file = hermes_home / ".update_check"
|
||||
embedded_rev = os.environ.get("HERMES_REVISION") or None
|
||||
|
||||
# Docker images have no working tree to count commits against — the
|
||||
# published image excludes `.git` (see .dockerignore) and sets no
|
||||
# HERMES_REVISION (that's nix-only). Without this guard the checks below
|
||||
# fall through to `check_via_pypi()`, whose PyPI-version mismatch flag (1)
|
||||
# then gets rendered by the CLI banner and the TUI badge as a phantom
|
||||
# "1 commit behind" — even though no git repo or commit math is involved,
|
||||
# and `hermes update` correctly refuses to run in-place inside the
|
||||
# container anyway. The dashboard's REST `/api/hermes/update/check`
|
||||
# endpoint already short-circuits docker the same way (web_server.py);
|
||||
# mirror that here so the banner/TUI surfaces agree. Returning None makes
|
||||
# both the Rich banner (build_welcome_banner) and the Ink badge
|
||||
# (branding.tsx, guarded on `typeof === 'number' && > 0`) show nothing.
|
||||
try:
|
||||
from hermes_cli.config import detect_install_method
|
||||
if detect_install_method() == "docker":
|
||||
return None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Read cache — invalidate if the embedded rev OR installed version has
|
||||
# changed since the last check. The version guard matters for pip installs:
|
||||
# `check_via_pypi()` compares against VERSION, so a `pip install --upgrade`
|
||||
|
||||
Reference in New Issue
Block a user