huskies: progress 983 — differentiated icons for stuck-story states

Distinct icons in StagePanel/GatewayPanel/render.rs status output for
blocked-with-running-recovery (robot), blocked-with-queued-recovery (hourglass),
and blocked-cold (red circle). All 2822 tests pass.
This commit is contained in:
Timmy
2026-05-13 15:46:36 +01:00
parent 14a39b6205
commit c811672e18
3 changed files with 202 additions and 35 deletions
+29 -3
View File
@@ -233,13 +233,27 @@ fn render_item_line(
item.stage,
Stage::Merge { .. } | Stage::MergeFailure { .. } | Stage::MergeFailureFinal { .. }
) {
// MergeFailure and MergeFailureFinal carry their reason directly on
// the stage variant — always show ⛔ with the failure snippet.
match &item.stage {
Stage::MergeFailure { reason, .. } | Stage::MergeFailureFinal { reason } => {
// MergeFailureFinal: mergemaster already tried and gave up — always ⛔.
Stage::MergeFailureFinal { reason } => {
let snippet = first_non_empty_snippet(reason, 120);
return format!(" \u{26D4} {display}{cost_suffix}{dep_suffix}{snippet}\n");
}
// MergeFailure: a recovery agent may be running or queued.
Stage::MergeFailure { reason, .. } => {
return match agent.map(|a| &a.status) {
Some(AgentStatus::Running) => format!(
" \u{1F916} {display}{cost_suffix}{dep_suffix} — mergemaster running\n"
),
Some(AgentStatus::Pending) => format!(
" \u{23F3} {display}{cost_suffix}{dep_suffix} — mergemaster queued\n"
),
_ => {
let snippet = first_non_empty_snippet(reason, 120);
format!(" \u{26D4} {display}{cost_suffix}{dep_suffix}{snippet}\n")
}
};
}
_ => {}
}
@@ -264,6 +278,18 @@ fn render_item_line(
}
let blocked = item.stage.is_blocked();
// Blocked items with a recovery agent get differentiated indicators.
if blocked {
return match agent.map(|a| &a.status) {
Some(AgentStatus::Running) => {
format!(" \u{1F916} {display}{cost_suffix}{dep_suffix} — recovery coder running\n")
}
Some(AgentStatus::Pending) => {
format!(" \u{23F3} {display}{cost_suffix}{dep_suffix} — recovery coder queued\n")
}
_ => format!(" \u{1F534} {display}{cost_suffix}{dep_suffix}\n"),
};
}
let throttled = agent.map(|a| a.throttled).unwrap_or(false);
let dot = super::traffic_light_dot(blocked, throttled, agent.is_some());
if let Some(agent) = agent {