Skip to main content
The Hoox Terminal UI (TUI) is a full-screen, keyboard-driven operations center built with OpenTUI, React 19, and Zustand. This document covers package layout, state, data flows, and crash recovery for engineers. Package: packages/tui (@jango-blockchained/hoox-tui)
Entry: src/main.tsx · Root: src/app.tsx · CLI launcher: hoox tui

🏗️ Architectural Blueprint

Directory map

Stores are not under packages/tui/src/stores for production code — they live in @jango-blockchained/hoox-shared: Session persistence: $HOME/.hoox/.tui-state/session.json via shared restoreSession / saveSession.
  • View factories, sidebar labels, keyboard shortcuts, and palette view commands are defined in packages/tui/src/view-registry.tsx.
  • Semantic status colors (ConnectionStatusColor, WorkerStatusColor, LogLevelColor, AlertSeverityColor) live in @jango-blockchained/hoox-shared (packages/shared/src/colors.ts). Do not invent local status→hex maps in views.

Test doubles (no polluting mock.module)

Installed once from packages/tui/src/test-setup.ts (preload): View tests must not call mock.module for cli-bridge, shared stores, api-client, or sse. Override methods on the doubles instead. Edge topology fixtures use HOOX_GRAPH_METADATA_PATH (temp file) rather than mocking fs.

🗺️ View registry (15)

Must stay aligned with ViewId in packages/shared/src/types.ts, sidebar items, VIEWS in app.tsx, and command palette entries:

🛜 Dual-channel + SSE

Startup sequence (AppRoot)

  1. Restore session → set view / sidebar
  2. fetchWorkers() (HTTP) → on failure, cliBridge.monitorStatus()
  3. Fire-and-forget streamTrades() + streamLogs() (SSE; silent if API down)

CLI bridge (src/services/cli-bridge)

All mutating / diagnostic operator actions go through the hoox binary with timeout, abort tags, and structured CliErrorDetails sunk to the service store for the status bar expand panel. Notable methods: deployAll, deployWorker, repairWorker, rebuild, checkHealth, checkFix, checkSetup, monitorStatus, monitorKillSwitch, monitorQueueDepth, workerLogs, configShow, configValidate, configKvList, configKvGet, configSecretsList, dbQuery, agentHealthCheck. checkHealthFix exists on the bridge but is unused by views (dashboard/settings use checkFix).

🛡️ Crash protection

Layer 1 — per-view ErrorBoundary

Every primary view is wrapped. Render failures show Retry without killing sidebar/status.

Layer 2 — CrashRecoveryApp

Process uncaughtException / unhandledRejection → CrashScreen:
  • Restart — remount AppRoot
  • Safe Mode — remount with safeMode
  • Report Bug — write $HOME/.hoox/.tui-state/crash.log

🧪 Verification

E2E smoke (test/e2e/smoke.test.ts) requires an interactive TTY; otherwise it skips with a clear reason.

📊 Graph integration

  • Runtime topology view reads graph-metadata.json (repo root), resolved from CWD walk-up or package-relative path.
  • Code graph (graph.json / graph.dot) is produced by bun run graph (scripts/extract-graph.ts).
  • All 15 view exports are present as function nodes under packages/tui:…/views/….
  • Regenerate after large refactors: bun run graph (~25s). Metadata should include every worker under workers/*.

Known limitations (honest)

OpenTUI <text> children must be strings (or text nodes) — never nest <text> inside <text>. Prefer sibling <text> inside a row <box>.

Next steps

Last modified on July 21, 2026