← Commit history

Update 5 file(s)

John Lauer ·ffaddff4b9 ·1mo ago ·parent ed4a185
5 files changed +191−8
SKILL.md+73−5
@@ -100,11 +100,76 @@ If you pass a version that's not installed, the bridge returns a hint listing th | `kicad_click` | `click` | Send a click at (x, y) in a KiCad window | `hwnd`, `x`, `y` | | `kicad_adom_library_status` | `adom_library_status` | Report whether the Adom shared library is registered | — | +## The `show_*` family — START HERE for "show me X"++**These are the verbs a user's words map onto, and they were missing from this+skill entirely until 2026-08-27.** When someone says *"show me the board in+3D"*, reach for `kicad_show_3d_board`, not a hand-rolled open+screenshot. Each+one opens the right editor, brings the right thing up, and returns a captured+frame, so a single call is both the action and the proof.++| CLI form | Shows | Key args | Pitfall (from the verb's own catalog) |+|---|---|---|---|+| `kicad_show_project` | The whole project in the Project Manager (top of the design tree) | `filePath` (.kicad_pro) | absolute Windows path; no `%VAR%` expansion |+| `kicad_show_schematic` | The schematic (2D) in the Schematic Editor | `filePath` (.kicad_sch) | absolute Windows path; no `%VAR%` expansion |+| `kicad_show_2d_board` | The 2D layout in the PCB Editor | `filePath` (.kicad_pcb) | absolute Windows path; no `%VAR%` expansion |+| `kicad_show_3d_board` | The whole board in 3D | `filePath` | the 3D render self-raises late on slow boxes; the focus guardian handles it |+| `kicad_show_3d_chip` | A single part in 3D (the footprint's 3D view) | `libraryName`, `footprintName` | software-OpenGL boxes render slowly; the window can self-raise late (guarded) |+| `kicad_show_symbol` | A schematic symbol in the Symbol Editor | `libraryName`, `symbolName` | the symbol must be in an INSTALLED sym-lib-table library |+| `kicad_show_footprint` | A footprint in the Footprint Editor | `libraryName`, `footprintName` | a cold Footprint Editor spawns a fresh pcbnew and loads every fp lib — allow 20-30s |+| `kicad_show_library` | A symbol/footprint library, no part loaded | `libraryName` | the library must be registered in the sym-/fp-lib-table |++Two things that are true of every `show_*` verb and are worth knowing once:++- **They open windows in the BACKGROUND** and never steal the user's focus. A+  late self-raise is expected on slow boxes and is caught by the focus guardian.+- **A green `success` is not proof the right thing is on screen.** Issues #42 and+  #62 were both "success:true while the PREVIOUS part is still displayed".+  Check `resolvedSymbol` / the returned frame before you tell a user what they+  are looking at, especially in a batch.++## Exports, linting and settings++| CLI form | Purpose | Key args |+|---|---|---|+| `kicad_export_step` | STEP 3D model from a board | `filePath` |+| `kicad_export_svg` | SVG plot from a board/schematic | `filePath` |+| `kicad_export_pdf` | PDF plot from a board/schematic | `filePath` |+| `kicad_export_gerber` | Gerbers from a board (via kicad-cli) | `filePath` |+| `kicad_export_bom_csv` | BOM CSV from a schematic | `filePath` |+| `kicad_export_part` | One-off single-part export: a `.kicad_sym` with ONLY that symbol, a `.pretty` with ONLY that footprint | `libraryName`, part name |+| `kicad_export_molecule` | One-shot molecule pack: STEP + silk renders + sch/pro discovery (Adom molecule pipeline) | project/part |+| `kicad_lint_board` | DRC pre-check on a `.kicad_pcb` (kicad-cli, read-only) | `filePath` |+| `kicad_lint_schematic` | ERC pre-check on a `.kicad_sch` (kicad-cli, read-only) | `filePath` |+| `kicad_lint_library` | Lint a symbol/footprint library | `libraryPath` |+| `kicad_run_erc` | Run ERC on a schematic (read-only) | `filePath` |+| `kicad_format_upgrade` | Upgrade a file to the current KiCad file format | `filePath` |+| `kicad_get_settings` | Read the bridge's user-visible settings (overlay badges, ...) | — |+| `kicad_set_settings` | Change bridge settings; applies immediately to live windows | settings keys |+| `kicad_place_footprint` | Deterministically place a footprint into a board preview | `fileName`, `fileContent`, `footprintName`, `x`, `y`, `open` |+| `kicad_list_footprints` | List footprints in a library | `libraryName` |+| `kicad_make_part_project` | Generate a small real project (pro/sch/pcb) AROUND an installed Adom-library part | part name |+| `kicad_install_library_bundle` | Install a wiki Cloud Library bundle zip (symbols + footprints + 3D models) in ONE call | `zipPath`, optional `libraryName`, `capture`, `closeEditor` |++## Diagnostics and internals++| CLI form | Purpose |+|---|---|+| `kicad_status` | Bridge/host-app status — the verb Bridge polls after a non-terminal timeout |+| `kicad_progress` | Structured progress for a long-running background job |+| `kicad_verb_times` | Measured per-verb timing history for THIS machine |+| `kicad_diagnostics` | Read-only self-inspection (env, detection breakdown, processes, path probe) |+| `kicad_plugin_diagnose` | Why is the reverse-bridge plugin not loading? One call, every artifact |+| `kicad_install_plugin` | Install the reverse-bridge plugin into KiCad (idempotent) |+| `kicad_bridge_status` | Probe running KiCad plugin instances (multi-instance health) |+| `kicad_bridge_call` | Low-level IPC into a live pcbnew/eeschema — `bridge_status` FIRST to find a live instance |+| `kicad_demo` | Six-beat showcase tour: staged, or a background job with percent/ETA progress |+ ## Quick examples  ```bash # Open a schematic-adom-bridge kicad_open_schematic '{"path":"C:/designs/foo.kicad_sch"}'+adom-bridge kicad_open_schematic '{"filePath":"C:/designs/foo.kicad_sch"}'  # List open KiCad windows adom-bridge kicad_window_info '{}'@@ -113,14 +178,17 @@ adom-bridge kicad_window_info '{}' adom-bridge kicad_screenshot_all '{}'  # Run DRC-adom-bridge kicad_run_drc '{"board_path":"C:/designs/foo.kicad_pcb"}'+adom-bridge kicad_run_drc '{"filePath":"C:/designs/foo.kicad_pcb"}'  # Install a library pair adom-bridge kicad_install_library '{-  "name":"my-lib",-  "sym_path":"C:/libs/my-lib.kicad_sym",-  "fp_path":"C:/libs/my-lib.pretty"+  "libraryName":"my-lib",+  "libraryPath":"C:/libs/my-lib.kicad_sym",+  "libraryType":"symbol" }'++# Show a part in 3D (one call = the action AND the proof frame)+adom-bridge kicad_show_3d_chip '{"libraryName":"Adom","footprintName":"QFN-56-1EP_7x7mm"}' ```  ## Error shape
install.sh+1−1
@@ -4,7 +4,7 @@ H="$(cd "$(dirname "$0")"&&pwd)" D="$HOME/.claude/skills" mkdir -p "$D/kicad-bridge" cp -f "$H/SKILL.md" "$D/kicad-bridge/SKILL.md"-for sk in kicad-interaction kicad-3d-models kicad-tour kicad-bridge-dev kicad-bridge-publish kicad-bridge-hero kicad-bridge-test kicad-bridge-background; do+for sk in kicad-interaction kicad-3d-models kicad-tour kicad-web-control kicad-bridge-dev kicad-bridge-publish kicad-bridge-hero kicad-bridge-test kicad-bridge-background; do   mkdir -p "$D/$sk"   cp -f "$H/skills/$sk/SKILL.md" "$D/$sk/SKILL.md" done
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "kicad-bridge",-  "version": "1.0.104",+  "version": "1.0.105",   "type": "app",   "description": "Skills for your container so your AI knows how to drive the KiCad bridge. The bridge runtime itself is the release zip; Adom Bridge loads that.",   "tags": [
page.json+1−1
@@ -4,7 +4,7 @@   "slug": "kicad-bridge",   "title": "KiCad - the KiCad Bridge",   "brief": "Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.",-  "version": "1.0.104",+  "version": "1.0.105",   "tags": [     "kicad",     "pcb",
skills/kicad-web-control/SKILL.mdadded+115
@@ -0,0 +1,115 @@+---+name: kicad-web-control+description: >+  The no-AI lane: how a wiki page drives KiCad through Adom Bridge web control,+  calling the SAME core verbs an AI calls directly. Covers staging a file onto the+  user's machine over the transport (write_file / write_file_chunk), the one-verb+  Cloud Library bundle install, the capture/proof contract, and the restart contract+  that never closes a user's KiCad. Read before wiring any web page to a kicad_*+  verb, before rendering install status or a proof frame in a page, or when a verb+  returns restartNeeded or proofSkipped. Trigger words - web control, webcontrol,+  no-AI lane, cloud library, cloud libraries export, install library bundle,+  kicad_install_library_bundle, installLibraryBundle, stage a zip, write_file_chunk,+  restartNeeded, proofSkipped, thumbnailDataUrl, wiki export button, one-verb install.+discovery_triggers:+  - "kicad web control"+  - "install a cloud library into kicad"+  - "kicad_install_library_bundle"+  - "wiki export to kicad"+user-invocable: true+---++# KiCad over web control — the no-AI lane++A wiki page can drive KiCad on the user's machine directly, with **no AI in the+loop**. It uses the same `kicad_*` verbs documented in the parent+`adom-desktop-kicad` skill; the only difference is who calls them. Read this+before wiring a page to a verb, and read it before you assume a page needs an+agent at all — most "install this into KiCad" flows do not.++## The lane, in order++1. **The page fetches the artifact** (for a Cloud Library, a bundle zip).+2. **The page stages it onto the machine** over the web-control transport with+   `write_file`, or `write_file_chunk` for anything large. There is no+   container-to-Windows push verb; staging IS the transport.+3. **The page calls one core verb** with the staged path.+4. **The page renders what came back** — including the proof frame, if it asked+   for one.++The reference implementation is `installLibraryBundle` in git-wiki+`static/webcontrol.js`. Copy its shape rather than inventing a new one.++## The one-verb install++`kicad_install_library_bundle` takes a zip holding `<Lib>.kicad_sym` ++`<Lib>.pretty/` + `3dmodels/` and does the whole install: symbols, footprints,+3D models with model-ref rewriting, and both lib-table registrations.++```bash+adom-bridge --ai-thread "<thread>" kicad_install_library_bundle '{+  "zipPath": "C:/Users/you/AppData/Local/Temp/mylib.zip",+  "libraryName": "MyLib",+  "capture": true+}'+```++| Arg | Meaning |+|---|---|+| `zipPath` | the staged zip (absolute Windows path) |+| `libraryName` | optional; defaults to the zip's stem. Must match `^[A-Za-z0-9][A-Za-z0-9 ._-]{0,63}$` — the name becomes directory names and lib-table entries |+| `capture` | `true` asks for a proof frame (see below) |+| `captureMaxWidth` | cap the proof image size |+| `closeEditor` | close the editor the verb opened for the proof |++It finds the three parts **regardless of a wrapping folder**, so a zip made by+"compress this directory" works. It is hardened for untrusted input: a zip-slip+guard rejects absolute paths, drive letters, `..` escapes and backslash tricks,+and caps apply at **256MB zipped / 512MB unpacked**.++## The restart contract — it never closes the user's KiCad++The verb reports, it does not act:++```+{ "symbols": N, "footprints": N, "modelsInstalled": N, "modelRefsRewritten": N,+  "kicadRunning": true, "restartNeeded": true }+```++`restartNeeded` mirrors `kicadRunning`, because a KiCad that was already open+predates the install and cannot see the new library until it restarts. **A+running KiCad is never closed for you.** The page (or the AI) tells the user;+deciding to close their editor is not the verb's call to make.++## The proof contract — `capture` and `proofSkipped`++With `capture: true` and **only when KiCad was not already running**, the verb+opens the Symbol Editor on the new library in the background, returns a frame as+`thumbnailDataUrl`, and closes the editor it opened. The wiki export flow renders+that frame under the install status, so the user sees the thing that was+installed rather than a success message about it.++When a frame is impossible, `proofSkipped` names why instead of failing the+install — for example `"kicad_running: the open KiCad predates the install;+restart to see the library"`. **A capture failure never turns a successful+install into a failure.** Read `proofSkipped` and say why there is no picture.++## Focus: the proof window can never land on top of the user++The verb is registered in `_SPAWNS_WINDOW` and `_SPAWNS_WINDOW_FOCUS` in+`server.py`, so the proof window rides the focus guardian: it gets the settle+poll, and the user's foreground window is restored afterwards. If you add a verb+that raises a KiCad window, register it in both sets or it WILL steal focus.++## Every call needs a caller identity++Web control does not exempt you. A `kicad_*` call with no `aiThread` is refused+with `caller_identity_required` — it will not even raise an approval prompt,+because the user must be able to see which tab is driving their machine. Pass+`--ai-thread "<name>"` (or `caller.aiThread`) on every call.++## Related++- `adom-desktop-kicad` — the parent skill and the full verb catalog.+- `control-api-proxy` — proxying control routes without CORS or a hardcoded port.+- `fusion-web-control` — the sibling lane for Fusion 360; same shape, same rules.