feat: add ecc2 inbox drain routing

This commit is contained in:
Affaan Mustafa
2026-04-07 12:51:28 -07:00
parent 8ff5e736cd
commit 7622973452
3 changed files with 233 additions and 0 deletions

View File

@@ -64,6 +64,20 @@ enum Commands {
#[arg(short, long, default_value_t = true)]
worktree: bool,
},
/// Route unread task handoffs from a lead session inbox through the assignment policy
DrainInbox {
/// Lead session ID or alias
session_id: String,
/// Agent type for routed delegates
#[arg(short, long, default_value = "claude")]
agent: String,
/// Create a dedicated worktree if new delegates must be spawned
#[arg(short, long, default_value_t = true)]
worktree: bool,
/// Maximum unread task handoffs to route
#[arg(long, default_value_t = 5)]
limit: usize,
},
/// List active sessions
Sessions,
/// Show session details
@@ -226,6 +240,45 @@ async fn main() -> Result<()> {
}
);
}
Some(Commands::DrainInbox {
session_id,
agent,
worktree: use_worktree,
limit,
}) => {
let lead_id = resolve_session_id(&db, &session_id)?;
let outcomes = session::manager::drain_inbox(
&db,
&cfg,
&lead_id,
&agent,
use_worktree,
limit,
)
.await?;
if outcomes.is_empty() {
println!("No unread task handoffs for {}", short_session(&lead_id));
} else {
println!(
"Routed {} inbox task handoff(s) from {}",
outcomes.len(),
short_session(&lead_id)
);
for outcome in outcomes {
println!(
"- {} -> {} ({}) | {}",
outcome.message_id,
short_session(&outcome.session_id),
match outcome.action {
session::manager::AssignmentAction::Spawned => "spawned",
session::manager::AssignmentAction::ReusedIdle => "reused-idle",
session::manager::AssignmentAction::ReusedActive => "reused-active",
},
outcome.task
);
}
}
}
Some(Commands::Sessions) => {
let sessions = session::manager::list_sessions(&db)?;
for s in sessions {
@@ -542,4 +595,32 @@ mod tests {
_ => panic!("expected assign subcommand"),
}
}
#[test]
fn cli_parses_drain_inbox_command() {
let cli = Cli::try_parse_from([
"ecc",
"drain-inbox",
"lead",
"--agent",
"claude",
"--limit",
"3",
])
.expect("drain-inbox should parse");
match cli.command {
Some(Commands::DrainInbox {
session_id,
agent,
limit,
..
}) => {
assert_eq!(session_id, "lead");
assert_eq!(agent, "claude");
assert_eq!(limit, 3);
}
_ => panic!("expected drain-inbox subcommand"),
}
}
}