FlowLayer Server
The FlowLayer server runtime: single binary that loads your config, orchestrates services, exposes the Session API, and streams logs and state in real time.
Quickstart
flowlayer-server -c flowlayer.jsonc -s 127.0.0.1:6999
flowlayer-client-tui -addr 127.0.0.1:6999 -token <token>
flowlayer-client-tui -config flowlayer.jsonc
The Orchestration Engine
The FlowLayer server is a single binary that reads a JSONC config, builds a dependency graph, launches services in the correct order, and exposes a live Session API.
/ws, /health) for clients
Two-binary architecture
flowlayer-server Orchestration engine. Owns service state, lifecycle, logs, and Session API.
flowlayer-client-tui Official client. Connects over WebSocket. Observer and control surface. Separate binary.
Protocol: WebSocket V1 — public spec, open to custom clients
Config: JSONC — see Configuration for full reference
CLI Usage
FlowLayer is invoked as a single command. All flags are optional — the binary auto-discovers a config file in the current directory when no path is specified.
flowlayer-server [-c <path>] [--config <path>] [<path>] [-s <bind>] [-token <value>] [--no-color] [-h|--help] [--version]
router
Session API bind — -s <bind>
Enables the Session API. Accepts host:port, :port, or a bare port number. CLI overrides session.bind from config.
-s 6999→ 127.0.0.1:6999 (localhost)-s :6999→ :6999 (all interfaces)-s 192.168.1.10:6999→ specific interface vpn_key
Token — -token <value>
Bearer token override. Overrides session.token from config. When the Session API is enabled but no token is set via CLI or config, the server auto-generates one.
palette
Color output — --no-color
--no-color Disables ANSI color output. NO_COLOR Environment variable. Any non-empty value disables color. If neither is set, color is enabled only when stdout is a TTY.
info
Version — --version
--version Prints flowlayer-server 1.0.0 and exits immediately. No config file is required. help
Help — -h / --help
-h --help flowlayer-server with no arguments and flowlayer-server -h / --help print the same onboarding help and exit with code 0. error Error behavior
Error: <message> Invalid CLI/config input prints Error: <message>, then the full help, and exits with code 2. Config Path Resolution
folder_open Priority order
Resolved in descending priority. Using both -c and --config simultaneously is an error. More than one positional argument is an error.
-c <path> --config <path> search Auto-discovery order
Scans the current directory in this order when no explicit path is given:
If no config is found, FlowLayer exits with code 2.
Configuration
The Session API is configured in your JSONC file via session.bind and session.token.
{
"session": {
"bind": "127.0.0.1:6999",
"token": "change-me"
}
}
Session API
When enabled through -s or session.bind, the server exposes two authenticated endpoints. The HTTP server starts during boot, before services are launched.
favorite GET /health
Liveness endpoint. Returns {'\"ok\": true'} when the server is running.
cable GET /ws
Upgrades to a WebSocket session using the FlowLayer V1 protocol. On connection the server sends hello then snapshot.
settings Session API lifecycle
Activation
CLI -s takes precedence over session.bind. If neither is set, no Session API is started.
Startup
HTTP server starts before service wave execution. If the bind address is unavailable, FlowLayer exits immediately with an error.
Shutdown
On SIGINT/SIGTERM, the HTTP server stops first (2-second grace for in-flight requests), then services are torn down in reverse dependency order.
Bearer Token Auth
Every Session API request requires a bearer token. There are no public endpoints — authentication is enforced on all routes including /health and /ws.
Token priority
1. -token CLI flag
2. session.token config value
3. Auto-generated: fl_<uuid>
The token is ephemeral and printed in boot logs. It is a session-level gate for a development tool, not a production credential.
Request header
| Condition | HTTP Status |
|---|---|
| No Authorization header | 401 Unauthorized |
| Header present, token does not match | 403 Forbidden |
| Valid token | Request proceeds |
DAG + Wave Execution
At boot, FlowLayer validates the config, builds a dependency graph, and prints the execution plan before starting any service. Same config always produces the same order.
$ flowlayer-server -c flowlayer.jsonc
[flowlayer] boot: validating config and graph...
[flowlayer] boot: session API: 127.0.0.1:6999 (/ws, /health)
[flowlayer] boot: DAG computed — 3 nodes, 2 waves
[flowlayer] boot: wave 0 │ billing → starting
[flowlayer] boot: wave 0 │ ping → starting
[flowlayer] boot: wave 0 │ billing → ready (http :3002/healthz)
[flowlayer] boot: wave 0 │ ping → ready (tcp :8088)
[flowlayer] boot: wave 1 │ users → starting
[flowlayer] boot: wave 1 │ users → ready (http :3003/healthz)
STARTUP COMPLETE — runtime active
account_tree DAG
Built from dependsOn declarations. Cycles cause immediate failure. Validated once at boot — never recomputed at runtime.
waves Waves
Services in the same wave start concurrently. The next wave begins only after all services in the current wave reach their terminal startup state (running or ready).
bolt Runtime commands
After boot, clients can send start_service, stop_service, and restart_service via the WebSocket API. See Protocol for the full command reference.
Shutdown Behavior
Graceful shutdown sequence
Session HTTP server stops. 2-second grace period for in-flight requests.
Services torn down in reverse dependency order.
Per-service: if stopCmd is defined, it runs instead of SIGTERM.
If no stopCmd: SIGTERM sent to the process group. 8-second wait for I/O flushing.
Any remaining processes receive SIGKILL.
stop_circle stopCmd
Accepts string | string[]. When present, FlowLayer runs this command instead of sending SIGTERM to the process group. Runs with the same effective environment as cmd, including service env overrides. Useful for Docker Compose and similar runtimes that need an explicit stop command.
warning Trigger
Graceful shutdown is triggered by SIGINT or SIGTERM received by the FlowLayer process.
Track-Only Guarantee
FlowLayer maintains a registry of every process it spawns and will only ever signal processes in that registry. External processes are never touched. This guarantee prevents accidental interference with other running processes on the machine.
Signals and lifecycle management apply only to registered PIDs.
Unregistered processes remain untouched and unaware.
monitor_heart Runtime principles
- check_circle
Deterministic
Same config, same order, every time. The execution plan is computed once and printed at boot.
- check_circle
Explicit
Commands are executed directly — no shell is invoked. Shell operators (
&&,|, redirections) are not interpreted. To use shell features, invoke a shell explicitly:["sh", "-c", "..."]. See Configuration → cmd for details. - check_circle
No automatic restart
FlowLayer does not restart crashed services. An unexpected daemon exit transitions the service to
failed.
Participation
Bug reports, feature requests, and roadmap discussion happen on GitHub Issues. The engine source is not public, but the protocol and config reference are, and alternative clients are welcome.