fix(gui): detect leftover desktop install records

On macOS, `hermes update` and `hermes desktop` reinstall any Hermes.app
listed in desktop-installed-apps.json that has gone missing, and the GUI
uninstall is what deletes that record. gui_is_installed() ignored the
record, so after the app was removed by hand `hermes uninstall --gui`
reported that no GUI was installed and returned without deleting it, and
the next update put the app back.

Count the install record in gui_is_installed() so the uninstall previews
and removes it. No new removal targets: uninstall_gui() already deletes
the record. The retention tests now also run with the record as the only
remaining GUI artifact.

Refs: #128974
Salvaged-from: #131147
This commit is contained in:
itsflownium
2026-10-02 19:31:42 +10:00
committed by unsupportedpastels
parent f9fec19d96
commit 80efaa56ee
2 changed files with 10 additions and 4 deletions

View File

@@ -86,8 +86,11 @@ def agent_is_installed(hermes_home: Path) -> bool:
def gui_is_installed(hermes_home: Path) -> bool:
"""Return True when any desktop GUI artifact exists (built or packaged)."""
return any(p.exists() for p in (*source_built_gui_artifacts(hermes_home), *packaged_gui_app_paths(), desktop_userdata_dir()))
"""Return True when any desktop GUI artifact or install record exists."""
return any(p.exists() for p in (
*source_built_gui_artifacts(hermes_home), *packaged_gui_app_paths(),
desktop_userdata_dir(), desktop_install_record(),
))
def gui_install_summary(hermes_home: "Path | None" = None) -> dict:

View File

@@ -9,9 +9,10 @@ from hermes_cli import gui_uninstall, main
from hermes_constants import get_hermes_home
@pytest.fixture
def installation(tmp_path, monkeypatch):
@pytest.fixture(params=("complete", "record_only"))
def installation(request, tmp_path, monkeypatch):
monkeypatch.setattr(Path, "home", lambda: tmp_path)
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
home = get_hermes_home()
assert home.resolve().is_relative_to(tmp_path.resolve())
root = home / "hermes-agent"
@@ -35,6 +36,8 @@ def installation(tmp_path, monkeypatch):
userdata / "connections.json": b'{"fixture": true}',
record: b'{"fixture": true}',
}
if request.param == "record_only":
gui_files = {record: gui_files[record]}
for path, data in {**protected, **gui_files}.items():
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(data)