From f69861f7e3a983aa76e792e63a836f5b2d421c66 Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen <7456949+mikl0s@users.noreply.github.com> Date: Sat, 10 Oct 2026 18:39:57 +0200 Subject: [PATCH] Cell: cell.set without an input is an error cell.set treated a missing input as an empty string, so a call that forgot the input (or sent it under the wrong key) cleared the cell and reported success. It now returns an error when neither `input` nor `value` is given. An explicit empty string still clears the cell. --- crates/engine/src/cmd/edit.rs | 7 +++++-- crates/mcp/src/tests.rs | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/edit.rs b/crates/engine/src/cmd/edit.rs index bb54fe0..a812c65 100644 --- a/crates/engine/src/cmd/edit.rs +++ b/crates/engine/src/cmd/edit.rs @@ -196,8 +196,11 @@ fn cell_set(s: &mut Session, p: &Json) -> Result { Some(c) => c, None => s.doc()?.selection.active, }; - let input = - str_param(p, "input").or_else(|| str_param(p, "value")).map(str::to_string).or_else(|| p.get("value").map(json_to_input)).unwrap_or_default(); + let input = str_param(p, "input") + .or_else(|| str_param(p, "value")) + .map(str::to_string) + .or_else(|| p.get("value").map(json_to_input)) + .ok_or_else(|| bad("cell.set", "missing `input` (or `value`)"))?; let array = bool_param(p, "array").unwrap_or(false); let protected = s.doc()?.wb.sheet(sheet).is_some_and(|sh| sh.is_protected() && s.doc().is_ok_and(|d| d.wb.styles.get(sh.style_id(at)).protection.locked)); diff --git a/crates/mcp/src/tests.rs b/crates/mcp/src/tests.rs index cf590be..1d4abb4 100644 --- a/crates/mcp/src/tests.rs +++ b/crates/mcp/src/tests.rs @@ -339,6 +339,18 @@ fn serve_loop_over_buffers() { assert!(lines[2]["result"]["content"][0]["text"].as_str().unwrap().contains("42")); } +#[test] +fn cell_set_without_input_is_error() { + let mut s = server(); + ok(&mut s, "set_cell", json!({"cell": "B2", "input": "keep"})); + fails(&mut s, "execute_command", json!({"command": "cell.set", "params": {"cell": "B2"}})); + fails(&mut s, "execute_command", json!({"command": "cell.set", "params": {}})); + assert_eq!(ok(&mut s, "get_cell", json!({"cell": "B2"}))["text"], "keep"); + // An explicit empty string still clears. + ok(&mut s, "execute_command", json!({"command": "cell.set", "params": {"cell": "B2", "input": ""}})); + assert_eq!(ok(&mut s, "get_cell", json!({"cell": "B2"}))["text"], ""); +} + #[test] fn remote_backend_over_tcp() { // A fake app: answers engine.execute by running a headless session; closes after the first