fix(cli): guard missing ui-tui workspace before TUI launch

This commit is contained in:
konsisumer 2026-06-19 19:54:16 +02:00 committed by Teknium
parent 5b45fb269a
commit 537ad9ea9a
2 changed files with 40 additions and 0 deletions

View file

@ -1650,6 +1650,22 @@ def _find_bundled_tui(hermes_cli_dir: Path | None = None) -> Path | None:
return bundled if bundled.is_file() else None
def _exit_missing_tui_workspace(tui_dir: Path) -> "NoReturn":
"""Abort TUI launch with a recovery hint when the workspace checkout is missing."""
print(
"Error: the TUI workspace is missing from this Hermes checkout.\n"
f"Expected directory: {tui_dir}\n"
"This usually means `hermes update` left tracked ui-tui files deleted.\n"
"Recovery:\n"
" 1. From the Hermes checkout, run `git restore -- ui-tui`\n"
" 2. Run `npm install --silent --no-fund --no-audit --progress=false`\n"
" 3. Retry `hermes --tui`\n"
"If the checkout is still inconsistent, run `hermes update --force`.",
file=sys.stderr,
)
sys.exit(1)
def _make_tui_argv(tui_dir: Path, tui_dev: bool) -> tuple[list[str], Path]:
"""TUI: --dev → tsx src; else node dist (HERMES_TUI_DIR prebuilt or esbuild)."""
_ensure_tui_node()
@ -1683,6 +1699,9 @@ def _make_tui_argv(tui_dir: Path, tui_dev: bool) -> tuple[list[str], Path]:
)
sys.exit(1)
if not ext_dir and not tui_dir.is_dir():
_exit_missing_tui_workspace(tui_dir)
# 1. Prebuilt bundle (nix / packaged release): just run it.
if not tui_dev:
if ext_dir:

View file

@ -327,6 +327,27 @@ def test_make_tui_argv_decodes_dev_prebuild_with_utf8_replace(
_assert_utf8_replace_capture(calls[0][1])
def test_make_tui_argv_exits_with_recovery_hint_when_workspace_missing(
tmp_path: Path, main_mod, monkeypatch, capsys
) -> None:
monkeypatch.delenv("HERMES_TUI_DIR", raising=False)
monkeypatch.setattr(main_mod, "_ensure_tui_node", lambda: None)
def fail_which(_name: str) -> str:
raise AssertionError("node/npm lookup must not run when ui-tui is missing")
monkeypatch.setattr(main_mod.shutil, "which", fail_which)
with pytest.raises(SystemExit) as exc:
main_mod._make_tui_argv(tmp_path / "ui-tui", tui_dev=False)
assert exc.value.code == 1
err = capsys.readouterr().err
assert "TUI workspace is missing" in err
assert "git restore -- ui-tui" in err
assert "hermes update --force" in err
# ── _workspace_root helper ──────────────────────────────────────────