hermes-agent/tests/docker
Ben Barclay 9272e4019a
fix(docker): point TUI launcher at prebuilt bundle via HERMES_TUI_DIR (#37923)
The embedded dashboard Chat tab dies on hosted images with a 502 /
"[session ended]": the PTY child's `hermes --tui` spawn runs a runtime
`npm install` that fails.

Root cause: the root package-lock.json describes the WHOLE npm monorepo
workspace set (root + web + ui-tui + apps/*), but the image only installs
root/web/ui-tui — apps/* (the desktop app) is never `npm install`ed here, and
its deps hoist into the shared root node_modules. So the actualized
node_modules permanently disagrees with the canonical lock,
`_tui_need_npm_install()` returns True on every launch, and the runtime
`npm install` it triggers (a) can never converge against the partial monorepo
and (b) races itself across concurrent /api/pty connections -> ENOTEMPTY ->
the launcher `sys.exit(1)`s, the slow install blows past Fly's WS-upgrade
window -> 502 -> the browser shows "[session ended]".

Fix: set `ENV HERMES_TUI_DIR=/opt/hermes/ui-tui` so `_make_tui_argv` takes the
prebuilt-bundle fast path (`node --expose-gc /opt/hermes/ui-tui/dist/entry.js`)
and never reaches the install check — exactly the nix/packaged-release path
the launcher was designed for. The bundle is already built at Layer 8
(`ui-tui && npm run build`); this just tells the launcher to use it.

Verified on a freshly-built image: HERMES_TUI_DIR is set, the prebuilt
dist/entry.js is present, `_make_tui_argv` resolves to the prebuilt node
invocation (no npm), and `docker run ... --tui` no longer prints
"npm install failed". New regression guard: tests/docker/test_tui_prebuilt_bundle.py.

A separate launcher hardening (make _tui_need_npm_install tolerant of
partial-monorepo installs) is tracked independently; this Docker-side fix
resolves the hosted-chat symptom on its own.

Area: docker (Dockerfile + tests/docker).
2026-06-03 15:30:45 +10:00
..
__init__.py test(docker): add conftest fixtures for docker harness 2026-05-24 18:05:14 -07:00
conftest.py fix(service_manager): s6 detection works for unprivileged hermes user 2026-05-24 18:05:33 -07:00
test_container_restart.py test(docker): poll for boot-log signal instead of fixed sleeps 2026-05-24 18:05:33 -07:00
test_dashboard.py fix(dashboard-auth): share /api/* public allowlist between legacy and OAuth gates 2026-05-29 12:17:12 +10:00
test_docker_exec_privilege_drop.py fix(docker): drop docker exec to hermes uid before invoking the CLI 2026-05-28 13:30:36 +10:00
test_dump_build_sha.py fix(docker): bake build-time git SHA into the image 2026-05-28 15:14:05 +10:00
test_gateway_run_supervised.py fix(docker): tee supervised gateway stdout to docker logs 2026-05-28 13:18:41 +10:00
test_main_invocation.py test(docker): lock baseline behavior for Phase 0 harness 2026-05-24 18:05:14 -07:00
test_profile_gateway.py test(docker): fix svstat 'want up' assertion in profile-gateway lifecycle test 2026-05-25 12:25:06 +10:00
test_s6_profile_gateway_integration.py fix(service_manager): rip out dead port parameter 2026-05-24 18:05:33 -07:00
test_tui_passthrough.py test(docker): lock baseline behavior for Phase 0 harness 2026-05-24 18:05:14 -07:00
test_tui_prebuilt_bundle.py fix(docker): point TUI launcher at prebuilt bundle via HERMES_TUI_DIR (#37923) 2026-06-03 15:30:45 +10:00
test_zombie_reaping.py fix(service_manager): s6 detection works for unprivileged hermes user 2026-05-24 18:05:33 -07:00