How baloise/catcast works
1. Overall shape
CatCast is a three-part Rust workspace for remote digital signage:
- catstage runs on the display machine and shows content full-screen.
- catc is the operator CLI used from a laptop to configure and control stages.
- catsocks is the relay broker, deployed as a Cloudflare Worker/WebSocket endpoint.
2. Primary trust boundary
The system is designed so the broker is not trusted with content or control data. catc and catstage communicate through catsocks using end-to-end encrypted messages, so the relay only sees opaque ciphertext and forwards it between peers.
3. Control plane flow
The operator uses catc to initialize a room, register stages, import config, and issue navigation/control commands. Those commands travel over the broker to the target stage. The stage applies them locally and persists enough state to survive restarts and broker outages.
4. Display/runtime boundary
catstage is the device-side runtime. It is a Tauri / WebView2 app, intended to be dropped onto a Windows machine and run without admin rights. Its role is to receive remote state, manage the local viewer, and keep the display running in fullscreen.
5. Stage internals
catstage is split into focused modules:
- socks: network connectivity to the broker
- scheduler: timing and rotation of display items
- logic: execution of display behavior/policy
- persist: local durable state
- autostart: install/start-at-login behavior
- about: local status/about-page data
6. Operator-side internals
catc is a command-line client with separate config and networking layers:
- cfg: command/config parsing and local configuration
- net: broker/stage communication
- cli: the user-facing commands
- main: wiring and process startup
This makes catc the orchestration tool, not the display runtime.
7. Shared domain and protocol
The workspace includes two shared crates:
- catcast-proto: wire-level message/types for stage control and sync
- catcast-core: shared configuration and state primitives
These crates define the common language between catc and catstage and keep protocol/state logic out of the app binaries.
8. Broker implementation
catsocks is intentionally minimal: a dumb WebSocket relay, with no account system and no application-level business logic. It is deployed separately via Wrangler to Cloudflare Workers, which matches the repository’s “free-tier broker” design.
9. Local persistence and recovery
Stage-side persistence is a first-class concern. catstage stores state locally so that a reboot or temporary broker outage does not erase the current signage state. That makes the display machine the source of truth for “what is currently shown,” while the broker is only a transport.
10. Policy / content logic
The repo includes default-logic/default.rhai and example YAML configs, which suggests content behavior is scriptable or policy-driven rather than hard-coded. The stage likely executes this logic to decide what to show and for how long, while catc supplies configuration and overrides.
11. Packaging and deployment
The workspace is set up for multi-binary build/release:
- GitHub Actions for CI/release/deploy
- a Tauri app package for catstage
- a Worker deployment target for catsocks
- examples for config and aliases
This indicates a split deployment model: desktop app on endpoints, serverless relay in the cloud, CLI on the operator machine.
12. Architecture diagram summary
A useful diagram should show three nodes:
- Operator laptop: catc
- Cloud relay: catsocks on Cloudflare Workers
- Stage machine: catstage
Connect catc and catstage through catsocks with encrypted WebSocket traffic, and show shared protocol/state crates feeding both clients. Add local persistence on catstage and the script/config inputs that shape display behavior.
Main entry points: src/main.rs catstage main · lib.rs Relay core · src/main.rs catc main · cfg.rs Config
Components 20
Operator
Laptop-side control plane and CLI
- catc main · Wires command parsing, config, and networking
crates/catc/src/main.rs - Commands · User-facing commands for room and stage control
crates/catc/src/cli.rs - Config · Parses local configuration and settings
crates/catc/src/cfg.rs - Networking · Connects to broker and stages
crates/catc/src/net.rs
Stage
Display-machine runtime and local state
- catstage main · Tauri runtime wiring for the display machine
crates/catstage/src/main.rs - Socks · Connectivity to the relay broker
crates/catstage/src/socks.rs - Scheduler · Times and rotates display items
crates/catstage/src/scheduler.rs - Logic · Executes display behavior and policy
crates/catstage/src/logic.rs - Persist · Durable local state for recovery
crates/catstage/src/persist.rs - Autostart · Install and start-at-login behavior
crates/catstage/src/autostart.rs - About · Local status and about-page data
crates/catstage/src/about.rs
Shared
Protocol and domain crates reused by clients
- Protocol · Wire-level messages for sync and control
crates/catcast-proto/src/lib.rs - Core config · Shared configuration primitives
crates/catcast-core/src/config.rs - Core state · Shared state model and persistence primitives
crates/catcast-core/src/state.rs
Relay
Minimal WebSocket broker
- catsocks · Cloudflare Worker relay entrypoint
crates/catsocks/src/bin/catsocks.rs - Relay core · Minimal WebSocket forwarding logic
crates/catsocks/src/lib.rs
Deploy
Release and deployment glue
- Deploy workflow · Worker deployment automation
.github/workflows/socks-deploy.yml
Other components
- Default logic · Scriptable default display policy
default-logic/default.rhai - Example config · Sample runtime configuration
examples/config.yaml - Aliases · Sample command aliases
examples/aliases.yaml
Connections 22
- catc main → Commands: uses · Command entry dispatches user operations
- catc main → Config: loads · Startup reads local configuration
- catc main → Networking: drives · CLI actions are executed through networking
- Networking → Protocol: encodes · Uses shared wire messages
- Config → Core config: maps to · Operator config aligns with shared config primitives
- catsocks → Relay core: runs · Worker entrypoint delegates to relay logic
- Relay core → Protocol: forwards · Relays opaque protocol frames without business logic
- Networking → Relay core: connects · Operator client reaches the broker over WebSocket
- catstage main → Socks: uses · Runtime wires broker connectivity
- catstage main → Scheduler: uses · Runtime schedules what is shown
- catstage main → Logic: uses · Runtime executes display policy
- catstage main → Persist: uses · Runtime persists recovery state
- catstage main → Autostart: uses · Runtime supports login startup
- catstage main → About: uses · Runtime exposes local status
- Socks → Protocol: decodes · Stage speaks the shared protocol through the broker
- Logic → Core state: reads · Display behavior depends on shared state model
- Persist → Core state: stores · Durable state is based on shared state primitives
- Logic → Default logic: scripts · Default policy is script-driven
- Config → Example config: example · Sample config informs operator setup
- Commands → Aliases: example · Sample aliases shape CLI usage
- Deploy workflow → catsocks: deploys · Workflow publishes the relay
- Deploy workflow → Relay core: packages · Deployment builds the worker runtime