Finish the wonderland: System told truthfully, in eight tabs instead of ten

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 23:31:52 -04:00
parent 9ffaf45a4d
commit be0e55214b
57 changed files with 5040 additions and 925 deletions
+61 -11
View File
@@ -200,6 +200,10 @@ CHECK_TITLES = {
"integration.bluebubbles": "BlueBubbles",
"integration.home-assistant": "Home Assistant",
"integration.calendar": "Calendar",
# Every id in CHECK_ORDER needs an entry here: unavailable_check() looks the
# title up by id, so a missing one turned a probe that merely timed out into
# a KeyError that took the whole scan down with it.
"panama.updates": "Software updates",
"panama.runtime-links": "Panama runtime links",
"panama.vicinae-commands": "Panama commands",
"panama.selected-terminal": "Selected terminal",
@@ -294,6 +298,14 @@ def check_json(check: Check) -> dict[str, object]:
result: dict[str, object] = {"id": check.id, "group": check.group, "title": check.title, "status": check.status, "detail": check.detail}
if check.action is not None:
result["action"] = action_json(check.action)
# The exact command a repair would run, so the page can show it before
# anybody presses the button. Taken from REPAIR_COMMANDS rather than
# written out again in the UI -- a second copy is a copy that can be wrong,
# and the whole point of showing it is that it is what actually happens.
# Only the authored-command repairs have one; the three in-process repairs
# are Python, not a command line, and claiming otherwise would be a lie.
if check.id in REPAIR_COMMANDS:
result["repairCommand"] = " ".join(REPAIR_COMMANDS[check.id])
return result
@@ -659,14 +671,14 @@ def check_updates(config: DoctorConfig) -> Check:
if newest != running:
return Check("panama.updates", "panama-tools", "Software updates", "warning",
f"A newer kernel is installed than the one running ({running} → {newest}). Restart to use it.",
action=Action("open", "Open Software Update"))
action=Action("open", "Open Software Update", target="updates"))
try:
payload = json.loads(cache.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
return Check("panama.updates", "panama-tools", "Software updates", "unconfigured",
"Updates have not been checked yet.",
action=Action("open", "Open Software Update"))
action=Action("open", "Open Software Update", target="updates"))
checked_at = int(payload.get("checkedAt", 0))
age_days = (time.time() - checked_at) / 86400 if checked_at else 999
@@ -677,11 +689,11 @@ def check_updates(config: DoctorConfig) -> Check:
if security > 0:
return Check("panama.updates", "panama-tools", "Software updates", "warning",
f"{security} pending update{'' if security == 1 else 's'} carry a security advisory.",
action=Action("open", "Open Software Update"))
action=Action("open", "Open Software Update", target="updates"))
if age_days > 7:
return Check("panama.updates", "panama-tools", "Software updates", "unconfigured",
"Updates have not been checked in over a week.",
action=Action("open", "Open Software Update"))
action=Action("open", "Open Software Update", target="updates"))
if total > 0:
return Check("panama.updates", "panama-tools", "Software updates", "ok",
f"{total} update{'' if total == 1 else 's'} available, none carrying a security advisory.")
@@ -799,14 +811,18 @@ def unavailable_versions() -> list[dict[str, str]]:
return [{"id": name, "version": "unavailable"} for name in ("hyprland", "quickshell", "fedora", "panama")]
def collect_checks(config: DoctorConfig) -> list[Check]:
probes: dict[str, Callable[[], Check]] = {
def probe_table(config: DoctorConfig) -> dict[str, Callable[[], Check]]:
return {
"desktop.hyprland": lambda: check_hyprland(config), "desktop.quickshell": lambda: check_quickshell(config), "desktop.notifications": lambda: check_notifications(config), "desktop.portals": lambda: check_portals(config), "desktop.portal-stability": lambda: check_portal_stability(config), "desktop.document-portal": lambda: check_document_portal(config),
"desktop.hyprpaper": lambda: service_check("desktop.hyprpaper", "Hyprpaper", "hyprpaper", config, Action("repair", "Restart Hyprpaper")), "desktop.hypridle": lambda: service_check("desktop.hypridle", "Hypridle", "hypridle", config, Action("repair", "Restart Hypridle")), "desktop.hyprlock": lambda: check_hyprlock(config), "desktop.vicinae": lambda: service_check("desktop.vicinae", "Vicinae", "vicinae", config, Action("repair", "Restart Vicinae")), "input.pipewire": lambda: service_check("input.pipewire", "PipeWire", "pipewire", config),
"input.clipboard": lambda: simple_ipc_check("input.clipboard", "Clipboard", "clipboard", config), "input.wallpaper": lambda: simple_ipc_check("input.wallpaper", "Wallpaper", "wallpaper", config), "input.video-wallpaper": lambda: check_video_wallpaper(config), "input.capture": lambda: simple_ipc_check("input.capture", "Capture", "capture", config), "input.ocr": lambda: executable_check("input.ocr", "OCR", "tesseract", config), "input.brightness": lambda: check_brightness(config),
"integration.nextcloud": lambda: check_nextcloud(config), "integration.rustdesk": lambda: check_rustdesk(config), "integration.kdeconnect": lambda: check_kdeconnect(config), "integration.bluebubbles": lambda: check_bluebubbles(config), "integration.home-assistant": lambda: check_home_assistant(config), "integration.calendar": lambda: check_calendar(config),
"panama.updates": lambda: check_updates(config), "panama.runtime-links": lambda: check_runtime_links(config), "panama.vicinae-commands": lambda: check_vicinae_commands(config), "panama.selected-terminal": lambda: executable_check("panama.selected-terminal", "Selected terminal", "kitty", config), "panama.selected-launcher": lambda: executable_check("panama.selected-launcher", "Selected launcher", "vicinae", config), "panama.processes": lambda: check_processes(config), "panama.caffeine": lambda: check_caffeine(config),
}
def collect_checks(config: DoctorConfig) -> list[Check]:
probes = probe_table(config)
with ThreadPoolExecutor(max_workers=8) as executor:
futures = {check_id: executor.submit(probes[check_id]) for check_id in CHECK_ORDER}
checks: list[Check] = []
@@ -818,11 +834,7 @@ def collect_checks(config: DoctorConfig) -> list[Check]:
return checks
def snapshot(config: DoctorConfig) -> dict[str, object]:
try:
checks = collect_checks(config)
except Exception:
checks = [unavailable_check(check_id) for check_id in CHECK_ORDER]
def snapshot_of(config: DoctorConfig, checks: list[Check]) -> dict[str, object]:
counts = {status: sum(check.status == status for check in checks) for status in ("ok", "warning", "error", "unconfigured")}
overall: Literal["healthy", "warning", "error"] = "error" if counts["error"] else "warning" if counts["warning"] else "healthy"
session = "hyprland" if "hyprland" in os.environ.get("XDG_CURRENT_DESKTOP", "").casefold() else "other"
@@ -833,6 +845,30 @@ def snapshot(config: DoctorConfig) -> dict[str, object]:
return {"schemaVersion": 1, "generatedAt": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"), "summary": {"status": overall, "healthy": counts["ok"], "warnings": counts["warning"], "errors": counts["error"], "unconfigured": counts["unconfigured"]}, "context": {"session": session, "versions": versions}, "checks": [check_json(check) for check in checks]}
def snapshot(config: DoctorConfig) -> dict[str, object]:
try:
checks = collect_checks(config)
except Exception:
checks = [unavailable_check(check_id) for check_id in CHECK_ORDER]
return snapshot_of(config, checks)
def single_check(check_id: str, config: DoctorConfig) -> dict[str, object]:
"""One probe, in the shape of a whole snapshot.
Re-checking a single row after a repair should not cost the other
twenty-nine probes. The reply is the same envelope a full scan produces --
same schema, same summary arithmetic, same check object -- so the caller
validates it with the code it already has, rather than growing a second
reader for a second shape that could drift from the first.
"""
try:
checks = [probe_table(config)[check_id]()]
except Exception:
checks = [unavailable_check(check_id)]
return snapshot_of(config, checks)
def repair_authored_command(check_id: str, config: DoctorConfig) -> RepairResult:
command = REPAIR_COMMANDS[check_id]
if check_id == "desktop.quickshell":
@@ -1139,8 +1175,22 @@ def main(argv: list[str]) -> int:
output.add_argument("--json", action="store_true")
output.add_argument("--summary", action="store_true")
parser.add_argument("--repair", metavar="CHECK_ID")
parser.add_argument("verb", nargs="*", metavar="check CHECK_ID",
help="check CHECK_ID -- re-run one probe and print it as a snapshot")
args = parser.parse_args(argv)
if args.verb:
# An unknown id is refused rather than answered with an empty snapshot:
# a caller that asked for a check that does not exist has a bug, and a
# valid-looking reply with no rows in it would hide it.
if len(args.verb) != 2 or args.verb[0] != "check" or args.verb[1] not in CHECK_ORDER:
parser.error("usage: panama-doctor check CHECK_ID")
if args.repair is not None or args.summary:
parser.error("check takes no other output mode")
print(json.dumps(single_check(args.verb[1], config_from_environment()),
separators=(",", ":"), sort_keys=False))
return 0
if args.repair is not None:
if args.repair not in REPAIR_IDS or args.summary:
result = RepairResult(args.repair, False, 2, "This health check has no authored repair.")