aboutsummaryrefslogtreecommitdiff
path: root/src/cli/integration.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/integration.rs')
-rw-r--r--src/cli/integration.rs142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/cli/integration.rs b/src/cli/integration.rs
new file mode 100644
index 00000000..6239faf2
--- /dev/null
+++ b/src/cli/integration.rs
@@ -0,0 +1,142 @@
+use crate::api::schema::IntegrationTarget;
+
+pub(super) fn run_integration_command(args: &[String]) -> std::io::Result<i32> {
+ let Some(subcommand) = args.first().map(|arg| arg.as_str()) else {
+ print_integration_help();
+ return Ok(2);
+ };
+
+ match subcommand {
+ "install" => integration_install(&args[1..]),
+ "uninstall" => integration_uninstall(&args[1..]),
+ "status" => integration_status(&args[1..]),
+ "help" | "--help" | "-h" => {
+ print_integration_help();
+ Ok(0)
+ }
+ _ => {
+ print_integration_help();
+ Ok(2)
+ }
+ }
+}
+
+fn integration_status(args: &[String]) -> std::io::Result<i32> {
+ let outdated_only = match args {
+ [] => false,
+ [flag] if flag == "--outdated-only" => true,
+ _ => {
+ eprintln!("usage: herdr integration status [--outdated-only]");
+ return Ok(2);
+ }
+ };
+
+ if outdated_only {
+ crate::integration::print_outdated_update_notice();
+ return Ok(0);
+ }
+
+ for status in crate::integration::installed_integration_statuses() {
+ let target = crate::integration::integration_target_label(status.target);
+ let version = match status.installed_version {
+ Some(version) => format!("v{version}"),
+ None => "legacy".to_string(),
+ };
+ let state = match status.state {
+ crate::integration::IntegrationStatusKind::NotInstalled => "not installed".to_string(),
+ crate::integration::IntegrationStatusKind::Current => {
+ format!("current ({version})")
+ }
+ crate::integration::IntegrationStatusKind::Outdated => {
+ format!("outdated ({version} < v{})", status.expected_version)
+ }
+ };
+ println!("{target}: {state} ({})", status.path.display());
+ }
+
+ Ok(0)
+}
+
+fn integration_install(args: &[String]) -> std::io::Result<i32> {
+ let Some(target) = parse_integration_target(args, "install")? else {
+ return Ok(2);
+ };
+
+ match crate::integration::install_target(target) {
+ Ok(messages) => {
+ print_integration_messages(messages);
+ Ok(0)
+ }
+ Err(err) => {
+ eprintln!("{err}");
+ Ok(1)
+ }
+ }
+}
+
+fn integration_uninstall(args: &[String]) -> std::io::Result<i32> {
+ let Some(target) = parse_integration_target(args, "uninstall")? else {
+ return Ok(2);
+ };
+
+ match crate::integration::uninstall_target(target) {
+ Ok(messages) => {
+ print_integration_messages(messages);
+ Ok(0)
+ }
+ Err(err) => {
+ eprintln!("{err}");
+ Ok(1)
+ }
+ }
+}
+
+fn print_integration_messages(messages: Vec<String>) {
+ for message in messages {
+ println!("{message}");
+ }
+}
+
+fn parse_integration_target(
+ args: &[String],
+ action: &str,
+) -> std::io::Result<Option<IntegrationTarget>> {
+ let Some(target) = args.first().map(|arg| arg.as_str()) else {
+ eprintln!("usage: herdr integration {action} <pi|claude|codex|opencode|hermes>");
+ return Ok(None);
+ };
+ if args.len() != 1 {
+ eprintln!("usage: herdr integration {action} <pi|claude|codex|opencode|hermes>");
+ return Ok(None);
+ }
+
+ let parsed = match target {
+ "pi" => IntegrationTarget::Pi,
+ "claude" => IntegrationTarget::Claude,
+ "codex" => IntegrationTarget::Codex,
+ "opencode" => IntegrationTarget::Opencode,
+ "hermes" => IntegrationTarget::Hermes,
+ _ => {
+ eprintln!("unknown integration target: {target}");
+ eprintln!("currently supported: pi, claude, codex, opencode, hermes");
+ return Ok(None);
+ }
+ };
+
+ Ok(Some(parsed))
+}
+
+fn print_integration_help() {
+ eprintln!("herdr integration commands:");
+ eprintln!(" herdr integration install pi");
+ eprintln!(" herdr integration install claude");
+ eprintln!(" herdr integration install codex");
+ eprintln!(" herdr integration install opencode");
+ eprintln!(" herdr integration install hermes");
+ eprintln!(" herdr integration uninstall pi");
+ eprintln!(" herdr integration uninstall claude");
+ eprintln!(" herdr integration uninstall codex");
+ eprintln!(" herdr integration uninstall opencode");
+ eprintln!(" herdr integration uninstall hermes");
+ eprintln!(" herdr integration status [--outdated-only]");
+}