aboutsummaryrefslogtreecommitdiff
path: root/src/cli
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli')
-rw-r--r--src/cli/pane.rs63
-rw-r--r--src/cli/spec.rs19
-rw-r--r--src/cli/workspace.rs91
3 files changed, 136 insertions, 37 deletions
diff --git a/src/cli/pane.rs b/src/cli/pane.rs
index a178eb4b..80e10c69 100644
--- a/src/cli/pane.rs
+++ b/src/cli/pane.rs
@@ -943,7 +943,7 @@ fn pane_run(args: &[String]) -> std::io::Result<i32> {
fn pane_report_agent(args: &[String]) -> std::io::Result<i32> {
let Some(raw_pane_id) = args.first() else {
- eprintln!("usage: 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!("usage: herdr pane report-agent <pane_id> --source ID --agent LABEL --state idle|working|blocked|unknown [--message TEXT] [--seq N] [--agent-session-id ID] [--agent-session-path PATH]");
return Ok(2);
};
@@ -952,7 +952,6 @@ fn pane_report_agent(args: &[String]) -> std::io::Result<i32> {
let mut agent = None;
let mut state = None;
let mut message = None;
- let mut custom_status = None;
let mut seq = None;
let mut agent_session_id = None;
let mut agent_session_path = None;
@@ -992,14 +991,6 @@ fn pane_report_agent(args: &[String]) -> std::io::Result<i32> {
message = Some(value.clone());
index += 2;
}
- "--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;
- }
"--seq" => {
let Some(value) = args.get(index + 1) else {
eprintln!("missing value for --seq");
@@ -1053,7 +1044,6 @@ fn pane_report_agent(args: &[String]) -> std::io::Result<i32> {
agent,
state,
message,
- custom_status,
seq,
agent_session_id,
agent_session_path,
@@ -1224,7 +1214,7 @@ fn pane_release_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]");
+ 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] [--state-label STATUS=TEXT] [--clear-state-labels] [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]");
return Ok(2);
};
@@ -1234,11 +1224,10 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
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 tokens = 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;
@@ -1294,18 +1283,6 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
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");
@@ -1330,6 +1307,29 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
clear_state_labels = true;
index += 1;
}
+ "--token" => {
+ let Some(value) = args.get(index + 1) else {
+ eprintln!("missing value for --token");
+ return Ok(2);
+ };
+ let (key, value) = match super::parse_token_assignment(value) {
+ Ok(token) => token,
+ Err(message) => {
+ eprintln!("{message}");
+ return Ok(2);
+ }
+ };
+ tokens.insert(key, value);
+ index += 2;
+ }
+ "--clear-token" => {
+ let Some(key) = args.get(index + 1) else {
+ eprintln!("missing value for --clear-token");
+ return Ok(2);
+ };
+ tokens.insert(key.clone(), None);
+ index += 2;
+ }
"--seq" => {
let Some(value) = args.get(index + 1) else {
eprintln!("missing value for --seq");
@@ -1369,7 +1369,6 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
}
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");
@@ -1377,11 +1376,10 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
}
if title.is_none()
&& display_agent.is_none()
- && custom_status.is_none()
&& state_labels.is_empty()
+ && tokens.is_empty()
&& !clear_title
&& !clear_display_agent
- && !clear_custom_status
&& !clear_state_labels
{
eprintln!("missing metadata field to set or clear");
@@ -1395,11 +1393,10 @@ fn pane_report_metadata(args: &[String]) -> std::io::Result<i32> {
applies_to_source,
title,
display_agent,
- custom_status,
state_labels,
+ tokens,
clear_title,
clear_display_agent,
- clear_custom_status,
clear_state_labels,
seq,
ttl_ms,
@@ -1433,10 +1430,10 @@ fn print_pane_help() {
eprintln!(" herdr pane close <pane_id>");
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-agent <pane_id> --source ID --agent LABEL --state idle|working|blocked|unknown [--message TEXT] [--seq N] [--agent-session-id ID] [--agent-session-path PATH]");
eprintln!(" herdr pane report-agent-session <pane_id> --source ID --agent LABEL [--seq N] [--agent-session-id ID] [--agent-session-path PATH]");
eprintln!(" herdr pane release-agent <pane_id> --source ID --agent LABEL [--seq N]");
- 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 report-metadata <pane_id> --source ID [--agent LABEL] [--applies-to-source ID] [--title TEXT|--clear-title] [--display-agent TEXT|--clear-display-agent] [--state-label STATUS=TEXT] [--clear-state-labels] [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]");
eprintln!(" herdr pane run <pane_id> <command>");
}
diff --git a/src/cli/spec.rs b/src/cli/spec.rs
index 4c68e3a5..f27eed49 100644
--- a/src/cli/spec.rs
+++ b/src/cli/spec.rs
@@ -160,6 +160,16 @@ fn workspace_command() -> Command {
.arg(required("workspace_id", "WORKSPACE_ID"))
.arg(required("label", "LABEL").num_args(1..)),
)
+ .subcommand(
+ Command::new("report-metadata")
+ .about("Report display-only workspace metadata")
+ .arg(required("workspace_id", "WORKSPACE_ID"))
+ .arg(option("source", "ID"))
+ .arg(repeatable_option("token", "NAME=VALUE"))
+ .arg(repeatable_option("clear-token", "NAME"))
+ .arg(option("seq", "N"))
+ .arg(option("ttl-ms", "N")),
+ )
.subcommand(id_command("close", "workspace_id", "Close a workspace"))
}
@@ -467,7 +477,6 @@ fn report_agent_command() -> Command {
.arg(option("agent", "LABEL"))
.arg(pane_agent_state_option("state"))
.arg(option("message", "TEXT"))
- .arg(option("custom-status", "TEXT"))
.arg(option("seq", "N"))
.arg(option("agent-session-id", "ID"))
.arg(path_option("agent-session-path", "PATH"))
@@ -505,10 +514,10 @@ fn report_metadata_command() -> Command {
.arg(flag("clear-title"))
.arg(option("display-agent", "TEXT"))
.arg(flag("clear-display-agent"))
- .arg(option("custom-status", "TEXT"))
- .arg(flag("clear-custom-status"))
.arg(option("state-label", "STATUS=TEXT"))
.arg(flag("clear-state-labels"))
+ .arg(repeatable_option("token", "NAME=VALUE"))
+ .arg(repeatable_option("clear-token", "NAME"))
.arg(option("seq", "N"))
.arg(option("ttl-ms", "N"))
}
@@ -817,6 +826,10 @@ fn option(name: &'static str, value_name: &'static str) -> Arg {
.action(ArgAction::Set)
}
+fn repeatable_option(name: &'static str, value_name: &'static str) -> Arg {
+ option(name, value_name).action(ArgAction::Append)
+}
+
fn path_option(name: &'static str, value_name: &'static str) -> Arg {
option(name, value_name).value_hint(ValueHint::AnyPath)
}
diff --git a/src/cli/workspace.rs b/src/cli/workspace.rs
index e59a3663..525fc971 100644
--- a/src/cli/workspace.rs
+++ b/src/cli/workspace.rs
@@ -1,6 +1,8 @@
use std::collections::HashMap;
-use crate::api::schema::{WorkspaceCreateParams, WorkspaceRenameParams};
+use crate::api::schema::{
+ Method, WorkspaceCreateParams, WorkspaceRenameParams, WorkspaceReportMetadataParams,
+};
pub(super) fn run_workspace_command(args: &[String]) -> std::io::Result<i32> {
let Some(subcommand) = args.first().map(|arg| arg.as_str()) else {
@@ -14,6 +16,7 @@ pub(super) fn run_workspace_command(args: &[String]) -> std::io::Result<i32> {
"get" => workspace_get(&args[1..]),
"focus" => workspace_focus(&args[1..]),
"rename" => workspace_rename(&args[1..]),
+ "report-metadata" => workspace_report_metadata(&args[1..]),
"close" => workspace_close(&args[1..]),
"help" | "--help" | "-h" => {
print_workspace_help();
@@ -136,6 +139,91 @@ fn workspace_rename(args: &[String]) -> std::io::Result<i32> {
})
}
+fn workspace_report_metadata(args: &[String]) -> std::io::Result<i32> {
+ let Some(raw_workspace_id) = args.first() else {
+ eprintln!("usage: herdr workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]");
+ return Ok(2);
+ };
+ let workspace_id = super::normalize_workspace_id(raw_workspace_id);
+ let mut source = None;
+ let mut tokens = HashMap::new();
+ 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;
+ }
+ "--token" => {
+ let Some(value) = args.get(index + 1) else {
+ eprintln!("missing value for --token");
+ return Ok(2);
+ };
+ let (key, value) = match super::parse_token_assignment(value) {
+ Ok(token) => token,
+ Err(message) => {
+ eprintln!("{message}");
+ return Ok(2);
+ }
+ };
+ tokens.insert(key, value);
+ index += 2;
+ }
+ "--clear-token" => {
+ let Some(key) = args.get(index + 1) else {
+ eprintln!("missing value for --clear-token");
+ return Ok(2);
+ };
+ tokens.insert(key.clone(), None);
+ index += 2;
+ }
+ "--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.filter(|source| !source.trim().is_empty()) else {
+ eprintln!("missing required --source");
+ return Ok(2);
+ };
+ if tokens.is_empty() {
+ eprintln!("missing token to set or clear");
+ return Ok(2);
+ }
+ super::send_ok_request(Method::WorkspaceReportMetadata(
+ WorkspaceReportMetadataParams {
+ workspace_id,
+ source,
+ tokens,
+ seq,
+ ttl_ms,
+ },
+ ))
+}
+
fn workspace_close(args: &[String]) -> std::io::Result<i32> {
let Some(raw_workspace_id) = args.first() else {
eprintln!("usage: herdr workspace close <workspace_id>");
@@ -156,5 +244,6 @@ fn print_workspace_help() {
eprintln!(" herdr workspace get <workspace_id>");
eprintln!(" herdr workspace focus <workspace_id>");
eprintln!(" herdr workspace rename <workspace_id> <label>");
+ eprintln!(" herdr workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]");
eprintln!(" herdr workspace close <workspace_id>");
}