diff options
Diffstat (limited to 'src/cli')
| -rw-r--r-- | src/cli/pane.rs | 195 |
1 files changed, 192 insertions, 3 deletions
diff --git a/src/cli/pane.rs b/src/cli/pane.rs index 23218a4a..d759fa0d 100644 --- a/src/cli/pane.rs +++ b/src/cli/pane.rs @@ -1,7 +1,7 @@ use crate::api::schema::{ Method, PaneListParams, PaneReadParams, PaneRenameParams, PaneReportAgentParams, - PaneSendInputParams, PaneSendKeysParams, PaneSendTextParams, PaneSplitParams, PaneTarget, - ReadFormat, ReadSource, Request, + PaneReportMetadataParams, PaneSendInputParams, PaneSendKeysParams, PaneSendTextParams, + PaneSplitParams, PaneTarget, ReadFormat, ReadSource, Request, }; pub(super) fn run_pane_command(args: &[String]) -> std::io::Result<i32> { @@ -20,6 +20,7 @@ pub(super) fn run_pane_command(args: &[String]) -> std::io::Result<i32> { "send-text" => pane_send_text(&args[1..]), "send-keys" => pane_send_keys(&args[1..]), "report-agent" => pane_report_agent(&args[1..]), + "report-metadata" => pane_report_metadata(&args[1..]), "run" => pane_run(&args[1..]), "help" | "--help" | "-h" => { print_pane_help(); @@ -387,7 +388,10 @@ fn pane_report_agent(args: &[String]) -> std::io::Result<i32> { } } - let Some(source) = source else { + let Some(source) = source.and_then(|source| { + let source = source.trim().to_string(); + (!source.is_empty()).then_some(source) + }) else { eprintln!("missing required --source"); return Ok(2); }; @@ -413,6 +417,190 @@ fn pane_report_agent(args: &[String]) -> std::io::Result<i32> { })) } +fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> { + let Some(raw_pane_id) = args.first() else { + eprintln!("usage: herdr pane report-metadata <pane_id> --source ID [--agent LABEL] [--applies-to-source ID] [--title TEXT|--clear-title] [--display-agent TEXT|--clear-display-agent] [--custom-status TEXT|--clear-custom-status] [--state-label STATUS=TEXT] [--clear-state-labels] [--seq N] [--ttl-ms N]"); + return Ok(2); + }; + + let pane_id = super::normalize_pane_id(raw_pane_id); + let mut source = None; + let mut agent = None; + let mut applies_to_source = None; + let mut title = None; + let mut display_agent = None; + let mut custom_status = None; + let mut state_labels = std::collections::HashMap::new(); + let mut clear_title = false; + let mut clear_display_agent = false; + let mut clear_custom_status = false; + let mut clear_state_labels = false; + let mut seq = None; + let mut ttl_ms = None; + + let mut index = 1; + while index < args.len() { + match args[index].as_str() { + "--source" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --source"); + return Ok(2); + }; + source = Some(value.clone()); + index += 2; + } + "--agent" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --agent"); + return Ok(2); + }; + agent = Some(value.clone()); + index += 2; + } + "--applies-to-source" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --applies-to-source"); + return Ok(2); + }; + applies_to_source = Some(value.clone()); + index += 2; + } + "--title" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --title"); + return Ok(2); + }; + title = Some(value.clone()); + index += 2; + } + "--clear-title" => { + clear_title = true; + index += 1; + } + "--display-agent" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --display-agent"); + return Ok(2); + }; + display_agent = Some(value.clone()); + index += 2; + } + "--clear-display-agent" => { + clear_display_agent = true; + index += 1; + } + "--custom-status" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --custom-status"); + return Ok(2); + }; + custom_status = Some(value.clone()); + index += 2; + } + "--clear-custom-status" => { + clear_custom_status = true; + index += 1; + } + "--state-label" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --state-label"); + return Ok(2); + }; + let Some((status, label)) = value.split_once('=') else { + eprintln!("expected --state-label STATUS=TEXT"); + return Ok(2); + }; + let status = status.trim().to_ascii_lowercase(); + if !matches!( + status.as_str(), + "idle" | "working" | "blocked" | "done" | "unknown" + ) { + eprintln!("unknown state label: {status}"); + return Ok(2); + } + state_labels.insert(status, label.to_string()); + index += 2; + } + "--clear-state-labels" => { + clear_state_labels = true; + index += 1; + } + "--seq" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --seq"); + return Ok(2); + }; + seq = Some(super::parse_u64_flag("--seq", value)?); + index += 2; + } + "--ttl-ms" => { + let Some(value) = args.get(index + 1) else { + eprintln!("missing value for --ttl-ms"); + return Ok(2); + }; + ttl_ms = Some(super::parse_u64_flag("--ttl-ms", value)?); + index += 2; + } + other => { + eprintln!("unknown option: {other}"); + return Ok(2); + } + } + } + + let Some(source) = source.and_then(|source| { + let source = source.trim().to_string(); + (!source.is_empty()).then_some(source) + }) else { + eprintln!("missing required --source"); + return Ok(2); + }; + if applies_to_source + .as_deref() + .is_some_and(|source| source.trim().is_empty()) + { + eprintln!("missing value for --applies-to-source"); + return Ok(2); + } + if title.is_some() && clear_title + || display_agent.is_some() && clear_display_agent + || custom_status.is_some() && clear_custom_status + || !state_labels.is_empty() && clear_state_labels + { + eprintln!("cannot set and clear the same metadata field"); + return Ok(2); + } + if title.is_none() + && display_agent.is_none() + && custom_status.is_none() + && state_labels.is_empty() + && !clear_title + && !clear_display_agent + && !clear_custom_status + && !clear_state_labels + { + eprintln!("missing metadata field to set or clear"); + return Ok(2); + } + + super::send_ok_request(Method::PaneReportMetadata(PaneReportMetadataParams { + pane_id, + source, + agent, + applies_to_source, + title, + display_agent, + custom_status, + state_labels, + clear_title, + clear_display_agent, + clear_custom_status, + clear_state_labels, + seq, + ttl_ms, + })) +} + fn print_pane_help() { eprintln!("herdr pane commands:"); eprintln!(" herdr pane list [--workspace <workspace_id>]"); @@ -426,5 +614,6 @@ fn print_pane_help() { eprintln!(" herdr pane send-text <pane_id> <text>"); eprintln!(" herdr pane send-keys <pane_id> <key> [key ...]"); eprintln!(" herdr pane report-agent <pane_id> --source ID --agent LABEL --state idle|working|blocked|unknown [--message TEXT] [--custom-status TEXT] [--seq N] [--agent-session-id ID] [--agent-session-path PATH]"); + eprintln!(" herdr pane report-metadata <pane_id> --source ID [--agent LABEL] [--applies-to-source ID] [--title TEXT|--clear-title] [--display-agent TEXT|--clear-display-agent] [--custom-status TEXT|--clear-custom-status] [--state-label STATUS=TEXT] [--clear-state-labels] [--seq N] [--ttl-ms N]"); eprintln!(" herdr pane run <pane_id> <command>"); } |
