Fix: Hermes-Update-Check git-basiert (war an GitHub-Releases, falscher Kanal)
Bug: UI zeigte nie ein Hermes-Update, obwohl die CLI eins anzeigte. Ursache: MC2 verglich das neueste GitHub-RELEASE (frozen v2026.6.19) gegen das installierte Commit — Hermes wird aber aus git main aktualisiert (`hermes update` = git pull origin <branch>), und main laeuft den Releases voraus. Darum war update immer false. Fix: _hermes_agent_update() macht jetzt git fetch + zaehlt Commits HEAD..origin/<branch> (genau wie `hermes update --check`). update=true wenn behind>0; latest = origin-Kurzhash + behind-Count. Tote Release-Helfer (_gh_latest, _commit_ts) + HERMES_AGENT_REPO-Import entfernt. Verifiziert: MC2 == CLI (beide "Update verfuegbar, 1 Commit hinter origin/main"). Frontend (UpdatesCard) rendert components bereits korrekt — nur das Backend-Signal war falsch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,6 @@ from datetime import datetime
|
||||
import httpx
|
||||
import psutil
|
||||
|
||||
from config import HERMES_AGENT_REPO
|
||||
from services import catalog, discover, jobengine, llamaswap, system
|
||||
|
||||
# System-Dienste (root, via sudo -n NOPASSWD) vs. User-Dienste (systemctl --user).
|
||||
@@ -89,42 +88,34 @@ def _engine_update_available() -> bool:
|
||||
_comp_cache = {"ts": 0.0, "data": []}
|
||||
|
||||
|
||||
def _gh_latest(repo: str) -> dict | None:
|
||||
"""Neuestes GitHub-Release {tag, published} oder None."""
|
||||
try:
|
||||
rel = httpx.get(f"https://api.github.com/repos/{repo}/releases/latest",
|
||||
timeout=6, headers={"User-Agent": "MissionControl2"}).json()
|
||||
return {"tag": str(rel.get("tag_name", "")), "published": rel.get("published_at")}
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _commit_ts(path: str) -> int | None:
|
||||
try:
|
||||
p = subprocess.run(["git", "-C", os.path.expanduser(path), "log", "-1", "--format=%ct"],
|
||||
capture_output=True, text=True, timeout=8)
|
||||
return int(p.stdout.strip()) if p.returncode == 0 and p.stdout.strip() else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _hermes_agent_update() -> dict:
|
||||
"""Hermes-Agent: neuestes Release vs. installiertes git-Commit-Datum."""
|
||||
"""Hermes-Agent wird aus **git** aktualisiert (CLI `hermes update` = git pull origin <branch>).
|
||||
Darum HEAD vs. origin/<branch> prüfen (fetch + behind-count) — NICHT GitHub-Releases: die
|
||||
werden selten getaggt, main läuft ihnen voraus → sonst zeigt das UI nie ein Update an."""
|
||||
info = {"key": "hermes_agent", "name": "Hermes Agent", "current": None,
|
||||
"latest": None, "update": False, "reachable": None}
|
||||
git = system.find_hermes_agent_git()
|
||||
if git:
|
||||
if not git or not git.get("path"):
|
||||
return info
|
||||
path = git["path"]
|
||||
info["current"] = git.get("hash")
|
||||
gh = _gh_latest(HERMES_AGENT_REPO)
|
||||
if gh:
|
||||
info["latest"] = gh["tag"]
|
||||
ts = _commit_ts(git["path"]) if (git and git.get("path")) else None
|
||||
if gh["published"] and ts:
|
||||
try:
|
||||
pub = datetime.fromisoformat(gh["published"].replace("Z", "+00:00")).timestamp()
|
||||
info["update"] = pub > ts + 86400 # Release > installiertes Commit (+1 Tag Toleranz)
|
||||
branch = (subprocess.run(["git", "-C", path, "rev-parse", "--abbrev-ref", "HEAD"],
|
||||
capture_output=True, text=True, timeout=8).stdout.strip() or "main")
|
||||
fetch = subprocess.run(["git", "-C", path, "fetch", "-q", "origin", branch],
|
||||
capture_output=True, text=True, timeout=25)
|
||||
info["reachable"] = (fetch.returncode == 0)
|
||||
if fetch.returncode == 0:
|
||||
cnt = subprocess.run(["git", "-C", path, "rev-list", "--count", f"HEAD..origin/{branch}"],
|
||||
capture_output=True, text=True, timeout=8)
|
||||
behind = int(cnt.stdout.strip() or "0") if cnt.returncode == 0 else 0
|
||||
info["behind"] = behind
|
||||
info["update"] = behind > 0
|
||||
oh = subprocess.run(["git", "-C", path, "rev-parse", "--short", f"origin/{branch}"],
|
||||
capture_output=True, text=True, timeout=8).stdout.strip()
|
||||
info["latest"] = (f"{oh} ({behind} neu)" if behind else (oh or info["current"]))
|
||||
except Exception:
|
||||
pass
|
||||
info["reachable"] = False
|
||||
return info
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user