59fb56558f
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.
187 lines
8.5 KiB
Markdown
187 lines
8.5 KiB
Markdown
# ROADMAP.md
|
|
# tvctl — Feature Roadmap and Milestone Tracker
|
|
# Agents: update this file as work is completed. See AGENT.md for instructions.
|
|
# Last updated: 2026-04-18
|
|
|
|
---
|
|
|
|
## Current Focus
|
|
|
|
**Milestone 6 — Polish and Release Prep**
|
|
Close the low-risk polish items that make the CLI easier to install, discover, and use day to day.
|
|
|
|
---
|
|
|
|
## In Progress
|
|
|
|
- Milestone 6 is in progress; shell completions and first-run CLI polish are landing first while heavier release work stays pending
|
|
|
|
---
|
|
|
|
## Milestone 1 — Project Foundation
|
|
_Goal: A compiling Rust project with correct structure and no logic yet._
|
|
|
|
_Completed 2026-04-14. See Completed below._
|
|
|
|
---
|
|
|
|
## Milestone 2 — Roku Adapter
|
|
_Goal: Can communicate with a real Roku TV over ECP._
|
|
|
|
- [x] 2026-04-14 — Implement core Roku ECP adapter in `src/adapters/roku/`
|
|
- [x] 2026-04-14 — `discover()` — SSDP scan returning Roku devices
|
|
- [x] 2026-04-14 — `list_apps()` — fetch installed channel list via ECP
|
|
- [x] 2026-04-14 — `launch()` — launch app by ECP channel ID
|
|
- [x] 2026-04-14 — `stop_app()` — exit current app
|
|
- [x] 2026-04-14 — `key()` — send ECP keypress
|
|
- [x] 2026-04-14 — `sequence()` — send multiple keypresses
|
|
- [x] 2026-04-14 — `state()` — query power state and active app
|
|
- [x] 2026-04-14 — `dev_install()` — zip upload via ECP developer web installer with Digest auth
|
|
- [x] 2026-04-14 — `dev_reload()` — reload the sideloaded app via `launch/dev`
|
|
- [x] 2026-04-14 — `dev_logs()` — fetch BrightScript debugger output from the live dev socket
|
|
- [x] 2026-04-14 — Key translation table (TvKey → Roku ECP key string)
|
|
- [x] 2026-04-14 — Automated live validation against `58" Hisense Roku TV` at `10.10.0.136`
|
|
|
|
---
|
|
|
|
## Milestone 3 — Daemon Core
|
|
_Goal: tvctld runs, manages devices, and handles the Unix socket._
|
|
|
|
- [x] 2026-04-14 — Daemon entry point and lifecycle (`src/daemon/mod.rs`)
|
|
- [x] 2026-04-14 — Unix socket listener
|
|
- [x] 2026-04-14 — Device registry (`src/daemon/registry.rs`)
|
|
- [x] Load from `devices.json` on start
|
|
- [x] Persist on change
|
|
- [x] CRUD operations
|
|
- [x] 2026-04-14 — Discovery service (`src/daemon/discovery.rs`)
|
|
- [x] SSDP scan
|
|
- [x] Auto-discover on startup (if configured)
|
|
- [x] Interval-based re-scan
|
|
- [x] Manual add by IP
|
|
- [x] 2026-04-14 — App cache manager (`src/daemon/cache.rs`)
|
|
- [x] Per-platform JSON files
|
|
- [x] Organic growth strategy
|
|
- [x] `app refresh` invalidation
|
|
- [x] 2026-04-14 — State cache (`src/daemon/state.rs`)
|
|
- In-memory only
|
|
- Per-device last-known state
|
|
- Timestamp on every entry
|
|
- [x] 2026-04-14 — Adapter registry (map platform string → adapter instance)
|
|
- [x] 2026-04-14 — Config loading from TOML
|
|
|
|
---
|
|
|
|
## Milestone 4 — CLI
|
|
_Goal: All tvctl commands work against a running daemon._
|
|
|
|
- [x] 2026-04-14 — CLI entry point and dispatch (`src/cli/mod.rs`)
|
|
- [x] 2026-04-14 — Unix socket client (send commands, receive responses)
|
|
- [x] 2026-04-14 `tvctl daemon` commands
|
|
- [x] `start` `stop` `restart` `status`
|
|
- [x] `install` (generate systemd user unit)
|
|
- [x] `uninstall`
|
|
- [x] 2026-04-14 `tvctl device` commands
|
|
- [x] `list` `discover` `add` `select` `info` `remove`
|
|
- [ ] `tvctl app` commands
|
|
- [x] 2026-04-14 `list` `launch` `stop` `refresh`
|
|
- [ ] `tvctl remote` commands
|
|
- [x] 2026-04-14 `key` `sequence`
|
|
- [x] 2026-04-14 `tvctl state`
|
|
- [x] 2026-04-14 `tvctl dev` commands
|
|
- [x] `install` `reload` `logs`
|
|
- [x] 2026-04-14 `tvctl config` commands
|
|
- [x] `list` `get` `set` `reset` `reload`
|
|
- [x] 2026-04-14 Global flags: `--device` `--json` `--help` `--version`
|
|
- [x] 2026-04-14 Full help text on every command (see AGENT.md definition of done)
|
|
- [x] 2026-04-14 Full help output on bare `tvctl`
|
|
- [x] 2026-04-14 Friendly error messages with hints on every failure path
|
|
- [x] 2026-04-14 `--json` output verified on every command
|
|
|
|
---
|
|
|
|
## Milestone 5 — HTTP API
|
|
_Goal: Full /v1/ API running on 127.0.0.1:7272._
|
|
|
|
- [x] 2026-04-15 — axum server setup in `src/api/mod.rs`
|
|
- [x] 2026-04-15 — All routes implemented (see PROJECT_MAP.md API surface)
|
|
- [x] 2026-04-15 — Standard response envelope on all routes
|
|
- [x] 2026-04-15 — Error responses with `code` + `message` + `hint`
|
|
- [x] 2026-04-15 — Device addressable by UUID or friendly name on all routes
|
|
- [x] 2026-04-15 — `PATCH /v1/config` with partial update support
|
|
- [x] 2026-04-15 — `POST /v1/config/reload` triggers live config reload in daemon
|
|
- [x] 2026-04-15 — Integration coverage for core HTTP routes against an isolated running daemon
|
|
|
|
---
|
|
|
|
## Milestone 6 — Polish and Release Prep
|
|
_Goal: Ready for real use._
|
|
|
|
- [x] 2026-04-15 — Shell completions (bash, zsh, fish) via clap
|
|
- [x] 2026-04-18 — `tvctl daemon install` generates correct systemd unit file
|
|
- [x] 2026-04-15 — First-run experience: helpful output when no devices discovered yet
|
|
- [x] 2026-04-15 — Daemon startup message with socket path and HTTP port
|
|
- [x] 2026-04-18 — Log output via `tracing` (respects `log_level` config)
|
|
- [x] 2026-04-15 — README accuracy pass (verify all examples work)
|
|
- [x] 2026-04-15 — `cargo clippy` clean
|
|
- [x] 2026-04-15 — `cargo test` passing
|
|
- [x] 2026-04-18 — Included static HTTP dashboard example for endpoint-by-endpoint API testing
|
|
- [ ] Cross-compile test (x86_64 + aarch64)
|
|
- [ ] GitHub Actions CI (build + clippy + test, Rust toolchain >= 1.85 for edition 2024)
|
|
- [ ] First binary release
|
|
|
|
---
|
|
|
|
## Post-MVP (Do Not Implement in v1)
|
|
|
|
These are captured here so they are not forgotten, but they are explicitly
|
|
out of scope until Milestone 6 is complete and stable.
|
|
|
|
- [ ] Google TV / Android TV adapter (ADB)
|
|
- [ ] Fire TV adapter (ADB variant)
|
|
- [ ] WebSocket live state updates
|
|
- [ ] Event watching / triggers
|
|
- [ ] Device groups (send command to multiple TVs)
|
|
- [ ] Automation rules engine
|
|
- [ ] Home Assistant integration
|
|
- [ ] Web UI (consumes HTTP API, no business logic)
|
|
- [ ] `tvctl dev logs` streaming (currently returns last N lines only)
|
|
- [ ] macOS support (launchd instead of systemd)
|
|
|
|
---
|
|
|
|
## Completed
|
|
|
|
- [x] 2026-04-14 — Initialize Cargo workspace (`cargo init`)
|
|
- [x] 2026-04-14 — Add baseline dependencies to `Cargo.toml`
|
|
- [x] 2026-04-14 — Create module skeleton and placeholder docs layout
|
|
- [x] 2026-04-14 — Define the adapter contract and core shared data types
|
|
- [x] 2026-04-14 — Compile the project cleanly with `cargo build`
|
|
- [x] 2026-04-14 — Add Roku ECP discovery, input, app, and state adapter support with unit tests
|
|
- [x] 2026-04-14 — Add env-gated live Roku integration tests and validate against the Hisense TV on the LAN
|
|
- [x] 2026-04-14 — Implement Roku developer-mode install/log support and validate sideloading on the Hisense TV
|
|
- [x] 2026-04-14 — Add daemon config loading, runtime paths, persisted registry/cache stores, and discovery foundations
|
|
- [x] 2026-04-14 — Add daemon Unix socket IPC plus working `daemon` and `device` lifecycle/discovery commands
|
|
- [x] 2026-04-14 — Finish Milestone 3 with registry CRUD, periodic discovery, manual add, and app-cache refresh plus live daemon validation
|
|
- [x] 2026-04-14 — Add daemon-backed app control, remote input, state queries, and dev workflows with live Roku CLI validation
|
|
- [x] 2026-04-14 — Add config list/get/set/reset/reload plus systemd user-service install/uninstall commands
|
|
- [x] 2026-04-14 — Finish Milestone 4 with help, JSON-mode, config socket-reload, and secret-redaction polish
|
|
- [x] 2026-04-15 — Add HTTP API route parity and integration coverage against an isolated running daemon
|
|
- [x] 2026-04-15 — Add shell completions and first-run CLI polish for Milestone 6
|
|
- [x] 2026-04-18 — Make runtime tracing respect `daemon.log_level` on daemon start and config reload
|
|
|
|
---
|
|
|
|
## Decision Log
|
|
|
|
Significant decisions made during development should be logged here
|
|
so future agents understand why things are the way they are.
|
|
|
|
| Date | Decision | Reason |
|
|
|------|----------|--------|
|
|
| 2026-04-14 | Full design completed before any code written | Intentional — design-first approach |
|
|
| 2026-04-14 | Samsung deprioritized | Unstable app IDs per region/model make universal support unreliable |
|
|
| 2026-04-14 | No pre-populated app database | Organic cache from live TV data is more accurate and zero-maintenance |
|
|
| 2026-04-14 | Unix socket for CLI, HTTP for tool builders | Clean security boundary, loopback-only by default |
|
|
| 2026-04-14 | User-level systemd service | No root required, correct ownership model |
|
|
| 2026-04-15 | Future remote input options should use a generalized adapter capability model | If multiple adapters need press/release or other delivery semantics, model it as adapter capabilities instead of hard-coding Roku-only behavior |
|