Home is now Overview | My Home | Phone. Overview leads with quick-action tiles (focus, Do Not Disturb, health, snapshots, storage), keeps the findings card — updates fold in, the reclaim-space prompt is gone on purpose — and adds glance cards, the next calendar event, and weather. My Home groups every light by Home Assistant area: the helper gained an `areas` command (one REST template render, no websocket), and the rooms degrade to a flat list on setups without areas. The favorites editor and connection card moved intact. Phone gains a vitals strip — battery and cell signal read from KDE Connect's plugin D-Bus objects, where absence is data, not an error — beside ring, clipboard, send-a-file, and the BlueBubbles handoff. The retired home-phone id resolves to my-home forever via a new alias map in SettingsRoutes (with a hasOwnProperty guard so prototype names cannot leak into settingsPage). Storage no longer claims 0 B free — the old page read a field the disks helper never emitted. Contracts updated alongside; per the new workflow, the full suite runs once at the end of the redesign (see the test backlog note). Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
51 lines
2.6 KiB
Bash
Executable File
51 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
fail() {
|
|
printf 'KDE Connect helper contract: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
helper="$project_root/config/dot/quickshell/scripts/panama-kdeconnect"
|
|
|
|
[[ -x "$helper" ]] || fail 'helper is missing or not executable'
|
|
|
|
status="$($helper status)"
|
|
|
|
# The shape is checked whenever a device is present, but a device being present
|
|
# is not itself required. kdeconnectd drops its device objects for a phone it
|
|
# has not seen recently -- the pairing survives in its config, the D-Bus object
|
|
# does not -- so demanding one makes this fail whenever the phone is off, out of
|
|
# range, or simply has not opened the app today. That is the machine's state,
|
|
# not a defect in the helper.
|
|
jq -e '.available == true and (.devices | type == "array")' <<<"$status" >/dev/null \
|
|
|| fail 'live status is not a readable device list'
|
|
|
|
if [[ "$(jq -r '.devices | length' <<<"$status")" == "0" ]]; then
|
|
printf 'KDE Connect helper contract: PASS (no device visible to the daemon right now; shape checks skipped)\n'
|
|
exit 0
|
|
fi
|
|
|
|
# battery and signal are always present and are null far more often than not:
|
|
# the plugin objects exist only while a device is paired, reachable and has the
|
|
# plugin loaded. Null is the answer, so the check is on the shape when a value
|
|
# is there, never on a value being there.
|
|
jq -e '
|
|
([.devices[] | (keys | sort) == (["actions", "battery", "id", "name", "paired", "reachable", "signal", "type"] | sort)] | all) and
|
|
([.devices[] | (.id | test("^[A-Fa-f0-9]{32,64}$"))] | all) and
|
|
([.devices[].actions[] | . == "clipboard" or . == "ping" or . == "ring" or . == "share"] | all) and
|
|
([.devices[] | select(.battery != null) | (.battery | keys | sort) == ["charge", "charging"]] | all) and
|
|
([.devices[] | select(.battery != null) | .battery.charge >= 0 and .battery.charge <= 100 and (.battery.charging | type == "boolean")] | all) and
|
|
([.devices[] | select(.signal != null) | (.signal | keys | sort) == ["networkType", "strength"]] | all) and
|
|
([.devices[] | select(.signal != null) | .signal.strength >= 0 and (.signal.networkType | type == "string")] | all) and
|
|
([.devices[] | select(.paired and .reachable | not) | .battery == null and .signal == null] | all)
|
|
' <<<"$status" >/dev/null || fail 'live status shape is invalid'
|
|
|
|
paired_count="$(jq '[.devices[] | select(.paired)] | length' <<<"$status")"
|
|
reachable_count="$(jq '[.devices[] | select(.reachable)] | length' <<<"$status")"
|
|
printf 'KDE Connect helper contract: PASS (%s paired, %s reachable; identities redacted)\n' \
|
|
"$paired_count" \
|
|
"$reachable_count"
|