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
Merge PR #469: 1.0.108: kicad_move_footprint accepts Adom Bridge's call options (timeout), closes #142
3 files changed
+17−10
rust/Cargo.lock+3−3@@ -319,7 +319,7 @@ dependencies = [ [[package]] name = "kicad-bridge"-version = "1.0.107"+version = "1.0.108" dependencies = [ "adom-eda-checks", "kicad-core",@@ -331,7 +331,7 @@ dependencies = [ [[package]] name = "kicad-core"-version = "1.0.107"+version = "1.0.108" dependencies = [ "kicad-ipc-rs", "kicad-platform",@@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "kicad-platform"-version = "1.0.107"+version = "1.0.108" dependencies = [ "serde", "serde_json",
rust/Cargo.toml+1−1@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"] [workspace.package]-version = "1.0.107"+version = "1.0.108" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-core/src/placement.rs+13−6@@ -575,9 +575,12 @@ pub const MOVE_KEYS: &[&str] = &[ /// The keys of one `refs[]` entry. pub const MOVE_ENTRY_KEYS: &[&str] = &["ref", "x", "y", "rotation", "side"]; /// Keys any verb may carry that are not about the move: the asker's reason and identity, which-/// Adom Bridge and AI clients put in the arguments of every call. Keys starting with `_` are the-/// bridge's own notes (`_fromFrame` after a `frame:"standard"` call), also accepted.-const CALL_KEYS: &[&str] = &["reason", "caller", "aiThread"];+/// Adom Bridge and AI clients put in the arguments of every call, and Adom Bridge's own call+/// options that every verb accepts: `timeout` (the per-call budget in seconds, which the CLI+/// sends on every call since 2.1.189, wiki #142), `responseMode` and `streamTimeoutSeconds`.+/// Keys starting with `_` are the bridge's own notes (`_fromFrame` after a `frame:"standard"`+/// call), also accepted.+const CALL_KEYS: &[&str] = &["reason", "caller", "aiThread", "timeout", "responseMode", "streamTimeoutSeconds"]; fn move_key_allowed(key: &str) -> bool { MOVE_KEYS.contains(&key) || CALL_KEYS.contains(&key) || key.starts_with('_')@@ -1413,7 +1416,9 @@ mod tests { // frame:"standard" has become _fromFrame, and helpers pass ipcTimeoutMs. let b = board(&[fp("Q2", 110.0, 110.0, 0.0, "F.Cu", RECT, "")]); let call = json!({"filePath": "C:/p/b.kicad_pcb", "ref": "Q2", "x": 120, "y": -110, "rotation": 90, "frame": "standard",- "dryRun": true, "reason": "move Q2 beside the connector", "caller": {"thread": "t"}, "aiThread": "t", "ipcTimeoutMs": 20000});+ "dryRun": true, "reason": "move Q2 beside the connector", "caller": {"thread": "t"}, "aiThread": "t", "ipcTimeoutMs": 20000,+ // Adom Bridge's call options: the CLI sends timeout on every call (wiki #142)+ "timeout": 130, "responseMode": "wait", "streamTimeoutSeconds": 600}); let native = crate::board_model::args_to_kicad_frame(&call).unwrap(); assert_eq!(native["_fromFrame"], json!("standard")); let plan = plan_moves(&b, &native).unwrap();@@ -1425,15 +1430,17 @@ mod tests { assert_eq!(e.code, "unknown_argument"); // kicad_align_parts hands its own arguments on: only the move's survive let align = json!({"filePath": "C:/p/b.kicad_pcb", "refs": [{"ref": "Q2", "x": 120, "y": 110}], "mode": "top", "by": "anchor", "to": 4,- "spacing": 2, "source": "live", "dryRun": true, "reason": "line them up", "_fromFrame": "standard"});+ "spacing": 2, "source": "live", "dryRun": true, "reason": "line them up", "_fromFrame": "standard", "timeout": 130}); let kept = move_args_only(&align); for k in ["mode", "by", "to", "spacing", "source"] { assert!(kept.get(k).is_none(), "{k}"); }- for k in ["filePath", "refs", "dryRun", "reason", "_fromFrame"] {+ for k in ["filePath", "refs", "dryRun", "reason", "_fromFrame", "timeout"] { assert!(kept.get(k).is_some(), "{k}"); } assert!(plan_moves(&b, &kept).is_ok());+ // wiki #142: the issue's call as the CLI sends it+ assert!(plan_moves(&b, &json!({"filePath": "/Users/u/x/x.kicad_pcb", "ref": "Q2", "x": 120, "y": 110, "dryRun": true, "timeout": 130})).is_ok()); assert_eq!(plan_moves(&b, &align).unwrap_err().code, "unknown_argument"); }