rlgl

command module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2025 License: MIT Imports: 1 Imported by: 0

README

Red Light/Green Light

rlgl

A lightweight status dashboard for developers to showcase their current work-in-progress. Display what you're focusing on, your task queue, and availability status in real-time. Perfect for solo developers, remote teams, or anyone who wants a simple way to broadcast "what I'm working on right now."

rlgl runs in two modes:

  • Server Mode: Hosts the dashboard web interface and receives status updates via WebSocket
  • Client Mode: Reads your local YAML config and pushes updates to the server

Go Go Report Card License Test Status Coverage

Features

  • Client/Server Architecture: Run a central server and push updates from multiple clients
  • WebSocket Authentication: Secure WebSocket connections with token-based authentication
  • WebSocket Communication: Clients push config updates to the server via WebSocket
  • Real-time Updates: Server-Sent Events (SSE) stream config changes instantly to web viewers
  • Simple Configuration: Single YAML file to manage your work status
  • Focus Indicator: Show what you're currently working on
  • Task Queue: Display your upcoming tasks
  • In-Memory Storage: Server stores client configs in memory (no database required)

Prerequisites

  • Go 1.25.1 or later
  • Docker (optional, for containerized deployment)

Configuration

Create a configuration file at config/rlgl.yaml:

name: "Ben's WIP Status"
description: "Current work and availability"
user: "bensapp"
contributor:
  active: true
  focus: "Implementing CSRF protection for rlgl"
  queue:
    - "Add Docker multi-arch support"
    - "Write comprehensive tests"
    - "Update documentation"

The config file structure:

  • name: Your status page title
  • description: Brief description of the page
  • user: Your username or identifier
  • contributor.active: Status indicator (true = green light/available, false = red light/busy)
  • contributor.focus: What you're currently working on
  • contributor.queue: Your upcoming tasks/backlog

Update the YAML file anytime to change your status - the client will push updates to the server automatically!

Building from Source

Go Build
# Clone the repository
$ git clone https://github.com/benwsapp/rlgl.git
$ cd rlgl

# Download dependencies
$ go mod download

# Build the binary
$ go build -o rlgl .
Docker Build
Single Architecture
# Build for current platform
$ docker build -t rlgl:latest .
Multi-Architecture (using buildx)
# Create a new builder (first time only)
$ docker buildx create --name multiarch --use

# Build for multiple architectures
$ docker buildx build \
    --platform linux/amd64,linux/arm64 \
    -t your-registry/rlgl:latest \
    --push .

Running

Server Mode

Run the server to host the dashboard and receive updates from clients:

# Run server with defaults (listens on :8080)
# Authentication token will be auto-generated and displayed
$ ./rlgl serve

# Specify custom address
$ ./rlgl serve --addr :3000

# With pre-configured authentication token
$ ./rlgl serve --token rlgl_your_secret_token_here

# With trusted origins for CSRF (comma-separated)
$ ./rlgl serve --trusted-origins https://example.com,https://app.example.com

# Using environment variables
$ export RLGL_SERVER_ADDR=":3000"
$ export RLGL_TOKEN="rlgl_your_secret_token_here"
$ export RLGL_TRUSTED_ORIGINS="https://example.com,https://app.example.com"
$ ./rlgl serve

Authentication: The server requires a token for WebSocket connections. If you don't provide one via --token or RLGL_TOKEN, the server will generate a secure random token and display it on startup. Save this token - you'll need it for client connections!

Client Mode

Run the client to push your local config to the server:

# Push config continuously (every 30s by default)
# Replace TOKEN with the value from server startup
$ ./rlgl client \
    --client-id my-laptop \
    --config config/rlgl.yaml \
    --server ws://localhost:8080/ws \
    --token rlgl_your_token_here

# Push config once and exit
$ ./rlgl client \
    --client-id my-laptop \
    --config config/rlgl.yaml \
    --server ws://localhost:8080/ws \
    --token rlgl_your_token_here \
    --once

