https://github.com/benwsapp/rlgl
Collaboration app to display your work-in-progress
https://github.com/benwsapp/rlgl
development golang productivity
Last synced: 5 months ago
JSON representation
Collaboration app to display your work-in-progress
- Host: GitHub
- URL: https://github.com/benwsapp/rlgl
- Owner: benwsapp
- License: mit
- Created: 2025-10-02T19:03:08.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-10-16T17:07:39.000Z (8 months ago)
- Last Synced: 2025-10-17T18:09:10.402Z (8 months ago)
- Topics: development, golang, productivity
- Language: Go
- Homepage:
- Size: 263 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Red Light/Green Light
A lightweight dashboard for developers to display their current work-in-progress.
[](https://tip.golang.org/doc/go1.25)
[](https://goreportcard.com/report/github.com/benwsapp/rlgl)
[](LICENSE.md)
[](https://github.com/benwsapp/rlgl/actions/workflows/ci.yml)
[](https://app.codacy.com/gh/benwsapp/rlgl/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[](https://app.codacy.com/gh/benwsapp/rlgl/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
[](https://golangci-lint.run/)
[](https://github.com/benwsapp/rlgl/releases/latest)

**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
## Features
- **Client/Server Architecture**: Server hosts web UI and Slack integration while client manages state
- **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 persistent storage required)
## Getting Started
### Quick Install (Recommended)
```bash
$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash
```
This will install the latest version to `~/.local/bin` and add it to your PATH.
**Install Options:**
```bash
# Install specific version
$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --version v1.0.0
# Install to custom directory
$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --dir /usr/local/bin
# Skip adding to PATH
$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --no-path
```
### Docker
```bash
$ docker run -p 8080:8080 benwsapp/rlgl:latest serve
```
See [Docker documentation](#docker) below for more details.
## Configuration
Create a configuration file at `config/rlgl.yaml`:
```yaml
name: "Ben's WIP Status"
description: "Current work and availability"
user: "Ben Sapp"
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
```bash
# 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
```bash
# Build for current platform
$ docker build -t rlgl:latest .
```
#### Multi-Architecture (using buildx)
```bash
# 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:
```bash
# 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:
```bash
# 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:**
| Variable | Description | Default |
|----------|-------------|---------|
| `RLGL_SERVER_ADDR` | Server address | `:8080` |
| `RLGL_TOKEN` | WebSocket authentication token | Auto-generated if not provided |
| `RLGL_TRUSTED_ORIGINS` | Comma-separated list of trusted origins for CSRF protection | None |
**Client:**
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `RLGL_REMOTE_HOST` | WebSocket server URL | `ws://localhost:8080/ws` | No |
| `RLGL_CLIENT_ID` | Unique client identifier | None | Yes |
| `RLGL_TOKEN` | WebSocket authentication token | None | Yes |
| `RLGL_CLIENT_INTERVAL` | Interval between config pushes | `30s` | No |
| `RLGL_CLIENT_ONCE` | Push config once and exit | `false` | No |
### Docker
#### Run Server
```bash
# 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
```bash
$ 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
```bash
# 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 ` header)
- Supports push config and ping/pong messages
- Backward compatible: also accepts token via `?token=` query parameter
- `GET /status` - JSON endpoint returning all client configs (keyed by client ID)
## Development
### Linting
```bash
# Run all linters
$ golangci-lint run
# Check cognitive complexity
$ gocognit -d -over 10 .
# Lint Dockerfile
$ hadolint Dockerfile
```
### Testing
```bash
# Run tests
$ go test ./...
# Run tests with coverage
$ go test -cover ./...
```
## License
MIT License - see [LICENSE](LICENSE) file for details.
Copyright © 2025 Ben Sapp