Plugin-based fleet management for the devices around your house —
Fire TV sticks, NVIDIA Shields, PCs — plus the software running on them.
Last verified 2026-08-02
Status: S0–S6 are complete —
fleetctldiscovers devices, captures and rebuilds Kodi profiles, and deploys them over ADB, verified against real Fire TV hardware. S7 (Home Assistant cutover) has not started; seedocs/roadmap.md.
fleetctl separates three things that usually get tangled together:
| Ring | Knows about | Examples |
|---|---|---|
| core | nothing device-specific | transport, inventory, discovery, artifacts, operations, workflows, audit |
| packs | what a device is | firetv, shield, linux_host (planned S8) |
| apps | software on a device | kodi |
Dependencies point inward only. An app pack never imports a device pack — its steps declare the Capability values they need (exec, files, state, ...) and the engine resolves which pack on the target actually provides them. That's what lets one Kodi build deploy to a Fire Stick and a Shield without either knowing the other exists.
flowchart TB
subgraph apps["apps/ — software on a device"]
KODI["kodi"]
end
subgraph packs["packs/ — device types"]
FIRETV["firetv"]
SHIELD["shield"]
LINUX["linux_host (S8)"]
end
subgraph core["core/ — device-agnostic kernel"]
T["transport"]
I["inventory"]
W["workflow"]
O["observability"]
end
apps --> core
packs --> core
KODI -.->|"declares capabilities;<br/>never imports a pack"| packs
classDef a fill:#7c3aed,stroke:#5b21b6,color:#fff
classDef p fill:#ea580c,stroke:#c2410c,color:#fff
classDef c fill:#0d9488,stroke:#0f766e,color:#fff
class KODI a
class FIRETV,SHIELD,LINUX p
class T,I,W,O c
Build status by stage — what exists today vs. what's planned
| Stage | Contents | Status |
|---|---|---|
| S0 | Repo bootstrap, CI, quality gate | ✅ done |
| S1 | Core kernel — transport, artifacts, operations, observability | ✅ done |
| S2 | packs/firetv + apps/kodi, hardware parity |
✅ done |
| S3 | Config-as-code + workflows | ✅ done |
| S4 | Policy engine + audit hardening | ✅ done |
| S5 | packs/shield — validates the seams |
✅ done |
| S6 | MCP adapter | ✅ done |
| S7 | Home Assistant cutover | ⬜ not started |
| S8 | linux_host / SSH, HTTP API if needed |
⬜ not started |
Full detail and ordering constraints: docs/roadmap.md.
Requires Python 3.12+ and uv.
git clone https://github.com/salvuswarez/fleetctl.git
cd fleetctl
uv sync --all-extras
uv run fleetctl --versionThen see docs/getting-started.md for first-run config and pointing it at a real device.
uv sync --all-extras # install everything, including dev tools
uv run pytest # tests (500+)
uv run pytest --cov=src # with coverage (gate: 90%)
uv run black src tests # format
uv run isort src tests # import order
uv run mypy # strict type checking
uv build # wheel + sdistCI runs all of the above on every push and pull request.
Config is YAML and lives under config/, which is gitignored — only *.example files are tracked. Config files hold secret references, never secret values:
artifacts:
smb:
host: 192.168.1.50
user: !ref env:SMB_USER
password: !ref env:SMB_PASS!ref env:NAME resolves against the process environment at load time and is wrapped in a Secret afterward, so a fleet.yml is safe to paste into a bug report. Full field reference: docs/configuration.md.
fleetctl runs destructive operations against real hardware: wiping app profiles, disabling system packages, deploying to every tagged device. Three things keep that honest:
- Effect classification. Every step declares itself
read,mutating, ordestructive. Policy keys off the class, not a list of names. - Protected devices. Devices can be marked off-limits for named steps via config, no code change.
- Audit trail. Every mutating or destructive command is recorded — actor, target, outcome, duration — in an append-only, hash-chained log.
See docs/safety.md and SECURITY.md.
MIT — see LICENSE.
|
fleetctl Overview |
|
|