Client / TUI
Overview
Section titled “Overview”flowlayer-client-tui is the official terminal client for FlowLayer runtime sessions.
It attaches to a running flowlayer-server over WebSocket, then provides one keyboard-first workspace for:
- service state observation
- log inspection
- control actions (
start,stop,restart) - connection diagnostics and reconnect behavior
Typical quickstart:
flowlayer-server -s 127.0.0.1:6999 -c flowlayer.jsoncflowlayer-client-tui -addr 127.0.0.1:6999 -token <token>What the Client Is
Section titled “What the Client Is”The client is an operator UI process, not part of server orchestration.
| Capability | What it does |
|---|---|
| Session attachment | Connects to ws://<addr>/ws with bearer auth |
| State rendering | Displays snapshot baseline and live updates |
| Log workspace | Merges replay + live events in one stream |
| Control surface | Sends protocol commands for service/session actions |
| Recovery loop | Reconnects with bounded exponential backoff |
What it is not covered in detail in Known Limits.
Thin Client Model
Section titled “Thin Client Model”The thin-client model separates authority and presentation.
| Concern | Client role | Server role |
|---|---|---|
| Dependency graph | Observe only | Own and enforce |
| Lifecycle transitions | Request actions | Validate and execute |
| Runtime state | Render current truth | Publish canonical state |
| Log retention semantics | Keep working buffer | Decide replay/retention behavior |
Consequences:
- command results are feedback, not an independent state engine
- UI never invents hidden transitions
- multiple clients can coexist without state divergence
Connection Modes
Section titled “Connection Modes”The client supports two connection modes.
direct
Section titled “direct”Direct mode passes connection values explicitly.
flowlayer-client-tui -addr 127.0.0.1:6999 -token <token>Use when you read token and bind from fresh server boot output.
config-based
Section titled “config-based”Config-based mode loads connection values from JSONC.
flowlayer-client-tui -config flowlayer.jsoncExpected config values:
{ "session": { "addr": "127.0.0.1:6999", "token": "change-me" }}The client reads only session connection values from config.
Start the server
Run flowlayer-server first. The TUI only connects after the Session API is already up.
Copy the token
Read the session token from the server startup log line. Format: fl_<uuid>.
Connect the TUI
Pass -addr / -token directly, or use -config to read connection values from the server config file.
Authentication Flow
Section titled “Authentication Flow”Authentication is bearer-token based and enforced by server endpoints.
Flow:
- Start server and capture token from server boot logs.
- Pass token via
-tokenor viasession.tokenin-configmode. - Client sends WebSocket upgrade request with bearer header.
- Server accepts or rejects based on token validity.
Authorization: Bearer <token>Token mismatch or missing header prevents session establishment.
Session Handshake
Section titled “Session Handshake”After successful connection to /ws, session initialization is ordered.
helloarrives first (protocol metadata, capabilities)snapshotarrives second (full runtime baseline)- client starts consuming incremental events and sending commands
ws://<addr>/ws with bearer tokenhello — protocol version and capabilitiessnapshot — full service state baselineservice_status, logSnapshot + Event Stream
Section titled “Snapshot + Event Stream”The client model combines baseline + increments.
| Message type | Purpose |
|---|---|
snapshot | Full baseline for services and session data |
| service status events | Incremental lifecycle/state transitions |
log events | Live log stream entries |
command ack / result | Acceptance and completion feedback |
This is the core rule: baseline from snapshot, then converge with server events.
What the UI Reads
Section titled “What the UI Reads”The UI consumes specific protocol outputs.
| Source | Why the UI needs it |
|---|---|
hello | confirm protocol/session metadata |
snapshot | initialize service table and statuses |
| status events | keep service list in sync |
live log events | update logs view in real time |
get_logs responses | fill history and replay missing ranges |
ack / result | display action acceptance and outcome |
The UI also tracks local-only state: selected service, filters, focus panel, modal visibility, footer messages.
What the UI Controls
Section titled “What the UI Controls”Control is protocol-driven, not process-driven.
| UI intent | Command |
|---|---|
| Start selected service | start_service |
| Stop selected service | stop_service |
| Restart selected service | restart_service |
| Start whole session set | start_all |
| Stop whole session set | stop_all |
| Reload log window or replay | get_logs |
Advanced clients may also use additional protocol calls; see Reference and Protocol.
Keybindings Full Table
Section titled “Keybindings Full Table”| Key | Scope | Behavior |
|---|---|---|
Up / Down | Focused panel | Navigate services list or scroll logs |
Tab | Global | Switch focus between services and logs panels |
PageUp / PageDown | Logs panel | Scroll logs by page |
/ | Focused panel | Start filter input for active panel |
Esc | Global | Close filter editor or modal |
i | Global | Open connection info (address, token, connection status) |
s | Services panel | Start selected service when applicable |
S | Services panel | Start all when selection context is global (all logs) |
x | Services panel | Stop selected service |
X | Services panel | Stop all when selection context is global (all logs) |
q | Global | Quit client |
Ctrl+C | Global | Quit client |
Key intent depends on focus and current selection context.
Navigation Model
Section titled “Navigation Model”Two primary panels:
- services panel
- logs panel
Navigation pattern:
- select panel with
Tab - move within panel (
Up/Down, paging in logs) - filter focused panel with
/ - close filter/modal with
Esc - inspect connection metadata with
i
This model keeps service selection and log confirmation in one loop.
Logs View Behaviour
Section titled “Logs View Behaviour”The logs view is stream-oriented.
- It displays replayed and live entries in one ordered timeline.
- It deduplicates entries when replay overlaps live delivery.
- It keeps a bounded working window for operator usability.
The client treats logs as operational context for decisions, not as durable archival storage.
Global vs Selected Service Actions
Section titled “Global vs Selected Service Actions”Action semantics depend on selection scope.
| Context | Key | Command |
|---|---|---|
| Specific service selected | s | start_service (or restart when state allows) |
| Specific service selected | x | stop_service |
Global context (all logs) | S | start_all |
Global context (all logs) | X | stop_all |
This split avoids accidental session-wide actions from per-service context.
Restart / Stop / Start semantics
Section titled “Restart / Stop / Start semantics”Action semantics are request/response based.
| Action | Requested by client | Decided by server |
|---|---|---|
| Start | Ask to transition service/session into running state | Validate dependencies and current state |
| Stop | Ask for controlled termination path | Apply stop policy (stopCmd or signal path) |
| Restart | Ask for stop/start lifecycle transition | Enforce runtime constraints and command ordering |
The client must treat ack and result as authoritative feedback channels.
Reconnect Behaviour
Section titled “Reconnect Behaviour”Reconnect creates a new WebSocket session, not a resumed transport.
Backoff schedule:
500ms -> 1s -> 2s -> 5s (max)
Reconnect sequence:
- wait backoff interval
- reconnect with auth
- wait for
hello - wait for
snapshot - replay logs using
after_seqwhen available - continue live event processing
All pending commands from previous disconnected socket are invalidated and not auto-replayed.
after_seq replay model
Section titled “after_seq replay model”Log continuity uses a high-water sequence strategy.
| Concept | Meaning |
|---|---|
seq | Monotonically increasing log sequence identifier |
lastSeq | Highest sequence observed by client |
after_seq | Replay request cursor used after reconnect |
effective_limit | Server-provided working-window bound |
Replay pattern:
- track
lastSeqacross both replay and live events - on reconnect, request
get_logswithafter_seq=lastSeq - merge replay with new live events
- deduplicate by
seq - trim local window using
effective_limit
This is how the client recovers missed logs without duplicating rows.
Selection-change behavior for log views:
- On service change, the visible log pane is cleared immediately.
- Late historical/replay responses that no longer match the active selection are ignored.
- This prevents stale or mixed service logs; responses are filtered client-side, not network-cancelled.
Error Handling
Section titled “Error Handling”Representative failure handling:
| Scenario | Client behavior |
|---|---|
| Invalid flags or positional args | Print error + help, exit 2 |
| Auth failure | Connection fails until token/bind are corrected |
| Disconnect during pending command | Mark pending command as invalidated |
| Replay overlap | Deduplicate by seq |
| Unknown or unsupported protocol behavior | Surface error context and keep UI stable |
Color behavior note: NO_COLOR disables red error coloring in terminal output.
Operational Workflow
Section titled “Operational Workflow”Recommended operator loop:
- start server and capture session token
- connect client (direct or config-based)
- wait for
hello+snapshot - inspect blocked/failed services first
- inspect related logs before action
- send targeted start/stop/restart request
- verify server result and resulting state/log output
- repeat for next dependency edge
Useful command snippets:
# Server firstflowlayer-server -s 127.0.0.1:6999 -c flowlayer.jsonc
# Direct client attachflowlayer-client-tui -addr 127.0.0.1:6999 -token <token>
# Config-based attachflowlayer-client-tui -config flowlayer.jsoncInstallation Paths
Section titled “Installation Paths”Two supported operation paths from the source client documentation:
Prebuilt binary
Section titled “Prebuilt binary”- Download the binary artifact for your platform.
- Make it executable.
- Run with direct or config-based connection mode.
./flowlayer-client-tui -addr 127.0.0.1:6999 -token <token>Run from source
Section titled “Run from source”Requires Go toolchain and repository checkout.
go run . -addr 127.0.0.1:6999 -token <token>In both paths, the server must already be running and reachable.
Contribution and Extension Paths
Section titled “Contribution and Extension Paths”Migration of the original client page contribution guidance:
- The terminal client implementation is open source and inspectable.
- UI improvements (layout, keybindings, display behavior) are contribution candidates.
- The protocol is public, so custom clients (web, IDE plugin, specialized operator UI) can be built without changing server runtime policy.
Useful external references:
- Client repository: https://github.com/FlowLayer/tui
- Client issues: https://github.com/FlowLayer/tui/issues
- Server/protocol docs for client implementers: Protocol, Reference
Known Limits
Section titled “Known Limits”An orchestrator
The TUI does not start or manage services itself. All orchestration logic stays in the FlowLayer server.
A log archive
Maintains an in-memory working window bounded by effective_limit. Scrolling past the top of the buffer transparently loads older history via get_logs with before_seq; for durable retention beyond the server’s ring buffer, use logs.dir.
A source of truth
Service state is server-owned. The TUI never invents state from command results — it only renders what the server reports.
A config authority
Only reads session.addr and session.token from config. Does not interpret service definitions or server settings.
Also out of scope:
- Not a multi-runtime coordinator in one client instance.
- No automatic replay of orphaned pending commands after disconnect.
Related Pages
Section titled “Related Pages”- Server
- Protocol
- Configuration
- Reference
- Troubleshooting
- Marketing overview: /tui/