# 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-14 --- ## Current Focus **Milestone 2 — Roku Adapter** Foundation scaffold is complete. Begin platform implementation work. --- ## In Progress - Roku adapter `dev_install()` and `dev_logs()` need developer-web credential handling plus real-device validation --- ## 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 - [ ] `dev_install()` — zip upload via ECP dev mode - [x] 2026-04-14 — `dev_reload()` — reload the sideloaded app via `launch/dev` - [ ] `dev_logs()` — fetch dev logs - [x] 2026-04-14 — Key translation table (TvKey → Roku ECP key string) - [ ] Manual integration test against real Roku device --- ## Milestone 3 — Daemon Core _Goal: tvctld runs, manages devices, and handles the Unix socket._ - [ ] Daemon entry point and lifecycle (`src/daemon/mod.rs`) - [ ] Unix socket listener - [ ] Device registry (`src/daemon/registry.rs`) - Load from `devices.json` on start - Persist on change - CRUD operations - [ ] Discovery service (`src/daemon/discovery.rs`) - SSDP scan - Auto-discover on startup (if configured) - Interval-based re-scan - Manual add by IP - [ ] App cache manager (`src/daemon/cache.rs`) - Per-platform JSON files - Organic growth strategy - `app refresh` invalidation - [ ] State cache (`src/daemon/state.rs`) - In-memory only - Per-device last-known state - Timestamp on every entry - [ ] Adapter registry (map platform string → adapter instance) - [ ] Config loading from TOML --- ## Milestone 4 — CLI _Goal: All tvctl commands work against a running daemon._ - [ ] CLI entry point and dispatch (`src/cli/mod.rs`) - [ ] Unix socket client (send commands, receive responses) - [ ] `tvctl daemon` commands - `start` `stop` `restart` `status` - `install` (generate systemd user unit) - `uninstall` - [ ] `tvctl device` commands - `list` `discover` `add` `select` `info` `remove` - [ ] `tvctl app` commands - `list` `launch` `stop` `refresh` - [ ] `tvctl remote` commands - `key` `sequence` - [ ] `tvctl state` - [ ] `tvctl dev` commands - `install` `reload` `logs` - [ ] `tvctl config` commands - `list` `get` `set` `reset` `reload` - [ ] Global flags: `--device` `--json` `--help` `--version` - [ ] Full help text on every command (see AGENT.md definition of done) - [ ] Full help output on bare `tvctl` - [ ] Friendly error messages with hints on every failure path - [ ] `--json` output verified on every command --- ## Milestone 5 — HTTP API _Goal: Full /v1/ API running on 127.0.0.1:7272._ - [ ] axum server setup in `src/api/mod.rs` - [ ] All routes implemented (see PROJECT_MAP.md API surface) - [ ] Standard response envelope on all routes - [ ] Error responses with `code` + `message` + `hint` - [ ] Device addressable by UUID or friendly name on all routes - [ ] `PATCH /v1/config` with partial update support - [ ] `POST /v1/config/reload` triggers live config reload in daemon - [ ] Integration test: curl all endpoints against running daemon --- ## Milestone 6 — Polish and Release Prep _Goal: Ready for real use._ - [ ] Shell completions (bash, zsh, fish) via clap - [ ] `tvctl daemon install` generates correct systemd unit file - [ ] First-run experience: helpful output when no devices discovered yet - [ ] Daemon startup message with socket path and HTTP port - [ ] Log output via `tracing` (respects `log_level` config) - [ ] README accuracy pass (verify all examples work) - [ ] `cargo clippy` clean - [ ] `cargo test` passing - [ ] Cross-compile test (x86_64 + aarch64) - [ ] GitHub Actions CI (build + clippy + test) - [ ] 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 --- ## 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 |