Skip to content

TUI hangs silently at startup — esbuild __esm helper deadlocks on @hermes/ink async init #31227

@phoenix-aetherview

Description

@phoenix-aetherview
The dashboard TUI (ui-tui/dist/entry.js) produces only 141 bytes of ANSI terminal reset sequences and then hangs forever with a blank screen. No errors, no crash, no stderr output — the Node process and the spawned python -m tui_gateway.entry child both stay alive but never render.

Environment
- Hermes Agent v0.14.0 (commit 7a4dc8e8d), fully updated from main
- Ubuntu 26.04 LTS, Linux 7.0.0-15-generic
- Node v22.22.1, npm 9.2.0, esbuild 0.28.0
- Tested with profiles default and aetherview, both via dashboard /chat PTY and hermes --tui in tmux

Steps to Reproduce
1. Build the TUI: cd ui-tui && npm run build
2. Run in tmux (or any real PTY):
   
   HERMES_PYTHON=/path/to/venv/bin/python TERM=xterm-256color \
     node --expose-gc ui-tui/dist/entry.js
   
3. Observe: terminal clears, then nothing — permanently blank

What's Happening

The esbuild bundle's __esm wrapper at line 14:
js
var __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};


This helper does NOT await nested async init, so init_entry_exports() never resolves. The Promise.all at bundled line 73713 hangs:
js
var [ink2, { App: App4 }, ...] = await Promise.all([
  init_entry_exports().then(() => entry_exports_exports),
  init_app().then(() => app_exports),
  init_perfPane().then(() => perfPane_exports),
  Promise.resolve().then(() => (init_fpsStore(), fpsStore_exports))
]);


The build script itself acknowledges this on lines 38-41 of scripts/build.mjs:
js
// Skip the prebuilt @hermes/ink bundle — esbuild's __esm helper doesn't
// await nested async init, which breaks lazy-initialized exports like
// render. Bundling from source sidesteps that.
alias: { '@hermes/ink': resolve(root, 'packages/hermes-ink/src/entry-exports.ts') },


But bundling from source doesn't solve the problem — the __esm wrapper still breaks the async init chain.

Confirmed the @hermes/ink npm package is also broken independently: npx tsx src/entry.tsx fails with ERR_MODULE_NOT_FOUND: Cannot find module '@hermes/ink/dist/entry-exports.js' because the dist directory is never built.

Additional Details
- Bundle: 73,713 lines, 3.0MB, 348 __esm wrappers, 99 await init_ calls
- Running npm run build on packages/hermes-ink would produce dist/entry-exports.js but the main TUI build doesn't trigger it
- All other dependencies are fine — react, @nanostores/react, app modules are inlined correctly
- Clean rebuild (wipe node_modules, reinstall, rebuild) produces identical broken behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/tuiTerminal UI (ui-tui/ + tui_gateway/)javascriptPull requests that update javascript codetype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions