impl CliAdapter {
fn decode_command(
&self,
command: &Commands,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
match command {
Commands::Generate {
category,
template,
params,
output,
create_dirs,
} => Self::decode_generate(category, template, params, output, create_dirs),
Commands::Scaffold { command } => match command {
ScaffoldCommands::Project {
toolchain,
templates,
params,
parallel,
} => Self::decode_scaffold(toolchain, templates, params, *parallel),
_ => Err(ProtocolError::UnsupportedProtocol(
"Agent scaffolding not supported via unified protocol".to_string(),
)),
},
Commands::List {
toolchain,
category,
format,
} => Self::decode_list(toolchain, category, format),
Commands::Search {
query,
toolchain,
limit,
} => Self::decode_search(query, toolchain, *limit),
Commands::Validate { uri, params } => Self::decode_validate(uri, params),
Commands::Context {
toolchain,
project_path,
output,
format,
include_large_files: _,
skip_expensive_metrics: _,
language: _,
languages: _,
} => Self::decode_context(toolchain.as_deref(), project_path, output, format),
Commands::Analyze(analyze_cmd) => Self::decode_analyze_command(analyze_cmd),
Commands::Qdd(_) => Self::cli_only_command_error(),
Commands::Demo {
path,
url,
format,
no_browser,
port,
cli,
target_nodes,
centrality_threshold,
merge_threshold,
..
} => Self::decode_demo(
path,
url,
format,
*no_browser,
port,
*cli,
*target_nodes,
*centrality_threshold,
*merge_threshold,
),
Commands::Serve {
host,
port,
cors,
transport: _,
} => Self::decode_serve(host, *port, *cors),
Commands::Diagnose(_)
| Commands::QualityGate { .. }
| Commands::QualityGates { .. } | Commands::Maintain { .. } | Commands::Hooks(_) | Commands::Report { .. }
| Commands::RepoScore { .. } | Commands::RustProjectScore { .. } | Commands::BrickScore { .. } | Commands::PopperScore { .. } | Commands::DemoScore { .. } | Commands::Enforce(_)
| Commands::Refactor(_)
| Commands::Roadmap(_)
| Commands::Test { .. }
| Commands::Memory { .. }
| Commands::Cache { .. }
| Commands::Telemetry { .. }
| Commands::Config { .. }
| Commands::Agent { .. }
| Commands::Tdg { .. }
| Commands::ValidateDocs(_)
| Commands::ValidateReadme(_) | Commands::RedTeam(_) | Commands::Org(_) | Commands::Prompt(_) | Commands::Embed(_) | Commands::Semantic(_) | Commands::Debug { .. } | Commands::Work { .. } | Commands::Comply { .. } | Commands::ProjectDiag { .. } | Commands::TestDiscovery { .. } | Commands::DebugFiveWhys { .. } | Commands::Localize { .. } | Commands::Oracle { .. } | Commands::ShowMetrics { .. } | Commands::PredictQuality { .. } | Commands::RecordMetric { .. } | Commands::QaWork { .. } | Commands::PerfectionScore { .. } | Commands::Spec { .. } | Commands::CudaTdg { .. } | Commands::DepsAudit { .. } | Commands::Query { .. } | Commands::Falsify { .. } | Commands::Kaizen { .. } | Commands::Extract { .. } | Commands::Split { .. } | Commands::Sql { .. } => Self::cli_only_command_error(),
#[cfg(feature = "mutation-testing")]
Commands::Mutate(_) => Self::cli_only_command_error(),
}
}
fn decode_generate(
category: &str,
template: &str,
params: &[(String, Value)],
output: &Option<std::path::PathBuf>,
create_dirs: &bool,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let params_map: HashMap<String, Value> = params.iter().cloned().collect();
let body = json!({
"template_uri": format!("template://{}/{}", category, template),
"parameters": params_map,
"output_path": output,
"create_dirs": create_dirs
});
Ok((Method::POST, "/api/v1/generate".to_string(), body, None))
}
fn decode_scaffold(
toolchain: &str,
templates: &[String],
params: &[(String, Value)],
parallel: usize,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let params_map: HashMap<String, Value> = params.iter().cloned().collect();
let body = json!({
"toolchain": toolchain,
"templates": templates,
"parameters": params_map,
"parallel": ¶llel
});
Ok((Method::POST, "/api/v1/scaffold".to_string(), body, None))
}
fn decode_list(
toolchain: &Option<String>,
category: &Option<String>,
format: &OutputFormat,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let mut query_params = Vec::new();
if let Some(tc) = toolchain {
query_params.push(format!("toolchain={tc}"));
}
if let Some(cat) = category {
query_params.push(format!("category={cat}"));
}
if !query_params.is_empty() {
query_params.push(format!("format={format:?}").to_lowercase());
}
let query_string = if query_params.is_empty() {
String::new()
} else {
format!("?{}", query_params.join("&"))
};
Ok((
Method::GET,
format!("/api/v1/templates{query_string}"),
json!({}),
Some(format.clone()),
))
}
fn decode_search(
query: &str,
toolchain: &Option<String>,
limit: usize,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let body = json!({
"query": query,
"toolchain": toolchain,
"limit": &limit
});
Ok((Method::POST, "/api/v1/search".to_string(), body, None))
}
fn decode_validate(
uri: &str,
params: &[(String, Value)],
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let params_map: HashMap<String, Value> = params.iter().cloned().collect();
let body = json!({
"template_uri": uri,
"parameters": params_map
});
Ok((Method::POST, "/api/v1/validate".to_string(), body, None))
}
fn decode_context(
toolchain: Option<&str>,
project_path: &std::path::Path,
output: &Option<std::path::PathBuf>,
format: &ContextFormat,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let body = json!({
"toolchain": toolchain,
"project_path": project_path.to_string_lossy(),
"output_path": output,
"format": format_to_string(format)
});
Ok((
Method::POST,
"/api/v1/analyze/context".to_string(),
body,
Some(OutputFormat::Json),
))
}
fn decode_analyze_command(
analyze_cmd: &AnalyzeCommands,
) -> Result<(Method, String, Value, Option<OutputFormat>), ProtocolError> {
let command_category = Self::get_analyze_command_category(analyze_cmd);
match command_category {
AnalyzeCommandCategory::Basic => Self::dispatch_basic_analysis(analyze_cmd),
AnalyzeCommandCategory::Advanced => Self::dispatch_advanced_analysis(analyze_cmd),
AnalyzeCommandCategory::Structural => Self::dispatch_structural_analysis(analyze_cmd),
AnalyzeCommandCategory::Specialized => Self::dispatch_specialized_analysis(analyze_cmd),
}
}
}