use crate::registry::ToolContext;
pub const ENV_KANBAN_TASK: &str = "EDGECRAB_KANBAN_TASK";
pub fn env_task_id() -> Option<String> {
std::env::var(ENV_KANBAN_TASK)
.ok()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
}
pub fn resolve_task_id(ctx: &ToolContext, arg: Option<&str>) -> Option<String> {
arg.map(str::trim)
.filter(|s| !s.is_empty())
.map(str::to_string)
.or_else(|| ctx.kanban_task_id.clone())
.or_else(env_task_id)
}
pub fn orchestrator_tool_visible(ctx: &ToolContext) -> bool {
ctx.kanban_task_id.is_none() && env_task_id().is_none()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::registry::ToolContext;
#[test]
fn resolve_prefers_explicit_task_id() {
unsafe {
std::env::remove_var(ENV_KANBAN_TASK);
}
let ctx = ToolContext::test_context();
assert_eq!(
resolve_task_id(&ctx, Some("kb-abc")).as_deref(),
Some("kb-abc")
);
}
#[test]
fn resolve_uses_ctx_task_id() {
let mut ctx = ToolContext::test_context();
ctx.kanban_task_id = Some("kb-ctx".into());
assert_eq!(resolve_task_id(&ctx, None).as_deref(), Some("kb-ctx"));
}
#[test]
fn orchestrator_hidden_when_worker_ctx_set() {
let mut ctx = ToolContext::test_context();
ctx.kanban_task_id = Some("kb-1".into());
assert!(!orchestrator_tool_visible(&ctx));
ctx.kanban_task_id = None;
assert!(orchestrator_tool_visible(&ctx));
}
}