diff --git a/crates/buzz-cli/src/commands/messages.rs b/crates/buzz-cli/src/commands/messages.rs index 40a9ae80b5..11ec176380 100644 --- a/crates/buzz-cli/src/commands/messages.rs +++ b/crates/buzz-cli/src/commands/messages.rs @@ -818,13 +818,19 @@ pub async fn cmd_edit_message( content: &str, ) -> Result<(), CliError> { validate_hex64(event_id)?; - validate_content_size(content)?; + // Mirror `cmd_send_message`: `--content -` reads the replacement body + // from stdin, so multiline answers and shell-metacharacter-heavy text + // don't need to be jammed through argv. Without this, a literal "-" + // silently replaces the message with a single dash and the edit + // publishes with `accepted: true`. + let content = read_or_stdin(content)?; + validate_content_size(&content)?; // Resolve channel_id from the event's h-tag let channel_uuid = resolve_channel_id(client, event_id).await?; let target_eid = parse_event_id(event_id)?; - let builder = buzz_sdk::build_edit(channel_uuid, target_eid, content) + let builder = buzz_sdk::build_edit(channel_uuid, target_eid, &content) .map_err(|e| CliError::Other(format!("build_edit failed: {e}")))?; let event = client.sign_event(builder)?; diff --git a/crates/buzz-cli/src/validate.rs b/crates/buzz-cli/src/validate.rs index 4985b44141..d0de301ff5 100644 --- a/crates/buzz-cli/src/validate.rs +++ b/crates/buzz-cli/src/validate.rs @@ -476,6 +476,16 @@ mod tests { assert_eq!(super::read_or_stdin("").unwrap(), ""); } + #[test] + fn read_or_stdin_dash_reads_stdin_not_literal_dash() { + // Regression for the edit-vs-send mismatch in #4361: callers passing + // "-" expected stdin to be read, not the literal "-" published. A + // test runner's stdin is empty (or closed), so `read_to_string` returns + // Ok("") — the point is that the result is *not* the literal "-". + let got = super::read_or_stdin("-").unwrap(); + assert_ne!(got, "-", "`-` must be treated as a stdin marker, not content"); + } + // --- read_file_or_stdin --- #[test]