feat: queue tickets with dependency context

This commit is contained in:
2026-08-24 13:40:33 +09:00
parent d69c367285
commit 379ae214fc
9 changed files with 101 additions and 124 deletions
+1 -1
View File
@@ -462,7 +462,7 @@ pub(super) fn panel_ticket_detail(row: &PanelRow) -> String {
.as_ref()
.and_then(|ticket| ticket.blocked_reason.as_deref())
{
parts.push(format!("Gate: waiting for {blocked_reason}"));
parts.push(format!("Dependencies: {blocked_reason}"));
} else {
parts.push("Gate: clear".to_string());
}
+7 -8
View File
@@ -1846,24 +1846,23 @@ fn panel_orchestration_overlay_uses_compact_status_column_and_detail_line() {
}
#[test]
fn ready_ticket_with_waiting_gate_shows_queue_disabled_reason() {
fn ready_ticket_with_dependency_context_keeps_queue_action_available() {
let mut row = panel_test_ticket_row(
"00001WAITING",
"Ready but gated",
ActionPriority::Background,
NextUserAction::Wait,
"Ready with dependency context",
ActionPriority::ReadyForQueue,
NextUserAction::Queue,
"ready",
);
row.disabled_reason = Some("Queue disabled: waiting for BLOCKER-1".to_string());
row.ticket.as_mut().unwrap().blocked_reason = Some("BLOCKER-1 via depends_on".to_string());
let lines = panel_row_lines(&row, true, 160);
let detail = &lines[1];
let detail_line = plain_line(&detail);
assert!(detail_line.contains("Gate: waiting for BLOCKER-1 via depends_on"));
assert!(detail_line.contains("Action: queue disabled"));
assert!(detail_line.contains("Reason: Queue disabled: waiting for BLOCKER-1"));
assert!(detail_line.contains("Dependencies: BLOCKER-1 via depends_on"));
assert!(detail_line.contains("Action: Queue"));
assert!(!detail_line.contains("Queue disabled"));
}
#[test]
+15 -12
View File
@@ -2203,7 +2203,7 @@ mod tests {
}
#[test]
fn workspace_panel_marks_ready_ticket_with_unresolved_relation_waiting_gate() {
fn workspace_panel_queues_ready_ticket_with_unresolved_relation_context() {
let temp = TempDir::new().unwrap();
write_ticket_config(temp.path());
let backend = LocalTicketBackend::new(temp.path().join(".yoi/tickets"));
@@ -2233,14 +2233,9 @@ mod tests {
.unwrap();
assert_eq!(row.kind, PanelRowKind::Ticket);
assert_eq!(row.next_action, Some(NextUserAction::Wait));
assert_eq!(row.priority, ActionPriority::Background);
assert!(
row.disabled_reason
.as_deref()
.unwrap()
.contains("Queue disabled: waiting for")
);
assert_eq!(row.next_action, Some(NextUserAction::Queue));
assert_eq!(row.priority, ActionPriority::ReadyForQueue);
assert!(row.disabled_reason.is_none());
assert!(
row.ticket
.as_ref()
@@ -2253,7 +2248,7 @@ mod tests {
}
#[test]
fn workspace_panel_allows_ready_ticket_when_relation_prerequisite_is_queued() {
fn workspace_panel_queues_ready_ticket_when_relation_prerequisite_is_queued() {
let temp = TempDir::new().unwrap();
write_ticket_config(temp.path());
let backend = LocalTicketBackend::new(temp.path().join(".yoi/tickets"));
@@ -2286,12 +2281,20 @@ mod tests {
assert_eq!(row.next_action, Some(NextUserAction::Queue));
assert_eq!(row.priority, ActionPriority::ReadyForQueue);
assert!(row.disabled_reason.is_none());
assert!(row.ticket.as_ref().unwrap().blocked_reason.is_none());
assert!(
row.ticket
.as_ref()
.unwrap()
.blocked_reason
.as_deref()
.unwrap_or_default()
.contains(&dependency.id)
);
assert!(
row.key_hint
.as_deref()
.unwrap()
.contains("Queue allowed: prerequisites are already queued/in progress")
.contains("dependency relations remain scheduling context")
);
assert!(row.key_hint.as_deref().unwrap().contains(&dependency.id));
}