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.
8.5 KiB
8.5 KiB
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.
- 2026-04-14 — Implement core Roku ECP adapter in
src/adapters/roku/ - 2026-04-14 —
discover()— SSDP scan returning Roku devices - 2026-04-14 —
list_apps()— fetch installed channel list via ECP - 2026-04-14 —
launch()— launch app by ECP channel ID - 2026-04-14 —
stop_app()— exit current app - 2026-04-14 —
key()— send ECP keypress - 2026-04-14 —
sequence()— send multiple keypresses - 2026-04-14 —
state()— query power state and active app - 2026-04-14 —
dev_install()— zip upload via ECP developer web installer with Digest auth - 2026-04-14 —
dev_reload()— reload the sideloaded app vialaunch/dev - 2026-04-14 —
dev_logs()— fetch BrightScript debugger output from the live dev socket - 2026-04-14 — Key translation table (TvKey → Roku ECP key string)
- 2026-04-14 — Automated live validation against
58" Hisense Roku TVat10.10.0.136
Milestone 3 — Daemon Core
Goal: tvctld runs, manages devices, and handles the Unix socket.
- 2026-04-14 — Daemon entry point and lifecycle (
src/daemon/mod.rs) - 2026-04-14 — Unix socket listener
- 2026-04-14 — Device registry (
src/daemon/registry.rs)- Load from
devices.jsonon start - Persist on change
- CRUD operations
- Load from
- 2026-04-14 — Discovery service (
src/daemon/discovery.rs)- SSDP scan
- Auto-discover on startup (if configured)
- Interval-based re-scan
- Manual add by IP
- 2026-04-14 — App cache manager (
src/daemon/cache.rs)- Per-platform JSON files
- Organic growth strategy
app refreshinvalidation
- 2026-04-14 — State cache (
src/daemon/state.rs)- In-memory only
- Per-device last-known state
- Timestamp on every entry
- 2026-04-14 — Adapter registry (map platform string → adapter instance)
- 2026-04-14 — Config loading from TOML
Milestone 4 — CLI
Goal: All tvctl commands work against a running daemon.
- 2026-04-14 — CLI entry point and dispatch (
src/cli/mod.rs) - 2026-04-14 — Unix socket client (send commands, receive responses)
- 2026-04-14
tvctl daemoncommandsstartstoprestartstatusinstall(generate systemd user unit)uninstall
- 2026-04-14
tvctl devicecommandslistdiscoveraddselectinforemove
tvctl appcommands- 2026-04-14
listlaunchstoprefresh
- 2026-04-14
tvctl remotecommands- 2026-04-14
keysequence
- 2026-04-14
- 2026-04-14
tvctl state - 2026-04-14
tvctl devcommandsinstallreloadlogs
- 2026-04-14
tvctl configcommandslistgetsetresetreload
- 2026-04-14 Global flags:
--device--json--help--version - 2026-04-14 Full help text on every command (see AGENT.md definition of done)
- 2026-04-14 Full help output on bare
tvctl - 2026-04-14 Friendly error messages with hints on every failure path
- 2026-04-14
--jsonoutput verified on every command
Milestone 5 — HTTP API
Goal: Full /v1/ API running on 127.0.0.1:7272.
- 2026-04-15 — axum server setup in
src/api/mod.rs - 2026-04-15 — All routes implemented (see PROJECT_MAP.md API surface)
- 2026-04-15 — Standard response envelope on all routes
- 2026-04-15 — Error responses with
code+message+hint - 2026-04-15 — Device addressable by UUID or friendly name on all routes
- 2026-04-15 —
PATCH /v1/configwith partial update support - 2026-04-15 —
POST /v1/config/reloadtriggers live config reload in daemon - 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.
- 2026-04-15 — Shell completions (bash, zsh, fish) via clap
- 2026-04-18 —
tvctl daemon installgenerates correct systemd unit file - 2026-04-15 — First-run experience: helpful output when no devices discovered yet
- 2026-04-15 — Daemon startup message with socket path and HTTP port
- 2026-04-18 — Log output via
tracing(respectslog_levelconfig) - 2026-04-15 — README accuracy pass (verify all examples work)
- 2026-04-15 —
cargo clippyclean - 2026-04-15 —
cargo testpassing - 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 logsstreaming (currently returns last N lines only)- macOS support (launchd instead of systemd)
Completed
- 2026-04-14 — Initialize Cargo workspace (
cargo init) - 2026-04-14 — Add baseline dependencies to
Cargo.toml - 2026-04-14 — Create module skeleton and placeholder docs layout
- 2026-04-14 — Define the adapter contract and core shared data types
- 2026-04-14 — Compile the project cleanly with
cargo build - 2026-04-14 — Add Roku ECP discovery, input, app, and state adapter support with unit tests
- 2026-04-14 — Add env-gated live Roku integration tests and validate against the Hisense TV on the LAN
- 2026-04-14 — Implement Roku developer-mode install/log support and validate sideloading on the Hisense TV
- 2026-04-14 — Add daemon config loading, runtime paths, persisted registry/cache stores, and discovery foundations
- 2026-04-14 — Add daemon Unix socket IPC plus working
daemonanddevicelifecycle/discovery commands - 2026-04-14 — Finish Milestone 3 with registry CRUD, periodic discovery, manual add, and app-cache refresh plus live daemon validation
- 2026-04-14 — Add daemon-backed app control, remote input, state queries, and dev workflows with live Roku CLI validation
- 2026-04-14 — Add config list/get/set/reset/reload plus systemd user-service install/uninstall commands
- 2026-04-14 — Finish Milestone 4 with help, JSON-mode, config socket-reload, and secret-redaction polish
- 2026-04-15 — Add HTTP API route parity and integration coverage against an isolated running daemon
- 2026-04-15 — Add shell completions and first-run CLI polish for Milestone 6
- 2026-04-18 — Make runtime tracing respect
daemon.log_levelon 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 |