diff --git a/Cargo.lock b/Cargo.lock index 2e2ff8f0..775f1b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -675,7 +675,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openresearch-cli" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index c651a850..04052f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openresearch-cli" -version = "0.1.2" +version = "0.1.3" edition = "2021" description = "OpenResearch CLI (orx) — Rust port" repository = "https://github.com/alphaXiv/openresearch-cli" diff --git a/src/commands/dev.rs b/src/commands/dev.rs index 72ee3d9e..fd17f48c 100644 --- a/src/commands/dev.rs +++ b/src/commands/dev.rs @@ -54,6 +54,11 @@ pub async fn run(args: crate::DevArgs) -> Result<()> { println!("No dev node was open."); return Ok(()); } + // A non-discard close that commits nothing means the session's edits + // never landed (e.g. a str-replace that no-op'd). The node is still torn + // down, but we surface this loudly and exit non-zero so callers chaining + // open/edit/close don't mistake an empty edit for success. + let mut empty_edit = false; if res.committed { let sha = match &res.commit_sha { Some(sha) => { @@ -66,9 +71,17 @@ pub async fn run(args: crate::DevArgs) -> Result<()> { } else if args.discard { println!("Discarded changes."); } else { - println!("Nothing to commit."); + empty_edit = true; } println!("\u{2713} Dev node torn down."); + if empty_edit { + eprintln!( + "\u{26a0} Nothing to commit \u{2014} the working tree was clean. \ + No edits landed this session (did a str-replace/write no-op?). \ + Use `--discard` if an empty close was intended." + ); + std::process::exit(1); + } return Ok(()); } diff --git a/src/main.rs b/src/main.rs index d8844abc..75e47253 100644 --- a/src/main.rs +++ b/src/main.rs @@ -377,7 +377,12 @@ pub struct FsWriteArgs { pub struct FsStrReplaceArgs { pub exp_id: String, pub path: String, + // old/new are arbitrary code strings that routinely begin with `-`/`--` + // (flags, diff markers, CLI snippets). Without this, clap parses them as + // unknown flags and the edit silently never happens. + #[arg(allow_hyphen_values = true)] pub old_string: String, + #[arg(allow_hyphen_values = true)] pub new_string: String, } @@ -390,6 +395,8 @@ pub struct FsLsArgs { #[derive(Args, Debug)] pub struct FsGrepArgs { pub exp_id: String, + // Search patterns can begin with `-` (e.g. `-inf`, `--flag`); take them literally. + #[arg(allow_hyphen_values = true)] pub pattern: String, }