{"id":38004647,"url":"https://github.com/pfrederiksen/rivian-ls","last_synced_at":"2026-04-05T01:01:26.605Z","repository":{"id":332677065,"uuid":"1134596905","full_name":"pfrederiksen/rivian-ls","owner":"pfrederiksen","description":"Production-quality TUI + headless CLI for monitoring Rivian vehicle telemetry via unofficial API","archived":false,"fork":false,"pushed_at":"2026-03-24T23:21:30.000Z","size":563,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T01:12:28.421Z","etag":null,"topics":["bubbletea","cli","golang","graphql","rivian","telemetry","tui","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"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/pfrederiksen.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":"2026-01-14T23:52:05.000Z","updated_at":"2026-03-24T23:21:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pfrederiksen/rivian-ls","commit_stats":null,"previous_names":["pfrederiksen/rivian-ls"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/pfrederiksen/rivian-ls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrederiksen%2Frivian-ls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrederiksen%2Frivian-ls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrederiksen%2Frivian-ls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrederiksen%2Frivian-ls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pfrederiksen","download_url":"https://codeload.github.com/pfrederiksen/rivian-ls/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfrederiksen%2Frivian-ls/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31420789,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T00:25:07.052Z","status":"ssl_error","status_checked_at":"2026-04-05T00:25:05.923Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["bubbletea","cli","golang","graphql","rivian","telemetry","tui","websocket"],"created_at":"2026-01-16T19:15:50.158Z","updated_at":"2026-04-05T01:01:26.567Z","avatar_url":"https://github.com/pfrederiksen.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rivian-ls\n\nA production-quality terminal UI (TUI) and headless CLI tool for monitoring Rivian vehicle telemetry in real-time.\n\n\u003e ⚠️ **WARNING**: This tool uses an **unofficial** Rivian API that is not publicly documented or supported. Using this tool may violate Rivian's Terms of Service. Use at your own risk. The API may change or break at any time without notice.\n\n## Features\n\n- 🚗 **Real-time vehicle monitoring** via GraphQL + WebSocket subscriptions\n- 📊 **Interactive TUI** powered by Bubble Tea with multiple views\n- 🚙 **Multi-vehicle support** with interactive selection menu\n- 📈 **Historical charts** with ASCII sparklines for all metrics\n- 🤖 **Headless CLI mode** for scripting and automation\n- 💾 **Local persistence** for historical data and analysis\n- 🔐 **Secure credential storage** with OS keychain integration\n- 📉 **Derived insights**: charging narratives, readiness score, efficiency tracking\n- ⚙️ **Flexible configuration** via config file, environment variables, or CLI flags\n- 🔄 **Auto-fallback** from WebSocket to HTTP polling when needed\n\n### What's New in v0.4.0\n\n- **`login` command**: Standalone authentication command for verifying credentials\n  - Works fully non-interactively: `rivian-ls --email x --password y --otp 123456 login`\n  - Validates session end-to-end by querying vehicles after auth\n- **Two-phase OTP login**: Non-interactive MFA via two separate invocations\n  - Phase 1: `rivian-ls --email x --password y login` triggers SMS, saves session\n  - Phase 2: `rivian-ls login --otp 123456` completes authentication\n- **Non-TTY support**: Clear error messages when interactive prompts are needed but no terminal is available\n  - Guides users to the correct flag, env var, or config file\n- **Bug fix**: Fixed `UNAUTHENTICATED` error when using cached credentials\n  - Cached auth was missing CSRF token and app session ID required by the API\n  - Now creates a fresh session after restoring credentials from cache\n\n### What's New in v0.3.0\n\n- **Multi-Vehicle Support**: Interactive vehicle selection menu (`v` key)\n  - Switch between vehicles at runtime without restarting\n  - Shows battery %, online status, and vehicle details\n  - Keyboard navigation with arrows or number keys\n- **Historical Charts**: New 4th view with ASCII sparklines\n  - Battery Level, Range, Charging Rate, Temperature, Efficiency\n  - Configurable time ranges (24h, 7d, 30d)\n  - Statistics display (current, min, max, change)\n  - Left/Right arrows to switch metrics, `t` to cycle time ranges\n- **Bug Fix**: Honors `--vehicle` flag for initial vehicle selection\n\n### What's New in v0.2.0\n\n- **Config File Support**: Create `~/.config/rivian-ls/config.yaml` to set defaults\n- **Environment Variables**: Configure via `RIVIAN_EMAIL`, `RIVIAN_VERBOSE`, etc.\n- **New Flags**: `--quiet`, `--verbose`, `--no-store` for better control\n- **Standardized Exit Codes**: Proper exit codes (0-4) for shell scripting\n- **Configuration Layering**: CLI flags \u003e env vars \u003e config file \u003e defaults\n\n## Screenshots\n\n### Dashboard View\nReal-time overview of battery, charging, security, tire status, and calculated metrics.\n\n![Dashboard View](docs/screenshots/dashboard.png)\n\n### Charge View\nDetailed charging information with battery details and intelligent recommendations.\n\n![Charge View](docs/screenshots/charge.png)\n\n### Health View\nVehicle diagnostics, trends over time, and closure status monitoring.\n\n![Health View](docs/screenshots/health.png)\n\n## Installation\n\n### Homebrew (Recommended)\n\n```bash\nbrew install pfrederiksen/tap/rivian-ls\n```\n\n### Download Binary\n\nDownload the latest release for your platform from the [Releases page](https://github.com/pfrederiksen/rivian-ls/releases).\n\n### From Source\n\n**Prerequisites:**\n- Go 1.21 or later\n- A Rivian account with at least one vehicle\n\n```bash\ngit clone https://github.com/pfrederiksen/rivian-ls.git\ncd rivian-ls\nmake build\n```\n\nThe binary will be built as `./rivian-ls`.\n\n## Quick Start\n\n### TUI Mode (Interactive Dashboard)\n\nLaunch the interactive terminal UI:\n\n```bash\nrivian-ls\n```\n\nYou'll be prompted for your email and password on first run. If MFA/OTP is enabled, you'll be asked for the code. Credentials are cached securely for future runs.\n\nFor non-interactive login (e.g., scripts or CI), use the two-phase flow:\n\n```bash\n# Phase 1: Send credentials, trigger SMS\nrivian-ls login --email user@example.com --password secret\n\n# Phase 2: Complete with OTP code after receiving SMS\nrivian-ls login --otp 123456\n```\n\n**Navigation:**\n- Press `1`, `2`, `3`, or `4` (or `d`, `c`, `h`) to switch between views\n- Press `v` to open vehicle selection menu (multi-vehicle accounts)\n- Press `r` to manually refresh data\n- Press `q` or `Ctrl+C` to quit\n\n**Views:**\n1. **Dashboard** (`1` or `d`): Battery, range, charging status, locks, closures, cabin temp, tire pressures, ready score\n2. **Charge** (`2` or `c`): Detailed charging session info and history\n3. **Health** (`3` or `h`): Tire pressure trends and vehicle timeline\n4. **Charts** (`4`): Historical trends with ASCII sparklines\n   - Battery Level (%)\n   - Range Estimate (mi)\n   - Charging Rate (kW)\n   - Cabin Temperature (°F)\n   - Energy Efficiency (mi/kWh)\n   - Press `←`/`→` to switch metrics\n   - Press `t` to cycle time ranges (24h → 7d → 30d)\n\n### CLI Mode (Headless/Scripting)\n\nThe CLI mode is designed for scripting, automation, and piping data to other tools.\n\n#### Authenticate\n\n```bash\n# Interactive login (prompts for email, password, OTP)\nrivian-ls login\n\n# Non-interactive two-phase login:\n# Phase 1 — send credentials, trigger SMS\nrivian-ls login --email user@example.com --password secret\n# Phase 2 — complete with OTP code after receiving SMS\nrivian-ls login --otp 123456\n\n# Using environment variables\nRIVIAN_EMAIL=user@example.com RIVIAN_PASSWORD=secret rivian-ls login\n```\n\n#### Get a snapshot\n\n```bash\n# Human-readable text output (default)\nrivian-ls status\n\n# JSON output for scripting\nrivian-ls status --format json --pretty\n\n# YAML output\nrivian-ls status --format yaml --pretty\n\n# CSV output\nrivian-ls status --format csv\n\n# Table output\nrivian-ls status --format table\n```\n\n#### Stream live updates\n\n```bash\n# Stream updates continuously (WebSocket with auto-fallback to polling)\nrivian-ls watch\n\n# JSON output\nrivian-ls watch --format json --pretty\n\n# Force polling mode with 30-second interval\nrivian-ls watch --interval 30s\n\n# Note: WebSocket may fail due to Rivian API limitations - the tool automatically\n# falls back to HTTP polling mode (30s interval) when this happens\n```\n\n#### Export historical data\n\n```bash\n# Export all cached history as JSON\nrivian-ls export --format json --pretty \u003e vehicle-history.json\n\n# Export last 100 records as CSV\nrivian-ls export --limit 100 --format csv \u003e history.csv\n\n# Export data from the last 24 hours\nrivian-ls export --since 24h --format yaml \u003e last-24h.yaml\n```\n\n#### Common Options\n\n- `--email \u003cemail\u003e`: Specify email (prompts if not provided, required in non-TTY mode)\n- `--password \u003cpassword\u003e`: Specify password (prompts securely if not provided, required in non-TTY mode)\n- `--otp \u003ccode\u003e`: Provide MFA/OTP code to complete a two-phase login\n- `--vehicle \u003cindex\u003e`: Select vehicle by index (0-based, default: 0)\n- `--db \u003cpath\u003e`: Custom database path (default: `~/.local/share/rivian-ls/state.db`)\n- `--format \u003cformat\u003e`: Output format for CLI commands (`text`, `json`, `yaml`, `csv`, `table`)\n- `--pretty`: Pretty-print JSON/YAML output\n- `--interval \u003cduration\u003e`: Polling interval for watch mode (e.g., `30s`, `1m`)\n- `--offline`: Use cached data only (for `status` command)\n\n#### Exit Codes\n\n- `0`: Success\n- `1`: Authentication failure (invalid credentials, OTP failed)\n- `2`: Vehicle not found (no vehicles registered, invalid vehicle index)\n- `3`: API error (network failure, Rivian API unavailable)\n- `4`: Invalid arguments (bad flags, conflicting options, config errors)\n\n## Configuration\n\nConfiguration can be provided via multiple sources. Priority order (highest to lowest):\n1. Command-line flags\n2. Environment variables\n3. Config file (`~/.config/rivian-ls/config.yaml`)\n4. Defaults\n\n### Config File\n\nCreate `~/.config/rivian-ls/config.yaml`:\n\n```yaml\n# Authentication (optional - will prompt if not provided)\nemail: your.email@example.com\n# password: leave empty - prompting is more secure\n\n# Storage\ndb_path: ~/.local/share/rivian-ls/state.db\ndisable_store: false  # Set to true to prevent saving state history\n\n# Vehicle selection\nvehicle: 0  # 0-based index if you have multiple vehicles\n\n# Polling interval for watch mode\npoll_interval: 30s\n\n# Output verbosity\nquiet: false    # Suppress informational messages\nverbose: false  # Enable debug logging\n```\n\nSee [`config.yaml.example`](config.yaml.example) for a complete example.\n\n### Environment Variables\n\nAll config file options can be set via environment variables:\n\n```bash\nexport RIVIAN_EMAIL=\"your.email@example.com\"\nexport RIVIAN_PASSWORD=\"your-password\"  # Not recommended - use prompt instead\nexport RIVIAN_DB_PATH=\"/custom/path/to/state.db\"\nexport RIVIAN_TOKEN_CACHE=\"/custom/path/to/credentials.json\"\nexport RIVIAN_DISABLE_STORE=\"true\"\nexport RIVIAN_POLL_INTERVAL=\"30s\"\nexport RIVIAN_QUIET=\"true\"\nexport RIVIAN_VERBOSE=\"true\"\n```\n\n### Credential Storage\n\nCredentials are cached in `~/.config/rivian-ls/credentials.json`. The cache includes:\n- Email address\n- Access token and refresh token\n- Token expiration times\n\nOn subsequent runs, the tool will automatically use cached credentials. If tokens are expired, they'll be refreshed automatically. If refresh fails, you'll be prompted to log in again.\n\n### Multi-Vehicle Support\n\n**TUI Mode (Interactive):**\n- Press `v` to open the vehicle selection menu\n- Navigate with arrow keys or numbers (1-9)\n- Press Enter to confirm selection, Esc to cancel\n- Switch vehicles at runtime without restarting\n\n**CLI Mode (Headless):**\nUse `--vehicle \u003cindex\u003e` to select which vehicle on startup:\n\n```bash\n# Use first vehicle (default)\nrivian-ls status --vehicle 0\n\n# Use second vehicle\nrivian-ls status --vehicle 1\n```\n\n## Development\n\nSee [CLAUDE.md](CLAUDE.md) for development workflow, testing, and architecture details.\n\n## Architecture\n\n```\nrivian-ls/\n├── cmd/rivian-ls/          # CLI entrypoint\n├── internal/\n│   ├── rivian/            # GraphQL + WebSocket client for Rivian API\n│   ├── model/             # Domain models and state reducer\n│   ├── tui/               # Bubble Tea TUI implementation\n│   ├── cli/               # Headless CLI formatters and commands\n│   └── store/             # Local snapshot persistence (SQLite/BoltDB)\n├── docs/                  # Additional documentation\n└── .github/workflows/     # CI/CD pipelines\n```\n\n## Security \u0026 Privacy\n\n- **Credentials**: Never hardcoded or logged. Cached in `~/.config/rivian-ls/credentials.json` with `0600` permissions.\n- **Tokens**: Access/refresh tokens are stored securely and refreshed automatically. Never printed to stdout/stderr.\n- **Password input**: Prefer `RIVIAN_PASSWORD` env var or interactive prompt over `--password` flag (flags are visible in `ps` output). Config files containing passwords must have `0600` permissions or the password is rejected.\n- **Database**: SQLite file created with `0600` permissions. Contains vehicle telemetry including GPS coordinates.\n- **Data**: All data stored locally only (not sent to third parties).\n- **Privacy**: Use `--no-store` flag to disable local persistence entirely.\n- **Network**: All API calls use TLS with certificate verification. No secrets in URLs.\n\n## Troubleshooting\n\n### Authentication fails\n\n- Ensure your email and password are correct\n- If you have MFA enabled, ensure you enter the correct OTP code\n- Check that you can log in via the official Rivian mobile app\n\n### WebSocket connection fails\n\n- The app will automatically fall back to polling\n- Check your network/firewall settings\n- Try increasing `--interval` for longer polling periods\n\n### \"Vehicle not found\"\n\n- Ensure you have at least one vehicle registered in your Rivian account\n- Try using `--vehicle \u003cVIN\u003e` to select a specific vehicle\n\n## Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch (`feat/...`, `fix/...`, `chore/...`)\n3. Write tests for new functionality\n4. Ensure `make check` passes (linting + tests + coverage threshold)\n5. Update documentation as needed\n6. Open a pull request against `main`\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Disclaimer\n\nThis project is not affiliated with, endorsed by, or connected to Rivian Automotive, LLC. All product names, logos, and brands are property of their respective owners.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfrederiksen%2Frivian-ls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpfrederiksen%2Frivian-ls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfrederiksen%2Frivian-ls/lists"}