Skip to main content

Module statusbar

Module statusbar 

Source
Expand description

Status bar widget — always visible, single row at the bottom of the screen (above the prompt).

Layout, left-to-right (full tier, ≥ 80 cols):

[MODE] engine:<health> feed:<age> dd:<pct> ops:<LABEL>

Plus a retry:N addendum when the WS is disconnected and has already attempted a reconnect.

Design rules:

  • Mode label left-aligned and colored; never truncated.
  • Engine health is one word: OK / RECONNECTING / DOWN.
  • Feed age renders as seconds; caution > 3 s, alert > 10 s.
  • Drawdown reads risk.drawdown_pct. Thresholds:
    • missing → dd:-- (muted).
    • halted → dd:HALT in alert+bold (kill_all or circuit-breaker tripped). Hides the number on purpose — “the engine is refusing new risk” is the headline; the exact dd figure is a detail the /state overlay has more room for.
    • 0 .. 2% → primary.
    • 2 .. 5% → caution.
    • 5% → alert.

  • Operator-state segment is always visible, never hidden (Addendum A §2.3 — the indicator is present even at STEADY so the operator never has to guess whether the system is watching). Appearance:
    • ops:? — classifier has not reported yet (muted).
    • ops:<LABEL> — label colored by ColorHint.
    • ops:<LABEL>* — label is stale (muted asterisk).

The label is sourced from the engine’s GET /operator/state endpoint (ADR-016); the CLI never computes it locally.

§Width-responsive tiers

The status bar picks the widest tier that fits in area.width. Tiers are defined so that each narrower tier is a strict subset of the tier above, and the ordering is driven by operator-safety priority — we drop diagnostic segments (retry count, feed age) before we drop risk segments (drawdown, halt), and we never drop ops: at any width.

  • Tier::Full — all segments, double-space separators.
  • Tier::Compact — drops the retry:N addendum and uses single-space separators between segments.
  • Tier::Minimal — renders [MODE] ops:<LABEL> dd:<pct> only. The operator’s minimum useful floor: which mode you are in, what state the engine thinks you are in, and whether capital is bleeding.

§rate: (CLI-side) and hl: (Hyperliquid-side)

The two are parallel by design so an operator reads both with the same eye movement. Both use a shared “tri-color” policy:

  • headroom ≥ 25 % → primary
  • 10 % ≤ headroom < 25 % → caution
  • headroom < 10 %, tokens > 0 → alert
  • tokens == 0 → <name>:EXH in alert+bold

rate:N/M reads from the CLI-side token bucket (zero_engine_client::RateBudget) that the caller hands in each render. Nonerate:? in metadata color (the same honest-rendering rule ops:? uses before the classifier reports).

hl:N/M reads from /v2/status.hl_rate which the engine optionally reports. Unset → hl:?. Once the engine-side cut surfaces the field (tracked separately from the M2_PLAN row), this segment starts showing live Hyperliquid pressure without any CLI code change.

§Rendering

The widget is pure: given a Mode, an EngineState snapshot, a Theme, and a now: DateTime<Utc>, it builds a Line and paints it into the buffer. All freshness math flows through the caller-supplied now so snapshot tests can freeze time.

Structs§

StatusBar

Enums§

Tier
Width-responsive tier picked by StatusBar::render.