- Python 61.2%
- Shell 23%
- QML 15.8%
| .github/workflows | ||
| artifacts/visual | ||
| docs | ||
| helper | ||
| package | ||
| tests | ||
| tools | ||
| .gitignore | ||
| ARCHITECTURE.md | ||
| bootstrap-telemetry.sh | ||
| install.sh | ||
| LICENSE | ||
| README.md | ||
| setup-power-client.sh | ||
| setup-power-server.sh | ||
| setup-telemetry-server.sh | ||
archpc status
A compact Plasma 6 panel widget that shows whether archpc (192.168.0.74)
answers one ICMP echo request:
- yellow, gently pulsing — checking
- green — ICMP reply received
- dim gray — no reply, or the local helper reported an error
For a maintainer-oriented description of the complete as-built system, see
ARCHITECTURE.md. It documents the repository map, runtime
contracts, state machines, security boundaries, deployment scripts, test
seams, known limitations and refactor hazards. This README remains the
operator-focused installation and usage guide.
The short document map is in docs/README.md.
It checks at startup, every 60 seconds, and whenever the complete pill is clicked or keyboard-activated. Yellow is shown for at least 500 ms, preventing a fast reply from strobing; a slow check remains yellow until its bounded completion or the widget's 2-second helper deadline. Right-clicking the widget also offers Wake archpc, Suspend archpc, and Shutdown archpc, in that least-to-most disruptive order.
This is ICMP availability only. An HTTP response, HTTP refusal, SSH service, or any other TCP service does not determine the displayed host status.
Architecture
A stock Plasma QML package has no supported process-launch API. The widget
therefore talks to a small Python helper at the fixed loopback endpoint
http://127.0.0.1:47653/status. HTTP is only local IPC. The helper executes the
fixed argument vector:
/usr/bin/ping -4 -n -c 1 -W 1 -w 1 192.168.0.74
It never invokes a shell and accepts no target, command, or query parameter.
The server binds only 127.0.0.1; only GET /status runs a probe; responses are
small, schema-checked JSON. Exit 0 means online, exit 1 means an ordinary no-reply
offline result, and launch failures, other exits, or the independent 1.5-second
process guard are surfaced as helper errors in the tooltip.
The three context-menu actions send empty POST requests to fixed /action/
paths on the same helper. They cannot supply command text. A required custom
header causes web browsers to preflight and the helper rejects OPTIONS, which
prevents an ordinary web page from triggering an action through loopback. The
helper resolves the corresponding executable and starts it directly in a
separate transient systemd user service. The fixed commands are:
wol
wol-suspend
wol-shutdown
They run in the background without opening a terminal. The transient unit is collected when its command exits. No shell is involved.
The helper is installed under ~/.local/lib/archpc-status/ and supervised by
the hardened systemd user unit archpc-status-ping.service. This avoids the
legacy Plasma5Support executable DataEngine: that compatibility engine is a
migration aid, launches shell command text, and is not the reliable long-term
Plasma 6 integration. No base status service is installed on archpc itself.
Optional mode telemetry
The indicator-side telemetry integration is separate from the ICMP pill. It adds three disabled context-menu rows, in this order, followed by a separator and the existing Wake archpc, Suspend archpc, and Shutdown archpc actions:
Mode: …
VRAM: …
Uptime: …
-----------------------
Wake archpc
Suspend archpc
Shutdown archpc
The pill remains ICMP-only. Telemetry refreshes every 10 seconds and when the menu opens or the pill is activated; a sample older than 30 seconds is shown as stale. A remote attempt has a five-second SSH deadline. Slow or failed telemetry therefore cannot change the pill or disable the power actions. Failed collections immediately mark previous values as stale. Mode may also show Switching… or Unknown, and individual metrics may be unavailable.
The optional local configuration is:
${XDG_CONFIG_HOME:-$HOME/.config}/archpc-status/telemetry.json
It contains only a boolean enabled, a validated user, and absolute
identity_file and known_hosts_file paths. The installer passes the
resolved path to the user helper through its owned
ARCHPC_STATUS_TELEMETRY_CONFIG systemd drop-in and preserves this JSON and
the dedicated key on update or uninstall.
Use helper/telemetry.example.json as the
starting point, replacing its example paths and account:
{
"enabled": true,
"user": "archpc-telemetry",
"identity_file": "/home/YOUR_USER/.config/archpc-status/telemetry/id_ed25519",
"known_hosts_file": "/home/YOUR_USER/.config/archpc-status/telemetry/known_hosts"
}
The example is not installed over your configuration. A missing file or
{"enabled":false} disables collection. An enabled configuration requires all
four fields; unknown fields are rejected. Account names must match
[a-z_][a-z0-9_-]{0,31}. Key/known-hosts paths must be absolute and cannot
contain %, $ or control characters. Spaces are supported.
Use a dedicated key restricted on archpc to the read-only collector, with no
sudo, PTY or forwarding permission. Independently verify the host-key fingerprint
before populating the dedicated known-hosts file. The helper never trusts a
new/changed host key automatically and does not inherit your SSH configuration
or agent. Its key must work without a passphrase prompt; protect it with mode
0600 and its directory with 0700. /usr/bin/ssh is required only for enabled
telemetry.
Configuration is loaded at helper startup. After changes, run:
systemctl --user restart archpc-status-ping.service
This indicator functionality can be installed independently. Its rows remain
Unavailable until the separate llm-mode package has installed the fixed
read-only collector at /usr/local/libexec/archpc-telemetry on
192.168.0.74 and the dedicated host-key setup is complete. The target and
remote command are not configurable. The collector package and its exact
machine JSON contract are specified in
docs/reference/LLM_MODE_TELEMETRY_PLAN.md;
this repository does
not install or modify the remote mode controller, profiles, or human
llm-status output.
The independent local endpoint is GET /telemetry with the required header
X-Archpc-Status-Telemetry: 1. It does not alter /status. The helper's
--check-telemetry-server smoke check validates the local telemetry envelope
even when telemetry is disabled or the remote host is offline. No live remote
verification is claimed by this documentation.
Requirements
- KDE Plasma 6.0 or newer
kpackagetool6- Python 3 at
/usr/bin/python3 - Arch
iputils(/usr/bin/ping) wol-suspendandwol-shutdownavailable onPATH- optional: a configured
wolcommand onPATHfor Wake-on-LAN - a working systemd user manager (
systemctl --userand/usr/bin/systemd-run) - permission for the normal unprivileged
pinginvocation
Port 127.0.0.1:47653 must be free. Installation fails clearly if dependencies,
ping permissions, the user service, or its protocol smoke test fail. A missing
wol produces a warning but does not block installation. The Wake menu entry
remains visible; selecting it without wol reports that the command is missing.
For a complete new-client installation of the widget, suspend/shutdown and
telemetry without Wake-on-LAN, follow
docs/INSTALL_CLIENT.md.
Set up suspend and shutdown commands
If the new desktop does not already have wol-suspend and wol-shutdown, use
the standalone setup-power-client.sh and setup-power-server.sh installers.
The ordered instructions are in docs/POWER_ACTIONS.md.
They create a separate archpc-power account with a forced SSH dispatcher and
sudo permission for only the exact suspend/poweroff commands. They never grant
power permissions to the read-only telemetry account.
Start on the desktop, as your normal user:
./setup-power-client.sh prepare
./setup-power-client.sh prepare --apply
export PATH="$HOME/.local/bin:$PATH"
Authorise the printed public key on archpc using the server script, then run
the client's finish phase with the server's verified host-key fingerprint.
Preview is the default; --apply is required for changes. Neither installer
executes a power action during setup. The optional wol wake command remains
separate, and these installers do not install the widget itself.
Install, update, and uninstall
Run as the logged-in desktop user, never with sudo:
./install.sh
For a fresh Plasma 6 desktop, the optional bootstrap script prepares the
dedicated client key and installs the widget without requiring any
administrative access to archpc. The step-by-step multi-client instructions
are in docs/ADD_CLIENT.md. Preview and then apply the
client preparation:
./bootstrap-telemetry.sh prepare
./bootstrap-telemetry.sh prepare --apply
Transfer the printed .pub file to archpc. On archpc, use the separate
setup-telemetry-server.sh with the telemetry release archive, its adjacent
.sha256 file and that public key. Preview it as the server user, then apply it
through sudo:
./setup-telemetry-server.sh \
--archive /absolute/path/to/llm-mode-package-telemetry.tar.gz \
--client-key /absolute/path/to/id_ed25519.pub \
--client-name MY_CLIENT
sudo ./setup-telemetry-server.sh \
--archive /absolute/path/to/llm-mode-package-telemetry.tar.gz \
--client-key /absolute/path/to/id_ed25519.pub \
--client-name MY_CLIENT --apply
Copy the SHA256:... host-key fingerprint printed by the server script back
to the client. Preview and apply the finish phase:
./bootstrap-telemetry.sh finish \
--host-key-fingerprint SHA256:REPLACE_WITH_SERVER_OUTPUT
./bootstrap-telemetry.sh finish \
--host-key-fingerprint SHA256:REPLACE_WITH_SERVER_OUTPUT --apply
The server script adds each uniquely named client's restricted key without
removing existing clients. It never runs the full llm-mode installer or
changes profiles, mode or the default target. Existing unmanaged SSH policy,
unrestricted keys, changed host-key pins and unsafe paths cause a refusal
rather than being overwritten. Run the client script as the current Plasma
user, never with sudo. An optional --client-address IP on the server
command checks the effective SSH policy for that actual client IP; the
matching archive and sidecar alone do not establish archive provenance.
The shared non-mutating ./install.sh check preflight is used before client
preparation. If a later finish step fails after publishing telemetry
configuration, the previous client configuration is restored and the helper
is restarted with it, or stopped if that restart fails.
Then enter panel edit mode, choose Add Widgets…, search for archpc, and add
it. The installer performs a fixed ping smoke test, installs/starts the helper,
validates its loopback response, and then installs or upgrades the plasmoid.
It is idempotent.
After updating repository files:
./install.sh update
This replaces and restarts the helper before upgrading the widget. If an open panel does not reload, remove/add the widget or sign out and back in.
Remove panel instances first, then remove both widget and helper:
./install.sh uninstall
Uninstall stops/disables the user unit before deleting only this project's unit, helper, and Plasma package. This repository's test environment does not run the installer or start a persistent service.
Release interface and dependencies
The public installer interface is ./install.sh --help or
./install.sh -h, followed by install, update, upgrade, or
uninstall, plus the non-mutating check preflight.
The telemetry scripts remain dependency-light. Preview is the default and
--apply is required for changes. Apply-time prerequisites must be checked at
the point where they are used, rather than making a read-only preview depend
on credentials, a live host, or administrative access. Relative
XDG_CONFIG_HOME values are rejected by the release interface.
The tools/run_tests.sh interface is:
tools/run_tests.sh --help
tools/run_tests.sh --core-only # no Qt
tools/run_tests.sh # full suite
The .github/workflows/ci.yml workflow defines read-only automation checks for
the core and Qt suites. Hosted CI execution remains unverified by this
documentation.
Useful diagnostics on an installed desktop:
systemctl --user status archpc-status-ping.service
journalctl --user -u archpc-status-ping.service
/usr/bin/python3 ~/.local/lib/archpc-status/pingd.py --check-server
/usr/bin/python3 ~/.local/lib/archpc-status/pingd.py --check-telemetry-server
Interaction and accessibility
The tooltip distinguishes an online ICMP reply, a normal no-reply result, and a meaningful helper/transport/protocol error, and includes the last completion time. It also reports a failed background action request. Mouse click, Enter, and Space refresh immediately; a manual refresh resets the 60-second cadence. Starting a new check invalidates the old request and both of its timers, so stale replies cannot overwrite it. The full pill exposes a button role and accessibility press action.
Colors use Kirigami semantic theme roles. Core and halo diameters are rounded to
matching odd device-pixel parity and share a snapped center; the indicator and
actual label are vertically centered by RowLayout. This avoids half-pixel
core/halo disagreement on odd panel dimensions and 1x/2x scaling. The complete
pill rotates on vertical panels.
Test
The deterministic suite never pings the LAN target. It mocks all documented
ping exits plus timeout/missing executable, tests the fixed loopback API,
checks helper errors and malformed responses, the fixed and browser-resistant
host-action API, background argument vectors, startup/periodic/click behavior,
500 ms minimum display, slow/timeout behavior, stale requests, Plasma 6 QML
compilation, odd-dimension geometry, package policy, and installer lifecycle.
Telemetry tests cover the SSH contract, process/output limits, single-flight
cache, partial failures, freshness, menu ordering, menu/click refresh and
independence from ping and power actions. Installer tests use a temporary home
and fake service/package commands, never the real user manager or LAN target.
A pinned Qt 6.8 runtime can be installed only under ignored .tools/:
tools/bootstrap_test_env.sh
tools/run_tests.sh
For the stripped Debian container, tools/bootstrap_debian_container.sh
extracts required libraries only under .tools/. Also check shell/Python syntax:
python3 -m py_compile helper/*.py tools/*.py tests/*.py
For shell syntax and ShellCheck, include every root and tools/ entrypoint and
use each file's declared interpreter:
for script in ./*.sh tools/*.sh; do
case "$(sed -n '1p' "$script")" in
'#!/bin/sh'|'#!/usr/bin/env sh') sh -n "$script" ;;
'#!/bin/bash'|'#!/usr/bin/env bash') bash -n "$script" ;;
*) printf 'Unsupported shell shebang: %s\n' "$script" >&2; exit 1 ;;
esac
shellcheck "$script"
done
Visual verification
tools/render_visuals.sh
tools/render_visuals.sh --telemetry-only
The representative artifacts/visual/status-sheet.png
loads the production StatusPill.qml directly. Dedicated
geometry-odd-1x.png and geometry-odd-2x.png renders use an odd 169×81 logical
canvas for pixel inspection. These are real Qt Quick offscreen software renders,
not HTML mockups, but they cannot reproduce a particular Plasma compositor,
theme, or physical display. See artifacts/visual/README.md.
The telemetry state sheet renders the
production action text in a test menu. It is not a native Plasma menu screenshot.
References
- KDE Plasma widget setup
- KDE Plasma 6 porting
- KDE plasma5support
- Arch
ping(8) - systemd user services
- Qt QML XMLHttpRequest
License
MIT — see LICENSE.
