Interactive Terminal UI (TUI)
RelayCore ships a full-featured terminal UI for inspecting traffic in real time. It is built on ratatui and behaves like a lightweight Charles/Proxyman for your shell.
Launching
relay-core-cli run --ui
# optionally pair with the REST/SSE API for the four-panel layout
relay-core-cli run --ui --api-port 8082 When --ui is enabled the TUI takes over the terminal. The proxy itself continues to run in the same process — there is no extra service to start.
Layouts
The TUI adapts to your terminal width:
| Width | Layout | Panels |
|---|---|---|
| ≥ 120 columns | Four-panel (when --api-port is enabled) | Flow list · Flow detail · Active rules · Pending intercepts |
| 80–119 columns | Two-panel | Flow list · Flow detail (split horizontally, ratio adapts to width) |
| < 80 columns | Single-pane (toggle with Tab) | Full-screen flow list or flow detail |
The four-panel layout is only available when the TUI is connected to the REST/SSE API (i.e. --api-port is set and reachable). Without the API, the rules and intercepts panels fall back to a local 2-panel view.
Keybindings
Global
| Key | Action |
|---|---|
q | Quit the TUI (proxy continues in background until SIGINT) |
? | Toggle the in-app help overlay |
Esc | Return to the flow list / dismiss overlay |
Tab | Cycle active area (list → detail → rules → list) |
1 / 2 / 3 / 4 | Jump to detail tab: Overview · Request · Response · Messages |
y | Copy the selected HTTP flow as a cURL command |
Ctrl+C | Hard-exit the process |
Flow list (default focus)
| Key | Action |
|---|---|
j / ↓ | Next flow |
k / ↑ | Previous flow |
g | Jump to newest (top) and re-enable auto-scroll |
G / End | Jump to oldest (bottom) |
Enter / l / → | Focus the detail panel |
d | Delete the selected flow from the local list |
c | Clear the entire flow list (proxy is unaffected) |
p | Pause/resume capture. While paused, new flows are counted as pending instead of being added to the list. |
r | Focus the rules panel (API mode only) |
/ | Open the filter bar |
Flow detail
| Key | Action |
|---|---|
j / k or ↓ / ↑ | Scroll by one line |
Ctrl+d / PageDown | Scroll by 10 lines |
Ctrl+u / PageUp | Scroll up 10 lines |
g / Home | Scroll to top |
G / End | Scroll to bottom |
Tab | Cycle detail tabs (Overview → Request → Response → Messages → Overview) |
h / ← / Esc | Return to the flow list |
Filter bar
Press / in the flow list to start a filter, Enter or Esc to commit/close. See Filter expression syntax below.
Status bar
The bottom row always shows the live operating picture:
- Live request rate (5-second sliding window, in req/s)
- Total flows captured since startup
- Active area indicator (LIST / DETAIL / RULES)
- Uptime in
hh:mm:ss - Pending counter when capture is paused or auto-scroll is off
Mouse support
Mouse capture is enabled. You can scroll the list with the wheel and click to focus rows or panels.
Filter expression syntax
The TUI filter bar shares its parser with relay-core-cli flows --filter and the HTTP API's search_flows tool. Press / to open the bar, then enter a filter expression. See Filter Expressions for the full syntax.
Quick examples:
host:api method:POST status:>=400 # failing POSTs to api
ws status:500-599 # 5xx WebSocket
health # any flow whose URL contains "health" Detail tabs
- Overview — method, URL, status, duration, size, host, remote address, list of matched rules, and any error message
- Request — start line, headers, and body (subject to
max_body_sizein the policy) - Response — status line, headers, and body
- Messages — WebSocket message log (opcode, direction, size, base64 content). Empty for plain HTTP.
Copy as cURL
Press y on any HTTP/WebSocket flow to copy a portable POSIX-shell cURL command to the clipboard. Header values are escaped with single quotes; bodies are written with --data-binary. Requires pbcopy on macOS or wl-copy / xclip on Linux; if none is found the TUI still builds the command and shows a toast indicating the clipboard is unavailable.
Themes
Three color presets ship with the TUI. The current default relay matches the relaycore.dev brand palette (cyan accent on near-black).
| Theme ID | Aliases | Description |
|---|---|---|
relay | brand, default | relaycore.dev brand — cyan accent on near-black (default) |
slate | legacy | Tokyo Night-style slate background with amber focus |
high-contrast | hc, high_contrast, highcontrast | Brighter accents and borders for low-contrast terminals |
Resolution order
Theme is selected using the following precedence (highest first):
--theme <name>CLI flagRELAY_CORE_TUI_THEMEenvironment variable (also wired to the--themeflag via clap)[tui].themein~/.relay-core/config.toml- Default (
relay)
# One-off override
relay-core-cli run --ui --theme slate
# Persistent per-host preference
cat >> ~/.relay-core/config.toml <<'EOF'
[tui]
theme = "high-contrast"
EOF
# Environment override (e.g. in CI)
RELAY_CORE_TUI_THEME=slate relay-core-cli run --ui Color semantics
- HTTP method: GET = green, POST = orange, PUT = cyan, DELETE = red, PATCH = teal, HEAD = purple, OPTIONS = grey, WS = cyan
- Status code: 2xx = green, 3xx = orange, 4xx/5xx = red, in-flight = dim italic
- Duration: < 100 ms = green, < 500 ms = dim, ≥ 500 ms = red
- Hosts: deterministic 8-color palette hashed from the hostname
Names are parsed case-insensitively. An unknown name produces a clear error listing the available choices.
Capture pause & pending counter
Pressing p toggles "paused" mode. The proxy keeps running and the TUI still tracks incoming flow updates, but the list is frozen and the pending counter increments with each new event. Resume with p to drop the pending counter and refollow live traffic.
Tips
- Use
gfrequently to re-engage auto-scroll — manually scrolling withj/kdisables it so you can read a specific row while traffic continues. - The TUI only holds the last 1,000 flows in memory. Use
--save-stream <PATH>to capture every flow as JSONL to disk for offline analysis. - Combine with
--api-portto feed downstream tools (e.g.relay-core-cli flows) over the same proxy instance.