diff --git a/hive-c0re/src/actions.rs b/hive-c0re/src/actions.rs index 9036b2b..2a79cc6 100644 --- a/hive-c0re/src/actions.rs +++ b/hive-c0re/src/actions.rs @@ -89,7 +89,7 @@ pub async fn approve(coord: Arc, id: i64) -> Result<()> { let inputs: Vec = serde_json::from_str(&approval.commit_ref).unwrap_or_default(); let result = crate::meta::lock_update(&inputs).await; - finish_approval(&coord, &approval, result, None) + finish_approval(&coord, &approval, result, None, false) } ApprovalKind::Spawn => { // Run the spawn in the background so the approve POST returns @@ -210,12 +210,24 @@ fn finish_approval( }); } } - ApprovalKind::Spawn => coord.notify_manager(&HelperEvent::Spawned { - agent: approval.agent.clone(), - ok, - note, - sha: approval.fetched_sha.clone(), - }), + ApprovalKind::Spawn => { + coord.notify_manager(&HelperEvent::Spawned { + agent: approval.agent.clone(), + ok, + note, + sha: approval.fetched_sha.clone(), + }); + // Newly spawned container has no claude session yet. Emit + // NeedsLogin immediately so the manager prompts the operator + // rather than waiting for crash_watch (which would miss it + // because the agent appears simultaneously in both prev_needs + // and current_needs, making the diff empty on the first tick). + if ok { + coord.notify_manager(&HelperEvent::NeedsLogin { + agent: approval.agent.clone(), + }); + } + } ApprovalKind::ApplyCommit if is_first_spawn => { coord.notify_manager(&HelperEvent::Spawned { agent: approval.agent.clone(), @@ -223,6 +235,11 @@ fn finish_approval( note, sha: approval.fetched_sha.clone(), }); + if ok { + coord.notify_manager(&HelperEvent::NeedsLogin { + agent: approval.agent.clone(), + }); + } } ApprovalKind::ApplyCommit => coord.notify_manager(&HelperEvent::Rebuilt { agent: approval.agent.clone(),