Packaged installs failing to locate bundled TUI assets
Cluster 19514 · dashboard. Data as of
1 open item. Fix merged in #67116 on 18 Jul 2026. Check it covers your case.
The short answer
- Known?
- Yes. 16 related items grouped here, 5 issues already closed.
- Fix event
- A fix was merged to main in PR #67116. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PR #67116. That is separate from the fix event. - Still open
- 0 issues and 1 PR.
Most members concern the TUI (--tui / Chat tab) on packaged installs such as pip, pipx, and Homebrew, where a ui-tui workspace check or missing runtime assets in the package is reported alongside proposed changes to try the bundled TUI first, adjust manifests, or give clearer messages. One bug report (a bare FileNotFoundError) has too little detail to confirm it belongs to this theme.
Open issues0
Open PRs1
- PR#19525fix(package): include TUI runtime assets in manifest
Fixes on record
-
#67116 fix(cli): try bundled TUI before requiring ui-tui workspace
files:
contributors/emails/[redacted:email],hermes_cli/main.py,tests/hermes_cli/test_tui_npm_install.pyShow the diff
-
contributors/emails/[redacted:email]@@ -0,0 +1,2 @@ +lucaskvasirr +# PR #56672 salvage (fix(cli): try bundled TUI before requiring ui-tui workspace; #56665) -
hermes_cli/main.py@@ -1766,10 +1766,14 @@ def _node_bin(bin: str) -> str: ) sys.exit(1) - if not ext_dir: - _ensure_tui_workspace(tui_dir) - # 1. Prebuilt bundle (nix / packaged release): just run it. + # + # This must run BEFORE _ensure_tui_workspace() below. A pip/pipx install + # ships hermes_cli/tui_dist/entry.js in the wheel but never ships ui-tui/ + # at all (that directory only exists in a git checkout) — so requiring + # the workspace to exist first made every pip/pipx dashboard Chat tab + # connection hard-exit before it ever got a chance to try the bundled + # entry.js it already has. See #56665. if not tui_dev: if ext_dir: p = Path(ext_dir) @@ -1783,6 +1787,11 @@ def _node_bin(bin: str) -> str: node = _node_bin("node") return [node, "--expose-gc", str(bundled)], bundled.parent + # No prebuilt bundle available (or --dev, which never uses one) — we're + # about to npm install/build from source, so the workspace must exist. + if not ext_dir: + _ensure_tui_workspace(tui_dir) + # 2. Normal flow: npm install if needed, always esbuild, then node dist/entry.js. # --dev flow: npm install if needed, then tsx src/entry.tsx. # Existing desktop behaviour runs npm from the workspace root. Termux -
tests/hermes_cli/test_tui_npm_install.py@@ -361,6 +361,79 @@ def fake_run(*args, **kwargs): _assert_utf8_replace_capture(calls[0][1]) +def test_make_tui_argv_uses_bundled_tui_when_workspace_missing( + tmp_path: Path, main_mod, monkeypatch +) -> None: + """pip/pipx install regression (#56665): the wheel ships + hermes_cli/tui_dist/entry.js but never ships ui-tui/ (that directory only + exists in a git checkout). Before this fix, _make_tui_argv called + _ensure_tui_workspace() unconditionally before checking for the bundled + entry.js, so every pip/pipx dashboard Chat tab connection hard-exited + with `sys.exit(1)` — surfaced to the user as the unhelpful "Chat + unavailable: 1" — despite having a perfectly runnable bundled TUI on + disk. The bundled-wheel shortcut must be tried first and succeed without + ever touching the (missing) ui-tui workspace or git. + """ + monkeypatch.delenv("HERMES_TUI_DIR", raising=False) + monkeypatch.setattr(main_mod, "_ensure_tui_node", lambda: None) + + bundled_entry = tmp_path / "bundled" / "entry.js" + bundled_entry.parent.mkdir(parents=True) + bundled_entry.write_text("// bundled TUI") + monkeypatch.setattr(main_mod, "_find_bundled_tui", lambda: bundled_entry) + + def which(name: str) -> str | None: + if name == "node": + return "/usr/bin/node" + raise AssertionError(f"unexpected shutil.which({name!r}) call — bundled path must not need npm/git") + + monkeypatch.setattr(main_mod.shutil, "which", which) + + def fail_run(*_args, **_kwargs): + raise AssertionError("bundled TUI path must not spawn any subprocess (no npm install/build, no git restore)") + + monkeypatch.setattr(main_mod.subprocess, "run", fail_run) + + # ui-tui/ deliberately does not exist under tmp_path, and there is no + # .git either — this mirrors a pip/pipx install exactly. + tui_dir = tmp_path / "ui-tui" + assert not tui_dir.exists() + + argv, cwd = main_mod._make_tui_argv(tui_dir, tui_dev=False) + + assert argv == ["/usr/bin/node", "--expose-gc", str(bundled_entry)] + assert cwd == bundled_entry.parent + + +def test_make_tui_argv_dev_mode_still_requires_workspace_even_with_bundle( + tmp_path: Path, main_mod, monkeypatch, capsys +) -> None: + """--dev never uses the prebuilt bundle (there's no source to hot-reload + from a bundled entry.js), so it must still hit the workspace guard when + ui-tui/ is missing — the bundled-first reordering must not weaken --dev. + """ + monkeypatch.delenv("HERMES_TUI_DIR", raising=False) + monkeypatch.setattr(main_mod, "_ensure_tui_node", lambda: None) + + bundled_entry = tmp_path / "bundled" / "entry.js" + bundled_entry.parent.mkdir(parents=True) + bundled_entry.write_text("// bundled TUI") + monkeypatch.setattr(main_mod, "_find_bundled_tui", lambda: bundled_entry) + + def which(name: str) -> str | None: + if name == "git": + return "/usr/bin/git" + raise AssertionError("node/npm lookup must not run when ui-tui is missing") + + monkeypatch.setattr(main_mod.shutil, "which", which) + + with pytest.raises(SystemExit) as exc: + main_mod._make_tui_argv(tmp_path / "ui-tui", tui_dev=True) + + assert exc.value.code == 1 + assert "TUI workspace is missing" in capsys.readouterr().err + + def test_make_tui_argv_exits_with_recovery_hint_when_workspace_unrecoverable( tmp_path: Path, main_mod, monkeypatch, capsys ) -> None:
-
9 PRs closed without merging
From the close comments: won't fix / by design 4 · superseded by another PR 3 · done elsewhere 1 · other 1
-
#19995 fix(packaging): include TUI runtime assets · done elsewhere →
3215ef1,b2bf658,#19514,#19525 - #24646 fix(cli): exit with clear message when ui-tui/ is missing in packaged installs · other
-
#56669 fix(cli): check bundled TUI before workspace validation for pip/pipx installs · superseded by another PR →
#56672 -
#56672 fix(cli): try bundled TUI before requiring ui-tui workspace · superseded by another PR →
#67116,#56665 -
#56855 fix(dashboard): prefer bundled TUI for wheel chat · superseded by another PR →
#56672
Show 4 more
-
#57047 fix(cli): skip TUI workspace check for managed installs (Homebrew/NixOS) · won't fix / by design →
#57031 -
#57064 fix(tui): prefer bundled TUI on packaged installs; give install-method-specific recovery (#57031) · won't fix / by design →
#57031 -
#57087 fix(tui): prefer bundled dist before workspace check · won't fix / by design →
#57031 -
#57136 fix(cli): skip TUI workspace check when bundled TUI exists (#57031) · won't fix / by design →
#57031
Closed issues · 5
- Closed#19514[Bug]: MANIFEST.in missing ui-tui/ and scripts/ — hermes --tui crashes after pip install
- Closed#24544[Bug]: Homebrew / packaged installs advertise --tui but crash because ui-tui is not included in the installed package
- Closed#30957[Bug]: FileNotFoundError: No such file or directory:
- Closed#56665Chat tab fails with "Chat unavailable: 1" on pip/pipx install — ui-tui workspace check runs before bundled-wheel fallback
- Closed#57031[Bug]: Installs from homebrew / linuxbrew cannot run TUI
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.11: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- dashboard
- Merged PRs
- #67116
- Closed issues
- 5
- Attempts
- 9 PRs closed without merging
- Fix link checked
- 18 Jul 2026