# AGENTS.md ## Project Overview Camper Widget is a Plasma 6 applet displaying real-time camper van energy system data (battery, solar, AC input/load power). It consists of two components: 1. **Widget** (`package/`) - Pure QML KPackage using `org.kde.plasma.workspace.dbus` for D-Bus property subscriptions 2. **Background Service** (`service/`) - Rust async service that reads Victron MQTT data and publishes it over D-Bus (`org.craftknight.CamperWidget`) ## Commands All commands use [just](https://just.systems/man/en/introduction.html): | Command | Description | |---|---| | `just build` | Build service (release) — widget is pure QML, no compilation | | `just check` | Format check + clippy + cargo check (service) | | `just test` | Run Rust tests (service) | | `just verify` | Run check + build | | `just fmt` | Format Rust code (service) | | `just install` | Install widget (kpackagetool6) + service | | `just install-widget` | Install/update widget via kpackagetool6 | | `just install-service` | Build and install systemd service | | `just uninstall` | Uninstall widget + clean old artifacts | | `just run` | Run applet in plasmoidviewer | | `just run-service` | Run service (release) | | `just build-service` | Build service only | | `just check-service` | Check service only | | `just check-deps` | Print versions of required tools | | `just ci` | Full CI pipeline (check + test) | | `just ci-quick` | Quick CI (check only, no build/test) | | `just clean` | Delete build artifacts | ## Architecture ``` package/ ├── metadata.json # KPackage metadata (installed via kpackagetool6) ├── contents/ui/ # QML UI (main, compact, full representations) │ ├── main.qml # D-Bus bindings via org.kde.plasma.workspace.dbus │ ├── CompactRepresentation.qml │ ├── FullRepresentation.qml │ ├── ConfigGeneral.qml # KCM config page │ ├── IconUtils.qml # Battery/direction icon helpers │ └── FormatUtils.qml # Value formatting helpers └── contents/config/ # KCM config schema service/ ├── config/ │ └── camper-widget-refresh.service # systemd user unit └── src/ ├── main.rs # Entry point, tokio async runtime ├── lib.rs # Public module exports ├── dbus.rs # D-Bus server (zbus), property signals ├── victron_mqtt.rs # MQTT client reading Victron energy data ├── cache.rs # Serial number caching └── config.rs # Plasma INI config loading/watching tests/qml/ # QML unit tests for utility components ``` **Key patterns:** - Widget is a pure QML KPackage — no compilation, installed via `kpackagetool6` - Widget uses `org.kde.plasma.workspace.dbus` (`DBus.Properties`, `DBus.DBusServiceWatcher`) to subscribe to D-Bus property changes (requires Plasma 6.3+) - Service uses `tokio` async runtime with `zbus` 5 and `rumqttc` - D-Bus interface: `org.craftknight.CamperWidget` on session bus, with separate object paths per subsystem (Battery, Solar, AcInput, AcLoad) - Config read from Plasma applet INI (`~/.config/plasma-org.kde.plasma.desktop-appletsrc`), configured via widget's KCM settings page ## Conventions - Rust 2021 edition, standard `cargo fmt` + `clippy` formatting - QML for Plasma UI components - Config via Plasma KCM (stored in Plasma applet INI) - `just` as the task runner (not make) ## Commit Rules **IMPORTANT:** Before completing any task, you MUST run `/commit` to commit your changes. - Only commit files YOU modified in this session — never commit unrelated changes - Use atomic commits with descriptive messages - If there are no changes to commit, skip this step - Do not push unless explicitly asked - Always run `just check` before committing to catch formatting/lint issues - Use `git add` + `git commit` — **never** use `git restore` during the commit workflow