From 4e68176492cf37161fdc84e94169dae6f40aeb84 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 24 Aug 2026 22:10:15 +0200 Subject: [PATCH] fix(cli): correct task status keys in statehub status cmd_status read tasks['in_progress'] and tasks['blocked']; the task vocabulary is wait|todo|progress|done|cancel and the totals block never carried those two keys, so the command always raised KeyError. Also accept either the workplans or legacy workstreams totals key, and print the resolved API base so the operator can see which hub instance answered. Refs CUST-WP-0067-T01 Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006 --- custodian_cli.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/custodian_cli.py b/custodian_cli.py index 56b7fe6..361a1ec 100644 --- a/custodian_cli.py +++ b/custodian_cli.py @@ -560,10 +560,16 @@ def cmd_status(_args: argparse.Namespace) -> None: print(f"API: {health.get('status', '?')} DB: {health.get('db', '?')}") summary = _api_get("/state/summary") t = summary["totals"] - print(f"Topics: {t['topics']['active']} active") - print(f"Workstreams: {t['workstreams']['active']} active, {t['workstreams']['blocked']} blocked") - print(f"Tasks: {t['tasks']['in_progress']} in-progress, {t['tasks']['todo']} todo, {t['tasks']['blocked']} blocked") - print(f"Decisions: {t['decisions']['open']} open, {t['decisions']['escalated']} escalated") + topics = t.get("topics", {}) + workplans = t.get("workplans") or t.get("workstreams", {}) + tasks = t.get("tasks", {}) + decisions = t.get("decisions", {}) + print(f"API base: {API_BASE}") + print(f"Topics: {topics.get('active', 0)} active") + print(f"Workplans: {workplans.get('active', 0)} active, {workplans.get('blocked', 0)} blocked") + # Task statuses are wait|todo|progress|done|cancel (see workplan-convention.md). + print(f"Tasks: {tasks.get('progress', 0)} in-progress, {tasks.get('todo', 0)} todo, {tasks.get('wait', 0)} waiting") + print(f"Decisions: {decisions.get('open', 0)} open, {decisions.get('escalated', 0)} escalated") blocking = summary.get("blocking_decisions", []) if blocking: print(f"\nBlocking decisions ({len(blocking)}):")