From a734bf1a472b19d63341769d26a66628575df7f4 Mon Sep 17 00:00:00 2001 From: soryu Date: Wed, 4 Feb 2026 01:07:14 +0000 Subject: Add chain checkpoint contracts --- makima/src/bin/makima.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'makima/src/bin') diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs index 2037b47..3215bfd 100644 --- a/makima/src/bin/makima.rs +++ b/makima/src/bin/makima.rs @@ -612,6 +612,94 @@ async fn run_supervisor( .await?; println!("{}", serde_json::to_string(&result.0)?); } + // Chain supervisor commands + SupervisorCommand::ChainStatus(args) => { + let client = ApiClient::new(args.common.api_url, args.common.api_key)?; + eprintln!("Getting chain status for {}...", args.common.chain_id); + let result = client.get_chain(args.common.chain_id).await?; + if args.verbose { + // Get contracts as well + let contracts = client.get_chain_contracts(args.common.chain_id).await?; + println!("{}", serde_json::to_string(&serde_json::json!({ + "chain": result.0, + "contracts": contracts.0 + }))?); + } else { + println!("{}", serde_json::to_string(&result.0)?); + } + } + SupervisorCommand::ChainContracts(args) => { + let client = ApiClient::new(args.common.api_url, args.common.api_key)?; + eprintln!("Listing contracts in chain {}...", args.common.chain_id); + let result = client.get_chain_contracts(args.common.chain_id).await?; + if let Some(status) = &args.status { + // Filter by status client-side + let contracts: Vec<_> = result.0.as_array() + .unwrap_or(&vec![]) + .iter() + .filter(|c| c.get("status").and_then(|s| s.as_str()) == Some(status.as_str())) + .collect(); + println!("{}", serde_json::to_string(&contracts)?); + } else { + println!("{}", serde_json::to_string(&result.0)?); + } + } + SupervisorCommand::ChainProgress(args) => { + let client = ApiClient::new(args.common.api_url, args.common.api_key)?; + eprintln!("Triggering chain progression for {}...", args.common.chain_id); + // Use the start endpoint to progress (it handles already-active chains) + let result = client.start_chain(args.common.chain_id).await; + match result { + Ok(r) => println!("{}", serde_json::to_string(&r.0)?), + Err(e) => { + // Check if already active - in that case, just get status + if e.to_string().contains("ALREADY_ACTIVE") { + eprintln!("Chain is already active, checking current status..."); + let status = client.get_chain(args.common.chain_id).await?; + println!("{}", serde_json::to_string(&status.0)?); + } else { + return Err(e.into()); + } + } + } + } + SupervisorCommand::ChainGraph(args) => { + let client = ApiClient::new(args.common.api_url, args.common.api_key)?; + let result = client.get_chain_graph(args.common.chain_id).await?; + if args.format == "json" { + println!("{}", serde_json::to_string(&result.0)?); + } else { + // ASCII visualization (similar to chain graph command) + if let Some(nodes) = result.0.get("nodes").and_then(|n| n.as_array()) { + // Group by depth + let mut by_depth: std::collections::BTreeMap> = + std::collections::BTreeMap::new(); + for node in nodes { + let name = node.get("name").and_then(|n| n.as_str()).unwrap_or("?"); + let status = node.get("status").and_then(|s| s.as_str()).unwrap_or("pending"); + let depth = node.get("depth").and_then(|d| d.as_i64()).unwrap_or(0); + by_depth.entry(depth).or_default().push((name, status)); + } + let chain_name = result.0.get("name").and_then(|v| v.as_str()).unwrap_or("Chain"); + println!("Chain: {}", chain_name); + println!(); + for (depth, contracts) in by_depth { + let prefix = " ".repeat(depth as usize); + for (name, status) in contracts { + let icon = match status { + "completed" => "\u{2713}", + "active" => "\u{21bb}", + "failed" => "\u{2717}", + _ => "\u{25cb}", + }; + println!("{}[{}] {} ({})", prefix, icon, name, status); + } + } + } else { + println!("{}", serde_json::to_string(&result.0)?); + } + } + } } Ok(()) -- cgit v1.2.3