#![allow(unused_imports, unused_variables)]
use clap::{Parser, Subcommand};
use std::path::PathBuf;
use std::sync::Arc;
use tracing::{error, info};
use wootype::agent::{AgentCoordinator, AgentSession, AgentType, SessionConfig};
use wootype::api::{ApiConfig, ApiServer};
use wootype::bridge::{BridgeConfig, IpcBridge};
use wootype::core::{TypeId, TypeUniverse};
#[derive(Parser)]
#[command(name = "wootype")]
#[command(about = "Type System as a Service for Go")]
#[command(version)]
struct Cli {
#[arg(short, long, default_value = "info")]
log_level: String,
#[arg(short, long)]
config: Option<PathBuf>,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Daemon {
#[arg(short, long, default_value = "/tmp/wootype.sock")]
socket: PathBuf,
#[arg(short, long, default_value = "127.0.0.1:50051")]
grpc_addr: String,
#[arg(long)]
preload_stdlib: bool,
},
Import {
package: String,
#[arg(short, long)]
recursive: bool,
},
Query {
#[arg(short, long)]
session: Option<String>,
#[arg(short, long)]
type_name: Option<String>,
#[arg(short, long)]
package: Option<String>,
#[arg(short, long)]
pattern: Option<String>,
},
Validate {
#[arg(short, long)]
session: String,
#[arg(short, long)]
expr: String,
#[arg(short, long)]
expected_type: Option<String>,
},
Connect {
#[arg(short, long)]
name: String,
#[arg(short, long, default_value = "generic")]
agent_type: String,
#[arg(short, long, default_value = "full")]
isolation: String,
},
Status,
Bench {
#[arg(short, long, default_value = "all")]
kind: String,
},
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
tracing_subscriber::fmt()
.with_env_filter(&cli.log_level)
.init();
info!("Wootype v{}", env!("CARGO_PKG_VERSION"));
match cli.command {
Commands::Daemon {
socket,
grpc_addr,
preload_stdlib,
} => {
run_daemon(socket, grpc_addr, preload_stdlib).await?;
}
Commands::Import { package, recursive } => {
run_import(package, recursive).await?;
}
Commands::Query {
session,
type_name,
package,
pattern,
} => {
run_query(session, type_name, package, pattern).await?;
}
Commands::Validate {
session,
expr,
expected_type,
} => {
run_validate(session, expr, expected_type).await?;
}
Commands::Connect {
name,
agent_type,
isolation,
} => {
run_connect(name, agent_type, isolation).await?;
}
Commands::Status => {
run_status().await?;
}
Commands::Bench { kind } => {
run_bench(kind).await?;
}
}
Ok(())
}
async fn run_daemon(
socket: PathBuf,
grpc_addr: String,
preload_stdlib: bool,
) -> Result<(), Box<dyn std::error::Error>> {
info!("Starting wootype daemon");
info!("IPC socket: {:?}", socket);
info!("gRPC address: {}", grpc_addr);
let universe = Arc::new(TypeUniverse::new());
info!(
"Type universe initialized with {} types",
universe.type_count()
);
if preload_stdlib {
info!("Preloading stdlib packages...");
let importer = wootype::parser::PackageImporter::new(universe.clone());
let results = importer.preload_stdlib().await;
let total_imported: usize = results.iter().map(|r| r.types_imported).sum();
info!("Preloaded {} types from stdlib", total_imported);
}
let _coordinator = Arc::new(AgentCoordinator::new(universe.clone()));
info!("Agent coordinator initialized");
#[cfg(unix)]
let bridge_config = BridgeConfig {
socket_path: socket,
max_connections: 100,
message_timeout_ms: 5000,
};
#[cfg(windows)]
let bridge_config = BridgeConfig {
tcp_port: 9527,
max_connections: 100,
message_timeout_ms: 5000,
};
let mut bridge = IpcBridge::new(universe.clone(), bridge_config);
let api_config = ApiConfig {
bind_address: grpc_addr.parse()?,
max_concurrent_streams: 100,
enable_reflection: true,
};
let api_server = ApiServer::new(api_config, universe.clone());
tokio::select! {
result = bridge.start() => {
if let Err(e) = result {
error!("IPC bridge error: {}", e);
}
}
result = api_server.start() => {
if let Err(e) = result {
error!("API server error: {}", e);
}
}
}
Ok(())
}
async fn run_import(package: String, _recursive: bool) -> Result<(), Box<dyn std::error::Error>> {
info!("Importing package: {}", package);
let universe = Arc::new(TypeUniverse::new());
let importer = wootype::parser::PackageImporter::new(universe);
match importer.import(&package).await {
Ok(result) => {
info!("Imported {} types from {}", result.types_imported, package);
for error in &result.errors {
error!("Import error: {:?}", error);
}
}
Err(e) => {
error!("Failed to import {}: {:?}", package, e);
}
}
Ok(())
}
async fn run_query(
_session: Option<String>,
type_name: Option<String>,
package: Option<String>,
pattern: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let universe = Arc::new(TypeUniverse::new());
let _engine = wootype::query::QueryEngine::new(universe);
info!("Querying types...");
if let Some(name) = type_name {
info!("Looking up type: {}", name);
}
if let Some(pkg) = package {
info!("In package: {}", pkg);
}
if let Some(pat) = pattern {
info!("Pattern: {}", pat);
}
Ok(())
}
async fn run_validate(
_session: String,
expr: String,
expected_type: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
info!("Validating expression: {}", expr);
if let Some(expected) = expected_type {
info!("Expected type: {}", expected);
}
Ok(())
}
async fn run_connect(
name: String,
agent_type: String,
isolation: String,
) -> Result<(), Box<dyn std::error::Error>> {
info!("Connecting agent: {} (type: {})", name, agent_type);
let universe = Arc::new(TypeUniverse::new());
let coordinator = Arc::new(AgentCoordinator::new(universe));
let agent_type = match agent_type.as_str() {
"cursor" => AgentType::Cursor,
"claude_code" => AgentType::ClaudeCode,
"gemini_cli" => AgentType::GeminiCLI,
"github_copilot" => AgentType::GitHubCopilot,
_ => AgentType::Generic,
};
let isolation_level = match isolation.as_str() {
"full" => wootype::agent::IsolationLevel::Full,
"shared" => wootype::agent::IsolationLevel::SharedRead,
"snapshot" => wootype::agent::IsolationLevel::Snapshot,
_ => wootype::agent::IsolationLevel::Full,
};
let conn_request = wootype::agent::coordinator::ConnectionRequest {
agent_id: wootype::agent::AgentId::new(1),
name,
agent_type,
preferred_isolation: Some(isolation_level),
};
match coordinator.connect(conn_request).await {
wootype::agent::coordinator::ConnectionResult::Connected { session_id } => {
info!("Connected! Session ID: {}", session_id.0);
}
wootype::agent::coordinator::ConnectionResult::Rejected { reason } => {
error!("Connection rejected: {:?}", reason);
}
}
Ok(())
}
async fn run_status() -> Result<(), Box<dyn std::error::Error>> {
info!("Wootype Status");
info!("Version: {}", env!("CARGO_PKG_VERSION"));
Ok(())
}
async fn run_bench(kind: String) -> Result<(), Box<dyn std::error::Error>> {
info!("Running benchmarks: {}", kind);
let universe = Arc::new(TypeUniverse::new());
let engine = wootype::query::QueryEngine::new(universe);
let start = std::time::Instant::now();
for _ in 0..10000 {
let _ = engine.get_type(TypeId(1));
}
let elapsed = start.elapsed();
info!("Query benchmark: {:?} for 10000 queries", elapsed);
info!("Average: {:?} per query", elapsed / 10000);
Ok(())
}