use clap::{Parser, Subcommand};
use anyhow::Result;
use serde::{Serialize, Deserialize};
use synaptic_qudag_core::QuDAGNetwork;
use synaptic_neural_wasm::{NeuralNetwork, Layer};
use synaptic_neural_mesh::{NeuralMesh, Agent};
use synaptic_daa_swarm::{Swarm, SwarmBehavior};
use claude_market::{ClaudeMarket, MarketConfig};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Node {
#[command(subcommand)]
action: NodeAction,
},
Swarm {
#[command(subcommand)]
action: SwarmAction,
},
Neural {
#[command(subcommand)]
action: NeuralAction,
},
Mesh {
#[command(subcommand)]
action: MeshAction,
},
Market {
#[command(subcommand)]
action: MarketAction,
},
Wallet {
#[command(subcommand)]
action: WalletAction,
},
Status,
}
#[derive(Subcommand, Debug)]
pub enum NodeAction {
Start {
#[arg(short, long, default_value = "8080")]
port: u16,
},
Stop,
List,
}
#[derive(Subcommand, Debug)]
pub enum SwarmAction {
Create {
#[arg(short, long, default_value = "10")]
agents: usize,
#[arg(short, long)]
behavior: Option<String>,
},
Run {
#[arg(short, long)]
id: Option<String>,
},
List,
}
#[derive(Subcommand, Debug)]
pub enum NeuralAction {
Create {
#[arg(short, long)]
layers: Vec<usize>,
#[arg(short, long)]
output: String,
},
Train {
#[arg(short, long)]
model: String,
#[arg(short, long)]
data: String,
},
Predict {
#[arg(short, long)]
model: String,
#[arg(short, long)]
input: Vec<f32>,
},
}
#[derive(Subcommand, Debug)]
pub enum MeshAction {
Info,
AddAgent {
#[arg(short, long)]
name: String,
},
SubmitTask {
#[arg(short, long)]
name: String,
#[arg(short, long)]
compute: f64,
},
}
#[derive(Subcommand, Debug)]
pub enum MarketAction {
Init {
#[arg(short, long)]
db_path: Option<String>,
},
Offer {
#[arg(short, long)]
slots: u64,
#[arg(short, long)]
price: u64,
#[arg(long)]
opt_in: bool,
},
Bid {
#[arg(short, long)]
task: String,
#[arg(short, long)]
max_price: u64,
},
Status {
#[arg(short, long)]
detailed: bool,
},
Terms,
}
#[derive(Subcommand, Debug)]
pub enum WalletAction {
Balance,
Transfer {
#[arg(short, long)]
to: String,
#[arg(short, long)]
amount: u64,
#[arg(short, long)]
memo: Option<String>,
},
History {
#[arg(short, long, default_value = "10")]
limit: usize,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MeshCommand {
NodeStart { port: u16 },
NodeStop,
NodeList,
SwarmCreate { agents: usize, behavior: Option<SwarmBehavior> },
SwarmRun { id: Option<String> },
SwarmList,
NeuralCreate { layers: Vec<usize>, output: String },
NeuralTrain { model: String, data: String },
NeuralPredict { model: String, input: Vec<f32> },
MeshInfo,
MeshAddAgent { name: String },
MeshSubmitTask { name: String, compute: f64 },
MarketInit { db_path: Option<String> },
MarketOffer { slots: u64, price: u64, opt_in: bool },
MarketBid { task: String, max_price: u64 },
MarketStatus { detailed: bool },
MarketTerms,
WalletBalance,
WalletTransfer { to: String, amount: u64, memo: Option<String> },
WalletHistory { limit: usize },
Status,
}
pub async fn execute_command(command: MeshCommand) -> Result<CommandResult> {
match command {
MeshCommand::NodeStart { port } => {
let _network = QuDAGNetwork::new();
Ok(CommandResult::NodeStarted { port, id: "node-1".to_string() })
}
MeshCommand::NodeStop => {
Ok(CommandResult::NodeStopped)
}
MeshCommand::NodeList => {
Ok(CommandResult::NodeList { nodes: vec![] })
}
MeshCommand::SwarmCreate { agents, behavior } => {
let swarm = Swarm::new();
if let Some(b) = behavior {
swarm.add_behavior(b);
}
swarm.initialize(agents).await;
Ok(CommandResult::SwarmCreated { id: "swarm-1".to_string(), agents })
}
MeshCommand::SwarmRun { id } => {
let swarm = Swarm::new();
swarm.initialize(10).await;
Ok(CommandResult::SwarmRunning { id: id.unwrap_or("swarm-1".to_string()) })
}
MeshCommand::SwarmList => {
Ok(CommandResult::SwarmList { swarms: vec![] })
}
MeshCommand::NeuralCreate { layers, output } => {
let mut network = NeuralNetwork::new();
for i in 0..layers.len() - 1 {
let layer = Layer::dense(layers[i], layers[i + 1]);
network.add_layer(layer);
}
let json = network.to_json()?;
std::fs::write(&output, json)?;
Ok(CommandResult::NeuralCreated { path: output })
}
MeshCommand::NeuralTrain { model, data: _ } => {
let model_json = std::fs::read_to_string(&model)?;
let _network = NeuralNetwork::from_json(&model_json)?;
Ok(CommandResult::NeuralTrained { model, epochs: 100 })
}
MeshCommand::NeuralPredict { model, input } => {
let model_json = std::fs::read_to_string(&model)?;
let network = NeuralNetwork::from_json(&model_json)?;
let output_json = network.predict(&input)
.map_err(|e| anyhow::anyhow!("Prediction failed: {:?}", e))?;
let output: Vec<f32> = serde_json::from_str(&output_json)?;
Ok(CommandResult::NeuralPrediction { output })
}
MeshCommand::MeshInfo => {
let mesh = NeuralMesh::new();
let stats = mesh.get_stats();
Ok(CommandResult::MeshInfo {
agents: stats.total_agents,
tasks: stats.total_tasks,
})
}
MeshCommand::MeshAddAgent { name } => {
let mesh = NeuralMesh::new();
let agent = Agent::new(&name);
let id = mesh.add_agent(agent).await?;
Ok(CommandResult::AgentAdded { id: id.to_string(), name })
}
MeshCommand::MeshSubmitTask { name, compute } => {
let mesh = NeuralMesh::new();
let requirements = synaptic_neural_mesh::TaskRequirements {
min_compute_power: compute,
min_memory: 1024 * 1024,
required_specializations: vec!["general".to_string()],
max_latency_ms: 100.0,
};
let id = mesh.submit_task(&name, requirements).await?;
Ok(CommandResult::TaskSubmitted { id: id.to_string(), name })
}
MeshCommand::MarketInit { db_path } => {
let config = MarketConfig {
db_path: db_path.clone(),
..Default::default()
};
let _market = ClaudeMarket::new(config).await?;
Ok(CommandResult::MarketInitialized {
db_path: db_path.unwrap_or("claude_market.db".to_string())
})
}
MeshCommand::MarketOffer { slots, price, opt_in } => {
if !opt_in {
return Err(anyhow::anyhow!("Market participation requires explicit opt-in with --opt-in flag"));
}
Ok(CommandResult::MarketOfferCreated { slots, price })
}
MeshCommand::MarketBid { task, max_price } => {
Ok(CommandResult::MarketBidSubmitted { task, max_price })
}
MeshCommand::MarketStatus { detailed: _ } => {
Ok(CommandResult::MarketStatus {
active_offers: 3,
active_bids: 7,
})
}
MeshCommand::MarketTerms => {
let terms = r#"
SYNAPTIC MARKET TERMS OF SERVICE
Synaptic Market facilitates peer compute federation, not API access resale.
KEY COMPLIANCE REQUIREMENTS:
✅ NO shared API keys - Each participant uses their own Claude subscription
✅ LOCAL execution - Tasks run locally on provider's Claude account
✅ VOLUNTARY participation - Full user control with opt-in mechanisms
✅ TOKEN rewards - RUV tokens reward contribution, not access purchase
LEGAL FRAMEWORK:
• Each node maintains individual Claude subscriptions
• Tasks are routed, not account access shared
• Participation is voluntary and contribution-based
• API keys are never shared or transmitted
• This is peer compute federation, not resale
By using Synaptic Market, you agree to maintain your own Claude subscription
and comply with Anthropic's Terms of Service.
"#;
Ok(CommandResult::MarketTerms { terms: terms.to_string() })
}
MeshCommand::WalletBalance => {
Ok(CommandResult::WalletBalance { balance: 1000 })
}
MeshCommand::WalletTransfer { to, amount, memo: _ } => {
Ok(CommandResult::WalletTransferCompleted { to, amount })
}
MeshCommand::WalletHistory { limit: _ } => {
Ok(CommandResult::WalletHistory {
transactions: vec![
"Transfer: 100 RUV to peer-123 (market_payment)".to_string(),
"Received: 50 RUV from peer-456 (task_completion)".to_string(),
]
})
}
MeshCommand::Status => {
Ok(CommandResult::Status {
mesh_active: true,
nodes: 1,
agents: 0,
swarms: 0,
})
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CommandResult {
NodeStarted { port: u16, id: String },
NodeStopped,
NodeList { nodes: Vec<String> },
SwarmCreated { id: String, agents: usize },
SwarmRunning { id: String },
SwarmList { swarms: Vec<String> },
NeuralCreated { path: String },
NeuralTrained { model: String, epochs: usize },
NeuralPrediction { output: Vec<f32> },
MeshInfo { agents: usize, tasks: usize },
AgentAdded { id: String, name: String },
TaskSubmitted { id: String, name: String },
MarketInitialized { db_path: String },
MarketOfferCreated { slots: u64, price: u64 },
MarketBidSubmitted { task: String, max_price: u64 },
MarketStatus { active_offers: usize, active_bids: usize },
MarketTerms { terms: String },
WalletBalance { balance: u64 },
WalletTransferCompleted { to: String, amount: u64 },
WalletHistory { transactions: Vec<String> },
Status { mesh_active: bool, nodes: usize, agents: usize, swarms: usize },
}
pub fn cli_to_command(cli: Cli) -> MeshCommand {
match cli.command {
Commands::Node { action } => match action {
NodeAction::Start { port } => MeshCommand::NodeStart { port },
NodeAction::Stop => MeshCommand::NodeStop,
NodeAction::List => MeshCommand::NodeList,
},
Commands::Swarm { action } => match action {
SwarmAction::Create { agents, behavior } => {
let b = behavior.and_then(|s| match s.as_str() {
"flocking" => Some(SwarmBehavior::Flocking),
"foraging" => Some(SwarmBehavior::Foraging),
"exploration" => Some(SwarmBehavior::Exploration),
"consensus" => Some(SwarmBehavior::Consensus),
"optimization" => Some(SwarmBehavior::Optimization),
_ => None,
});
MeshCommand::SwarmCreate { agents, behavior: b }
},
SwarmAction::Run { id } => MeshCommand::SwarmRun { id },
SwarmAction::List => MeshCommand::SwarmList,
},
Commands::Neural { action } => match action {
NeuralAction::Create { layers, output } => MeshCommand::NeuralCreate { layers, output },
NeuralAction::Train { model, data } => MeshCommand::NeuralTrain { model, data },
NeuralAction::Predict { model, input } => MeshCommand::NeuralPredict { model, input },
},
Commands::Mesh { action } => match action {
MeshAction::Info => MeshCommand::MeshInfo,
MeshAction::AddAgent { name } => MeshCommand::MeshAddAgent { name },
MeshAction::SubmitTask { name, compute } => MeshCommand::MeshSubmitTask { name, compute },
},
Commands::Market { action } => match action {
MarketAction::Init { db_path } => MeshCommand::MarketInit { db_path },
MarketAction::Offer { slots, price, opt_in } => MeshCommand::MarketOffer { slots, price, opt_in },
MarketAction::Bid { task, max_price } => MeshCommand::MarketBid { task, max_price },
MarketAction::Status { detailed } => MeshCommand::MarketStatus { detailed },
MarketAction::Terms => MeshCommand::MarketTerms,
},
Commands::Wallet { action } => match action {
WalletAction::Balance => MeshCommand::WalletBalance,
WalletAction::Transfer { to, amount, memo } => MeshCommand::WalletTransfer { to, amount, memo },
WalletAction::History { limit } => MeshCommand::WalletHistory { limit },
},
Commands::Status => MeshCommand::Status,
}
}
pub fn init_tracing() {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_node_start() {
let cmd = MeshCommand::NodeStart { port: 8080 };
let result = execute_command(cmd).await.unwrap();
match result {
CommandResult::NodeStarted { port, .. } => assert_eq!(port, 8080),
_ => panic!("Unexpected result"),
}
}
#[tokio::test]
async fn test_swarm_create() {
let cmd = MeshCommand::SwarmCreate {
agents: 5,
behavior: Some(SwarmBehavior::Flocking)
};
let result = execute_command(cmd).await.unwrap();
match result {
CommandResult::SwarmCreated { agents, .. } => assert_eq!(agents, 5),
_ => panic!("Unexpected result"),
}
}
#[tokio::test]
async fn test_neural_create() {
let cmd = MeshCommand::NeuralCreate {
layers: vec![10, 5, 2],
output: "/tmp/test_model.json".to_string(),
};
let result = execute_command(cmd).await.unwrap();
match result {
CommandResult::NeuralCreated { path } => {
assert_eq!(path, "/tmp/test_model.json");
std::fs::remove_file(path).ok();
},
_ => panic!("Unexpected result"),
}
}
}