- {hasMergeFailure && (
-
- ✕
-
- )}
+ {hasMergeFailure && (() => {
+ const agentStatus = item.agent?.status;
+ if (agentStatus === "running") {
+ return (
+
+ ⟳
+
+ );
+ }
+ if (agentStatus === "pending") {
+ return (
+
+ ⏳
+
+ );
+ }
+ return (
+
+ ✕
+
+ );
+ })()}
{mergesInFlight?.has(item.story_id) && (
)}
- {item.blocked && !item.merge_failure && (
-
- ⊘ BLOCKED
-
- )}
+ {item.blocked && !item.merge_failure && (() => {
+ const agentStatus = item.agent?.status;
+ if (agentStatus === "running") {
+ return (
+
+ ⟳ RECOVERING
+
+ );
+ }
+ if (agentStatus === "pending") {
+ return (
+
+ ⏳ QUEUED
+
+ );
+ }
+ return (
+
+ ⊘ BLOCKED
+
+ );
+ })()}
{item.frozen && (
{
+ // 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 {