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.
1.0.108: kicad_move_footprint accepts Adom Bridge's call options (timeout), closes #142 #73
1.0.108: kicad_move_footprint accepts Adom Bridge's call options (timeout), closes #142
1.0.107 made kicad_move_footprint refuse arguments it does not read (PR #70). The Adom Bridge CLI 2.1.189 sends timeout, its per-call budget in seconds, in the arguments of every call, so every move through the CLI was refused with unknown_argument 'timeout', even a dry run. AI Flow's place land and land moves could not land a placement live.
- The move's top level also accepts Adom Bridge's call options that every verb takes: timeout, responseMode and streamTimeoutSeconds. kicad_align_parts passes timeout on to the move as well.
- A misspelled key is still refused: rot, angle and the rest come back as unknown_argument with suggestedKey.
Tested: the issue's call (filePath, ref, x, y, dryRun plus timeout) plans; the real-call test now also carries timeout, responseMode and streamTimeoutSeconds. All workspace tests pass.
closes #142
🤖 Generated with Claude Code
Diff Skip to comments
@@ -1,1992 +1,2000 @@⋯ 574 unchanged lines ⋯ /// 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('_')⋯ 829 unchanged lines ⋯ // 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();⋯ 5 unchanged lines ⋯ 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"); } ⋯ 550 unchanged lines ⋯ assert!(!outlines_overlap(&rect(0.0, 0.0, 1.0, 1.0), &rect(1.0, 0.0, 2.0, 1.0))); } }+@@ -1,27 +1,28 @@⋯ 2 unchanged lines ⋯ members = ["crates/*"] [workspace.package]-version = "1.0.107"+version = "1.0.108" edition = "2021" license = "MIT" publish = false⋯ 15 unchanged lines ⋯ codegen-units = 1 strip = true panic = "abort"+@@ -1,1307 +1,1308 @@⋯ 318 unchanged lines ⋯ [[package]] name = "kicad-bridge"-version = "1.0.107"+version = "1.0.108" dependencies = [ "adom-eda-checks", "kicad-core",⋯ 5 unchanged lines ⋯ [[package]] name = "kicad-core"-version = "1.0.107"+version = "1.0.108" dependencies = [ "kicad-ipc-rs", "kicad-platform",⋯ 20 unchanged lines ⋯ [[package]] name = "kicad-platform"-version = "1.0.107"+version = "1.0.108" dependencies = [ "serde", "serde_json",⋯ 940 unchanged lines ⋯ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"+
Comments
Log in to comment.
No comments yet.