use clap::{Parser, Subcommand};
use thegent_shm::adapters::inmemory::{
InMemoryCircuitBreaker, InMemoryCommandCache, InMemoryEventStore,
};
use thegent_shm::ports::driven::{
CircuitBreakerPort, CommandCachePort, EventPort,
};
#[derive(Parser, Debug)]
#[command(name = "thegent-shm")]
#[command(about = "Shared memory primitives for multi-agent orchestration")]
#[command(version = "0.1.0")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
Lock {
#[command(subcommand)]
action: LockAction,
},
Breaker {
#[command(subcommand)]
action: BreakerAction,
},
Events {
#[arg(short, long)]
all: bool,
},
Health,
}
#[derive(Subcommand, Debug)]
enum LockAction {
Acquire {
cmd_hash: String,
pid: u32,
},
Release {
cmd_hash: String,
pid: u32,
},
List,
Get {
cmd_hash: String,
},
}
#[derive(Subcommand, Debug)]
enum BreakerAction {
Success {
target: String,
},
Failure {
target: String,
},
Get {
target: String,
},
List,
}
fn main() {
let cli = Cli::parse();
let mut cache = InMemoryCommandCache::new();
let mut breakers = InMemoryCircuitBreaker::new();
let events = InMemoryEventStore::new();
match cli.command {
Commands::Lock { action } => {
match action {
LockAction::Acquire { cmd_hash, pid } => {
match cache.acquire_lock(&cmd_hash, pid) {
Ok(()) => {
println!("Lock acquired: {} for PID {}", cmd_hash, pid);
}
Err(e) => {
eprintln!("Failed to acquire lock: {}", e);
std::process::exit(1);
}
}
}
LockAction::Release { cmd_hash, pid } => {
match cache.release_lock(&cmd_hash, pid) {
Ok(()) => {
println!("Lock released: {}", cmd_hash);
}
Err(e) => {
eprintln!("Failed to release lock: {}", e);
std::process::exit(1);
}
}
}
LockAction::List => {
let locks = cache.list_locks();
if locks.is_empty() {
println!("No locks held");
} else {
for lock in locks {
println!(
"{}: PID={} status={:?}",
lock.cmd_hash, lock.pid, lock.status
);
}
}
}
LockAction::Get { cmd_hash } => {
if let Some(lock) = cache.get_lock(&cmd_hash) {
println!("Lock found:");
println!(" Hash: {}", lock.cmd_hash);
println!(" PID: {}", lock.pid);
println!(" Status: {:?}", lock.status);
} else {
println!("Lock not found: {}", cmd_hash);
}
}
}
}
Commands::Breaker { action } => {
match action {
BreakerAction::Success { target } => {
if let Err(e) = breakers.record_success(&target) {
eprintln!("Failed to record success: {}", e);
std::process::exit(1);
}
println!("Success recorded for: {}", target);
}
BreakerAction::Failure { target } => {
if let Err(e) = breakers.record_failure(&target) {
eprintln!("Failed to record failure: {}", e);
std::process::exit(1);
}
println!("Failure recorded for: {}", target);
if let Some(cb) = breakers.get_breaker(&target) {
if matches!(cb.state, thegent_shm::domain::value_objects::CircuitState::Open) {
println!("Circuit breaker OPENED for: {}", target);
}
}
}
BreakerAction::Get { target } => {
if let Some(cb) = breakers.get_breaker(&target) {
println!("Circuit Breaker: {}", cb.target);
println!(" State: {:?}", cb.state);
println!(" Failures: {}/{}", cb.failures, cb.threshold);
} else {
println!("Circuit breaker not found: {}", target);
}
}
BreakerAction::List => {
let breakers_list = breakers.list_breakers();
if breakers_list.is_empty() {
println!("No circuit breakers");
} else {
for cb in breakers_list {
println!(
"{}: {:?} ({}/{} failures)",
cb.target, cb.state, cb.failures, cb.threshold
);
}
}
}
}
}
Commands::Events { all } => {
if all {
let all_events = events.get_events_since(std::time::SystemTime::UNIX_EPOCH);
if all_events.is_empty() {
println!("No events");
} else {
for event in all_events {
println!("{:?}", event);
}
}
} else {
println!("Use --all to show all events");
}
}
Commands::Health => {
println!("Health check endpoint ready");
println!("Use thegent-observability crate for full health monitoring");
}
}
}