app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
← Commit history
1.0.17: NATIVE (Rust) build. 1.0.17: a restart that falls back to the kill reports gracefulClose, the reason the polite close did not work (wiki #48).
3 files changed
+10−6
rust/Cargo.lock+3−3@@ -244,7 +244,7 @@ dependencies = [ [[package]] name = "kicad-bridge"-version = "1.0.16"+version = "1.0.17" dependencies = [ "kicad-core", "kicad-platform",@@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "kicad-core"-version = "1.0.16"+version = "1.0.17" dependencies = [ "kicad-ipc-rs", "kicad-platform",@@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "kicad-platform"-version = "1.0.16"+version = "1.0.17" dependencies = [ "serde", "serde_json",
rust/Cargo.toml+1−1@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"] [workspace.package]-version = "1.0.16"+version = "1.0.17" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-bridge/src/verbs_windows.rs+6−2@@ -3097,6 +3097,7 @@ fn rescan_libraries(state: &mut State, args: &Value) -> Value { // monitor choice is captured here, while the windows still exist, and restored below. let remembered = remember_placement(); let mut close_how = "nothing was running";+ let mut graceful_failure = Value::Null; if !running.is_empty() { // Wiki #48 ask 3: graceful first, so KiCad writes its own geometry and its own files; // the kill is the fallback for a window that will not go.@@ -3107,10 +3108,13 @@ fn rescan_libraries(state: &mut State, args: &Value) -> Value { return json!({"success": false, "errorCode": "restart_close_failed", "close": closed, "_hint": "KiCad is asking whether to save the user's work, so nothing was closed or killed. Ask them, then save (or call kicad_close {\"discardChanges\": true}) before restarting."}); }+ // Keep WHY the graceful close failed: otherwise the kill overwrites the only+ // evidence and the next person sees "force-kill" with no cause.+ graceful_failure = json!({"errorCode": closed.get("errorCode").cloned().unwrap_or(Value::Null), "error": closed.get("error").cloned().unwrap_or(Value::Null), "output": closed.get("output").cloned().unwrap_or(Value::Null)}); closed = dispatch(state, "kicad_close", &json!({"force": true})).unwrap_or_else(|| json!({})); close_how = "force-kill after the graceful close failed"; if !closed["success"].as_bool().unwrap_or(false) {- return json!({"success": false, "errorCode": "restart_close_failed", "close": closed, "closeHow": close_how});+ return json!({"success": false, "errorCode": "restart_close_failed", "close": closed, "closeHow": close_how, "gracefulClose": graceful_failure}); } } std::thread::sleep(std::time::Duration::from_secs(4));@@ -3127,7 +3131,7 @@ fn rescan_libraries(state: &mut State, args: &Value) -> Value { let restored = restore_placement(); let moved = restored.iter().filter(|r| r["moved"] == json!(true)).count(); return json!({"success": true, "restarted": true, "ready": true, "method": "process-restart",- "placementRemembered": remembered, "placementRestored": restored, "closeHow": close_how,+ "placementRemembered": remembered, "placementRestored": restored, "closeHow": close_how, "gracefulClose": graceful_failure, "_hint": format!("Library caches rebuilt. Every part installed before this call is now visible; show verbs will not trigger another restart until the next install-while-open. Placement: {moved} window(s) put back where the user had them (wiki #48), without activating anything.")}); } }