feat: ship HTTP dashboard and harden daemon/API flows
Add the static HTTP dashboard example and wire in the recent daemon/API polish: CORS-aware API routing, service-install behavior cleanup, safer systemd unit ExecStart quoting, and friendly-name validation for path-safe targeting. Also refresh README/API/roadmap docs, remove the temporary claude observations file, and include the related tests for API/status and daemon validation.
This commit is contained in:
@@ -90,6 +90,16 @@ builders — Home Assistant integrations, stream deck plugins, scripts, dashboar
|
||||
default. HTTP handlers dispatch directly inside the daemon process rather than looping back through
|
||||
the Unix socket. All responses are JSON.
|
||||
|
||||
Browser clients can be enabled with opt-in CORS settings:
|
||||
|
||||
```toml
|
||||
[daemon]
|
||||
cors_enabled = true
|
||||
cors_allowed_origins = ["http://127.0.0.1:8080", "http://localhost:8080"]
|
||||
```
|
||||
|
||||
A full endpoint test dashboard example lives at `examples/http-dashboard/`.
|
||||
|
||||
**Adapter Layer**
|
||||
Each TV platform is implemented as an adapter behind a common Rust trait. The adapter handles all
|
||||
platform-specific protocol details. Above the adapter layer, nothing knows or cares whether the TV
|
||||
@@ -300,6 +310,20 @@ GET /v1/devices/a3f2c1d4-.../state
|
||||
GET /v1/devices/living-room/state ← same result
|
||||
```
|
||||
|
||||
If you use a friendly name in the path, URL-encode it first. This is required
|
||||
for names containing spaces or reserved characters.
|
||||
|
||||
```bash
|
||||
# Friendly name: "Living Room TV"
|
||||
curl http://127.0.0.1:7272/v1/devices/Living%20Room%20TV/state
|
||||
```
|
||||
|
||||
Friendly-name validation:
|
||||
|
||||
- Spaces are allowed.
|
||||
- Leading/trailing whitespace is trimmed.
|
||||
- `/` and `%` are rejected to keep path-based targeting safe and unambiguous.
|
||||
|
||||
### Example Requests
|
||||
|
||||
```bash
|
||||
@@ -381,6 +405,8 @@ socket = "/run/user/1000/tvctl.sock"
|
||||
http_enabled = true
|
||||
http_port = 7272
|
||||
http_host = "127.0.0.1"
|
||||
cors_enabled = false
|
||||
cors_allowed_origins = []
|
||||
log_level = "info"
|
||||
|
||||
[discovery]
|
||||
@@ -405,6 +431,8 @@ roku_password = ""
|
||||
| `daemon.http_enabled` | `true` | Expose HTTP API |
|
||||
| `daemon.http_port` | `7272` | HTTP API port |
|
||||
| `daemon.http_host` | `127.0.0.1` | Bind address (loopback by default) |
|
||||
| `daemon.cors_enabled` | `false` | Enable browser CORS responses for allowed origins |
|
||||
| `daemon.cors_allowed_origins` | `[]` | Explicit CORS origin allowlist used when CORS is enabled |
|
||||
| `daemon.log_level` | `info` | Tracing filter (for example `info` or `tvctl=debug`), applied on daemon start and `tvctl config reload` |
|
||||
| `discovery.auto_discover` | `true` | Discover devices on daemon start |
|
||||
| `discovery.interval_secs` | `300` | Re-scan interval (0 = disabled) |
|
||||
@@ -419,6 +447,23 @@ roku_password = ""
|
||||
## Storage Layout
|
||||
|
||||
```
|
||||
|
||||
## Dashboard Example
|
||||
|
||||
A static browser dashboard for manually testing every API endpoint is included:
|
||||
|
||||
`examples/http-dashboard/`
|
||||
|
||||
Run it:
|
||||
|
||||
```bash
|
||||
tvctl config set daemon.cors_enabled true
|
||||
tvctl config set daemon.cors_allowed_origins "http://127.0.0.1:8080,http://localhost:8080"
|
||||
tvctl config reload
|
||||
python3 -m http.server 8080 -d examples/http-dashboard
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:8080`.
|
||||
~/.config/tvctl/
|
||||
└── config.toml
|
||||
|
||||
|
||||
Reference in New Issue
Block a user