{"id":37116983,"url":"https://github.com/benwsapp/rlgl","last_synced_at":"2026-01-14T13:42:06.417Z","repository":{"id":319122531,"uuid":"1068691381","full_name":"benwsapp/rlgl","owner":"benwsapp","description":"Collaboration app to display your work-in-progress","archived":false,"fork":false,"pushed_at":"2025-10-16T17:07:39.000Z","size":269,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-17T18:09:10.402Z","etag":null,"topics":["development","golang","productivity"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benwsapp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-02T19:03:08.000Z","updated_at":"2025-10-16T17:12:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"20aa4ff3-3b03-491d-9871-9e546e7ab473","html_url":"https://github.com/benwsapp/rlgl","commit_stats":null,"previous_names":["benwsapp/rlgl"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/benwsapp/rlgl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwsapp%2Frlgl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwsapp%2Frlgl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwsapp%2Frlgl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwsapp%2Frlgl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benwsapp","download_url":"https://codeload.github.com/benwsapp/rlgl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwsapp%2Frlgl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28421725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T13:30:50.153Z","status":"ssl_error","status_checked_at":"2026-01-14T13:29:08.907Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["development","golang","productivity"],"created_at":"2026-01-14T13:42:05.743Z","updated_at":"2026-01-14T13:42:06.397Z","avatar_url":"https://github.com/benwsapp.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Red Light/Green Light\n\nA lightweight dashboard for developers to display their current work-in-progress.\n\n[![Go](https://img.shields.io/badge/go-1.25-00ADD8.svg?logo=go)](https://tip.golang.org/doc/go1.25)\n[![Go Report Card](https://goreportcard.com/badge/github.com/benwsapp/rlgl)](https://goreportcard.com/report/github.com/benwsapp/rlgl)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)\n[![Test Status](https://github.com/benwsapp/rlgl/actions/workflows/ci.yml/badge.svg)](https://github.com/benwsapp/rlgl/actions/workflows/ci.yml)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/35f11d9745244b6ea9b4f7656bd0ed74)](https://app.codacy.com/gh/benwsapp/rlgl/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/35f11d9745244b6ea9b4f7656bd0ed74)](https://app.codacy.com/gh/benwsapp/rlgl/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_coverage)\n[![golangci-lint](https://img.shields.io/badge/linted%20by-golangci--lint-brightgreen)](https://golangci-lint.run/)\n[![GitHub tag](https://img.shields.io/github/v/tag/benwsapp/rlgl?color=blue)](https://github.com/benwsapp/rlgl/releases/latest)\n\n\n![rlgl](https://github.com/benwsapp/rlgl/blob/main/img/screenshot.png)\n\n**rlgl** runs in two modes:\n- **Server Mode**: Hosts the dashboard web interface and receives status updates via WebSocket\n- **Client Mode**: Reads your local YAML config and pushes updates to the server\n\n## Features\n\n- **Client/Server Architecture**: Server hosts web UI and Slack integration while client manages state\n- **WebSocket Authentication**: Secure WebSocket connections with token-based authentication\n- **WebSocket Communication**: Clients push config updates to the server via WebSocket\n- **Real-time Updates**: Server-Sent Events (SSE) stream config changes instantly to web viewers\n- **Simple Configuration**: Single YAML file to manage your work status\n- **Focus Indicator**: Show what you're currently working on\n- **Task Queue**: Display your upcoming tasks\n- **In-Memory Storage**: Server stores client configs in memory (no persistent storage required)\n\n## Getting Started\n\n### Quick Install (Recommended)\n\n```bash\n$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash\n```\n\nThis will install the latest version to `~/.local/bin` and add it to your PATH.\n\n**Install Options:**\n```bash\n# Install specific version\n$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --version v1.0.0\n\n# Install to custom directory\n$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --dir /usr/local/bin\n\n# Skip adding to PATH\n$ curl -sSL https://raw.githubusercontent.com/benwsapp/rlgl/main/install.sh | bash -s -- --no-path\n```\n\n### Docker\n\n```bash\n$ docker run -p 8080:8080 benwsapp/rlgl:latest serve\n```\n\nSee [Docker documentation](#docker) below for more details.\n\n## Configuration\n\nCreate a configuration file at `config/rlgl.yaml`:\n\n```yaml\nname: \"Ben's WIP Status\"\ndescription: \"Current work and availability\"\nuser: \"Ben Sapp\"\ncontributor:\n  active: true\n  focus: \"Implementing CSRF protection for rlgl\"\n  queue:\n    - \"Add Docker multi-arch support\"\n    - \"Write comprehensive tests\"\n    - \"Update documentation\"\n```\n\nThe config file structure:\n- `name`: Your status page title\n- `description`: Brief description of the page\n- `user`: Your username or identifier\n- `contributor.active`: Status indicator (true = green light/available, false = red light/busy)\n- `contributor.focus`: What you're currently working on\n- `contributor.queue`: Your upcoming tasks/backlog\n\nUpdate the YAML file anytime to change your status - the client will push updates to the server automatically!\n\n## Building from Source\n\n### Go Build\n\n```bash\n# Clone the repository\n$ git clone https://github.com/benwsapp/rlgl.git\n$ cd rlgl\n\n# Download dependencies\n$ go mod download\n\n# Build the binary\n$ go build -o rlgl .\n```\n\n### Docker Build\n\n#### Single Architecture\n\n```bash\n# Build for current platform\n$ docker build -t rlgl:latest .\n```\n\n#### Multi-Architecture (using buildx)\n\n```bash\n# Create a new builder (first time only)\n$ docker buildx create --name multiarch --use\n\n# Build for multiple architectures\n$ docker buildx build \\\n    --platform linux/amd64,linux/arm64 \\\n    -t your-registry/rlgl:latest \\\n    --push .\n```\n\n## Running\n\n### Server Mode\n\nRun the server to host the dashboard and receive updates from clients:\n\n```bash\n# Run server with defaults (listens on :8080)\n# Authentication token will be auto-generated and displayed\n$ ./rlgl serve\n\n# Specify custom address\n$ ./rlgl serve --addr :3000\n\n# With pre-configured authentication token\n$ ./rlgl serve --token rlgl_your_secret_token_here\n\n# With trusted origins for CSRF (comma-separated)\n$ ./rlgl serve --trusted-origins https://example.com,https://app.example.com\n\n# Using environment variables\n$ export RLGL_SERVER_ADDR=\":3000\"\n$ export RLGL_TOKEN=\"rlgl_your_secret_token_here\"\n$ export RLGL_TRUSTED_ORIGINS=\"https://example.com,https://app.example.com\"\n$ ./rlgl serve\n```\n\n**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!\n\n### Client Mode\n\nRun the client to push your local config to the server:\n\n```bash\n# Push config continuously (every 30s by default)\n# Replace TOKEN with the value from server startup\n$ ./rlgl client \\\n    --client-id my-laptop \\\n    --config config/rlgl.yaml \\\n    --server ws://localhost:8080/ws \\\n    --token rlgl_your_token_here\n\n# Push config once and exit\n$ ./rlgl client \\\n    --client-id my-laptop \\\n    --config config/rlgl.yaml \\\n    --server ws://localhost:8080/ws \\\n    --token rlgl_your_token_here \\\n    --once\n\n# Custom push interval\n$ ./rlgl client \\\n    --client-id my-laptop \\\n    --config config/rlgl.yaml \\\n    --server ws://localhost:8080/ws \\\n    --token rlgl_your_token_here \\\n    --interval 1m\n\n# Using environment variables (defaults to rlgl.yaml in current directory)\n$ export RLGL_REMOTE_HOST=\"ws://localhost:8080/ws\"\n$ export RLGL_CLIENT_ID=\"my-laptop\"\n$ export RLGL_TOKEN=\"rlgl_your_token_here\"\n$ export RLGL_CLIENT_INTERVAL=\"1m\"\n$ ./rlgl client\n```\n\n### Environment Variables\n\n**Server:**\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `RLGL_SERVER_ADDR` | Server address | `:8080` |\n| `RLGL_TOKEN` | WebSocket authentication token | Auto-generated if not provided |\n| `RLGL_TRUSTED_ORIGINS` | Comma-separated list of trusted origins for CSRF protection | None |\n\n**Client:**\n\n| Variable | Description | Default | Required |\n|----------|-------------|---------|----------|\n| `RLGL_REMOTE_HOST` | WebSocket server URL | `ws://localhost:8080/ws` | No |\n| `RLGL_CLIENT_ID` | Unique client identifier | None | Yes |\n| `RLGL_TOKEN` | WebSocket authentication token | None | Yes |\n| `RLGL_CLIENT_INTERVAL` | Interval between config pushes | `30s` | No |\n| `RLGL_CLIENT_ONCE` | Push config once and exit | `false` | No |\n\n### Docker\n\n#### Run Server\n\n```bash\n# Server will generate and display authentication token on startup\n$ docker run -p 8080:8080 \\\n    rlgl:latest serve --addr :8080\n\n# Or use pre-configured token\n$ docker run -p 8080:8080 \\\n    -e RLGL_TOKEN=\"rlgl_your_token_here\" \\\n    rlgl:latest serve --addr :8080\n```\n\n#### Run Client\n\n```bash\n$ docker run \\\n    -v $(pwd)/config/rlgl.yaml:/config/rlgl.yaml:ro \\\n    rlgl:latest client \\\n        --client-id docker-client \\\n        --config /config/rlgl.yaml \\\n        --server ws://host.docker.internal:8080/ws \\\n        --token rlgl_your_token_here\n```\n\n#### With Environment Variables\n\n```bash\n# Server\n$ docker run -p 8080:8080 \\\n    -e RLGL_TOKEN=\"rlgl_your_token_here\" \\\n    -e RLGL_TRUSTED_ORIGINS=\"https://example.com,https://app.example.com\" \\\n    rlgl:latest serve\n\n# Client\n$ docker run \\\n    -v $(pwd)/config:/config:ro \\\n    -e RLGL_REMOTE_HOST=\"ws://host.docker.internal:8080/ws\" \\\n    -e RLGL_CLIENT_ID=\"docker-client\" \\\n    -e RLGL_TOKEN=\"rlgl_your_token_here\" \\\n    rlgl:latest client --config /config/rlgl.yaml\n```\n\n## Endpoints\n\n**Web Interface:**\n- `GET /` - Main page (renders template with first available client config)\n- `GET /config` - JSON endpoint returning first available client config\n- `GET /events` - Server-Sent Events stream for real-time config updates\n\n**WebSocket API:**\n- `WS /ws` - WebSocket endpoint for client connections (requires authentication via `Authorization: Bearer \u003ctoken\u003e` header)\n  - Supports push config and ping/pong messages\n  - Backward compatible: also accepts token via `?token=\u003ctoken\u003e` query parameter\n- `GET /status` - JSON endpoint returning all client configs (keyed by client ID)\n\n## Development\n\n### Linting\n\n```bash\n# Run all linters\n$ golangci-lint run\n\n# Check cognitive complexity\n$ gocognit -d -over 10 .\n\n# Lint Dockerfile\n$ hadolint Dockerfile\n```\n\n### Testing\n\n```bash\n# Run tests\n$ go test ./...\n\n# Run tests with coverage\n$ go test -cover ./...\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\nCopyright © 2025 Ben Sapp\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenwsapp%2Frlgl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenwsapp%2Frlgl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenwsapp%2Frlgl/lists"}