# Custom push interval
$ ./rlgl client \
    --client-id my-laptop \
    --config config/rlgl.yaml \
    --server ws://localhost:8080/ws \
    --token rlgl_your_token_here \
    --interval 1m

# Using environment variables (defaults to rlgl.yaml in current directory)
$ export RLGL_REMOTE_HOST="ws://localhost:8080/ws"
$ export RLGL_CLIENT_ID="my-laptop"
$ export RLGL_TOKEN="rlgl_your_token_here"
$ export RLGL_CLIENT_INTERVAL="1m"
$ ./rlgl client
Environment Variables

Server:

  • RLGL_SERVER_ADDR - Server address (default: :8080)
  • RLGL_TOKEN - WebSocket authentication token (auto-generated if not provided)
  • RLGL_TRUSTED_ORIGINS - Comma-separated list of trusted origins for CSRF protection

Client:

  • RLGL_REMOTE_HOST - WebSocket server URL (default: ws://localhost:8080/ws)
  • RLGL_CLIENT_ID - Unique client identifier (required)
  • RLGL_TOKEN - WebSocket authentication token (required)
  • RLGL_CLIENT_INTERVAL - Interval between config pushes (default: 30s)
  • RLGL_CLIENT_ONCE - Push config once and exit (default: false)
Docker
Run Server
# Server will generate and display authentication token on startup
$ docker run -p 8080:8080 \
    rlgl:latest serve --addr :8080

# Or use pre-configured token
$ docker run -p 8080:8080 \
    -e RLGL_TOKEN="rlgl_your_token_here" \
    rlgl:latest serve --addr :8080
Run Client
$ docker run \
    -v $(pwd)/config/rlgl.yaml:/config/rlgl.yaml:ro \
    rlgl:latest client \
        --client-id docker-client \
        --config /config/rlgl.yaml \
        --server ws://host.docker.internal:8080/ws \
        --token rlgl_your_token_here
With Environment Variables
# Server
$ docker run -p 8080:8080 \
    -e RLGL_TOKEN="rlgl_your_token_here" \
    -e RLGL_TRUSTED_ORIGINS="https://example.com,https://app.example.com" \
    rlgl:latest serve

# Client
$ docker run \
    -v $(pwd)/config:/config:ro \
    -e RLGL_REMOTE_HOST="ws://host.docker.internal:8080/ws" \
    -e RLGL_CLIENT_ID="docker-client" \
    -e RLGL_TOKEN="rlgl_your_token_here" \
    rlgl:latest client --config /config/rlgl.yaml

Endpoints

Web Interface:

  • GET / - Main page (renders template with first available client config)
  • GET /config - JSON endpoint returning first available client config
  • GET /events - Server-Sent Events stream for real-time config updates

WebSocket API:

  • WS /ws - WebSocket endpoint for client connections (requires authentication via Authorization: Bearer <token> header)
    • Supports push config and ping/pong messages
    • Backward compatible: also accepts token via ?token=<token> query parameter
  • GET /status - JSON endpoint returning all client configs (keyed by client ID)

Development

Linting
# Run all linters
$ golangci-lint run

# Check cognitive complexity
$ gocognit -d -over 10 .

# Lint Dockerfile
$ hadolint Dockerfile
Testing
# Run tests
$ go test ./...

# Run tests with coverage
$ go test -cover ./...

Security

This project implements multiple layers of security:

Authentication:

  • Token-based authentication for WebSocket connections
  • Tokens use format rlgl_<base64url_encoded_random_bytes>
  • Auto-generated tokens use 32 bytes of cryptographically secure randomness
  • Server generates token on first run if not pre-configured

CSRF Protection:

  • Go 1.25's http.CrossOriginProtection middleware
  • Security headers (X-Content-Type-Options, X-Frame-Options, CSP, etc.)
  • SameSite cookies (Lax/Strict modes)

Container Security:

  • Runs as non-root user (uid 65532) in Docker
  • Read-only filesystem in container

License

MIT License - see LICENSE file for details.

Copyright © 2025 Ben Sapp

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL