pub mod agent_rules;
pub mod append;
#[cfg(feature = "ast")]
pub mod ast;
pub mod batch;
pub mod create;
pub mod delete;
pub mod doc;
pub mod explain;
pub mod init;
#[cfg(feature = "mcp")]
pub mod mcp;
pub mod md;
pub mod output;
pub mod patch;
pub mod prepend;
pub mod read;
pub mod rename;
pub mod replace;
pub mod schema;
pub mod search;
pub mod status;
pub mod tidy;
pub mod tx;
pub mod undo;
pub mod write_dispatch;
pub mod write_mode;
use crate::cli::Cli;
use clap::Subcommand;
#[derive(Debug, Subcommand)]
pub enum Command {
#[command(display_order = 10)]
Append(append::AppendArgs),
#[command(display_order = 11)]
Create(create::CreateArgs),
#[command(display_order = 12)]
Delete(delete::DeleteArgs),
#[command(display_order = 11)]
Prepend(prepend::PrependArgs),
#[command(display_order = 13)]
Read(read::ReadArgs),
#[command(display_order = 14)]
Rename(rename::RenameArgs),
#[command(display_order = 20)]
Search(search::SearchArgs),
#[command(display_order = 21)]
Replace(replace::ReplaceArgs),
#[command(display_order = 22)]
Patch(patch::PatchArgs),
#[command(display_order = 23)]
Tidy(tidy::TidyArgs),
#[command(display_order = 24)]
Batch(batch::BatchArgs),
#[command(display_order = 30)]
Doc(doc::DocArgs),
#[command(display_order = 31)]
Md(md::MdArgs),
#[cfg(feature = "ast")]
#[command(display_order = 40)]
Ast(ast::AstArgs),
#[command(display_order = 50)]
Tx(crate::tx::TxArgs),
#[command(display_order = 51)]
Explain(explain::ExplainArgs),
#[command(display_order = 52)]
Undo(undo::UndoArgs),
#[command(display_order = 53)]
Status(status::StatusArgs),
#[command(display_order = 54)]
Schema(schema::SchemaArgs),
#[command(display_order = 55)]
AgentRules(agent_rules::AgentRulesArgs),
#[command(display_order = 56)]
Init(init::InitArgs),
#[cfg(feature = "mcp")]
#[command(display_order = 57)]
McpServer {
#[arg(long)]
log: Option<String>,
#[cfg(feature = "mcp-http")]
#[arg(long)]
http: bool,
#[cfg(feature = "mcp-http")]
#[arg(long, default_value = "127.0.0.1", requires = "http")]
host: String,
#[cfg(feature = "mcp-http")]
#[arg(long, default_value_t = 8080, requires = "http")]
port: u16,
#[cfg(feature = "mcp-http")]
#[arg(long, requires_all = ["http", "tls_key"])]
tls_cert: Option<std::path::PathBuf>,
#[cfg(feature = "mcp-http")]
#[arg(long, requires_all = ["http", "tls_cert"])]
tls_key: Option<std::path::PathBuf>,
},
#[command(display_order = 58)]
Completions {
#[arg(value_enum)]
shell: clap_complete::Shell,
},
}
fn load_project_config(global: &mut crate::cli::global::GlobalFlags) {
let Ok(cwd) = global.resolve_cwd() else {
return;
};
if let Some((config, _)) = crate::config::find_and_load(&cwd) {
crate::config::apply_config(global, &config);
}
}
pub fn dispatch(cli: Cli) -> anyhow::Result<u8> {
let mut global = cli.global;
match cli.command {
#[cfg(feature = "mcp")]
Command::McpServer {
log,
#[cfg(feature = "mcp-http")]
http,
#[cfg(feature = "mcp-http")]
host,
#[cfg(feature = "mcp-http")]
port,
#[cfg(feature = "mcp-http")]
tls_cert,
#[cfg(feature = "mcp-http")]
tls_key,
} => {
load_project_config(&mut global);
#[cfg(feature = "mcp-http")]
if http {
return mcp::run_mcp_http_server(
&global,
log,
&host,
port,
tls_cert.as_deref(),
tls_key.as_deref(),
);
}
mcp::run_mcp_server(&global, log)
}
Command::Schema(args) => schema::run(args, &global),
Command::AgentRules(args) => agent_rules::run(args, &global),
Command::Init(args) => init::run(args, &global),
Command::Completions { shell } => {
let mut cmd = <Cli as clap::CommandFactory>::command();
clap_complete::generate(shell, &mut cmd, "patchloom", &mut std::io::stdout());
Ok(crate::exit::SUCCESS)
}
Command::Read(args) => {
load_project_config(&mut global);
read::run(args, &global)
}
Command::Explain(args) => {
load_project_config(&mut global);
explain::run(args, &global)
}
Command::Undo(args) => {
load_project_config(&mut global);
undo::run(args, &global)
}
Command::Search(args) => {
load_project_config(&mut global);
search::run(args, &global)
}
Command::Status(args) => {
load_project_config(&mut global);
status::run(args, &global)
}
Command::Append(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
append::run(args, &global)
}
Command::Prepend(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
prepend::run(args, &global)
}
Command::Create(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
create::run(args, &global)
}
Command::Delete(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
delete::run(args, &global)
}
Command::Rename(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
rename::run(args, &global)
}
Command::Replace(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
replace::run(args, &global)
}
Command::Patch(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
patch::run(args, &global)
}
Command::Md(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
md::run(args, &global)
}
Command::Doc(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
doc::run(args, &global)
}
Command::Tidy(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
tidy::run(args, &global)
}
Command::Tx(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
tx::run(args, &global)
}
Command::Batch(args) => {
global.merge_write(&args.write);
load_project_config(&mut global);
batch::run(args, &global)
}
#[cfg(feature = "ast")]
Command::Ast(args) => {
match args.command {
ast::AstCommand::Rename(ref a) => global.merge_write(&a.write),
ast::AstCommand::Replace(ref a) => global.merge_write(&a.write),
_ => {}
}
load_project_config(&mut global);
ast::run(args, &global)
}
}
}