Setup creates Pi's mcp.json when it doesn't exist yet (#268)

Pi rejects an empty `mcp.json`, so setup marks Pi as "empty is invalid". The check also ran when the file didn't exist yet: its absent text read as empty, the plan was blocked ("the file is empty, and this app requires valid JSON"), and `setup --all-detected --yes` stopped with it.

A missing file now starts from `{}` and is created with our `mcpServers` entry. An existing empty file is still refused. The preview of a new file shows only the added lines.

**Verified:** a new setup test where Pi's folder exists without `mcp.json`: the plan isn't blocked, apply writes a valid file with our entry, and an empty file is still blocked. `cargo test -p craft-anything-setup` (24), clippy, fmt.

Fixes #238
This commit is contained in:
BFlat
2026-11-02 14:00:39 +07:00
committed by GitHub
parent 6f5cacc80f
commit 8071522b3d
2 changed files with 19 additions and 2 deletions
+3 -2
View File
@@ -148,7 +148,8 @@ pub fn inspect_client(c: &Client, command: &[String]) -> Action {
return a;
}
};
let base = text.clone().unwrap_or_default();
// A missing file is created; only an existing empty one is invalid where empty is (#238).
let base = text.clone().unwrap_or_else(|| if c.empty_is_invalid { "{}".into() } else { String::new() });
let existing = match config::read_entry(c, &base) {
Ok(e) => e,
Err(e) => {
@@ -169,7 +170,7 @@ pub fn inspect_client(c: &Client, command: &[String]) -> Action {
}
match config::set_entry(c, &base, &desired) {
Ok(new) => {
a.preview = preview(&base, &new);
a.preview = preview(text.as_deref().unwrap_or_default(), &new);
a.action = if text.is_some() { ActionKind::Update } else { ActionKind::Create };
a.backup = text.as_ref().map(|_| backup_path(&c.config));
a.old_text = text;
+16
View File
@@ -144,6 +144,22 @@ fn malformed_config_blocks_plan_and_uninstall() {
assert!(read(h.join(".cursor/mcp.json")).contains("craft-anything-cli"));
}
/// #238: Pi's folder exists but its mcp.json doesn't yet; setup creates it. An empty file is
/// still refused.
#[test]
fn pi_config_is_created_when_missing() {
let fx = fixture();
let pi = fx.host.home.join(".pi/agent/mcp.json");
std::fs::create_dir_all(pi.parent().unwrap()).unwrap();
let p = plan(&fx.host, &req(&fx, &["pi"])).unwrap();
assert!(!p.blocked, "{p:?}");
assert_eq!(apply(&p).status, "configured");
let v: serde_json::Value = serde_json::from_str(&read(&pi)).unwrap();
assert_eq!(v["mcpServers"]["craft-anything"]["args"][0], "mcp");
std::fs::write(&pi, "").unwrap();
assert!(plan(&fx.host, &req(&fx, &["pi"])).unwrap().blocked);
}
#[test]
fn strict_json_client_rejects_comments() {
let fx = fixture();