---
name: kicad-bridge-publish
user-invocable: false
description: >-
  DEVELOPER-only PUBLISH skill (user-invocable:false — for maintainers, never offered to everyday users). The exact recipe to ship a new version of the Adom Bridge KiCad bridge to wiki.adom.inc: version lockstep, the zip build, adom-wiki repo push + release create, the skills pkg, pushing to a target Bridge, and verify steps. Trigger words — publish kicad bridge, release kicad bridge, ship kicad bridge, bump kicad bridge, kicad bridge manifest, kicad bridge pkg.
---

# kicad-bridge-publish

How to cut and publish a KiCad-bridge release. **Use the `adom-wiki` CLI for ALL wiki interactions — never raw curl.** Two independent artifacts: the RUNTIME (zip + manifest, on the page `/files`) and the SKILLS PKG (`adom/kicad-bridge`, container-side docs).

## 1. Version lockstep (bump ALL three together)

- `bridge.json` → `"version"`
- `BRIDGE_VERSION` (plain text)
- the manifest JSON → `"version"`

They must match. `bridge.json` also carries `updateManifestUrl` (durable auto-update), `docs` (your page), `homepage` (a **wiki.adom.inc** URL, NEVER github), `detect` (host-app paths incl. `%LocalAppData%\Programs\KiCad`), `verbPrefixes`, complete `verbs[]`, `statusVerb`.

## 2. Build the zip — KEEP IT TINY (it is auto-bundled into Bridge)

The runtime zip ships inside Adom Bridge for **every** user, so it carries ONLY what the
bridge needs to RUN. No docs, no images, no skills, no samples. (Audited 2026-07-15: the zip
had grown to 488.9 KB carrying 219 KB of hero *fonts*, five `skills/` trees, demo scripts and
READMEs — none referenced by runtime code. Slimming it to 335.7 KB was a 31% cut with zero
functional change.)

**KEEP** (runtime-required):
- all `*.py` (server + `handlers/` + `plugin_payload/`)
- `certs/cacert.pem` — Bridge's portable Python has no CA bundle
- `*.ps1` (`launch_editor.ps1`, `navigate_symbol.ps1`) — UIA scripts the handlers shell out to
- `templates/blank-board.kicad_pcb` — read by `handlers/place_footprint.py`
- `bridge.json`, `BRIDGE_VERSION`, `start.bat`, `start.sh`
- root `SKILL.md` ONLY (the runtime skill `adom-desktop-kicad`, `public: true` — Bridge installs it)

**EXCLUDE** (everything else):
`skills/**` (container-side docs — they ship in the PKG, duplicating them here is pure bloat),
`demo/**`, `docs/**`, `tour*/**`, every `*.md` except root `SKILL.md`, every image/font
(`*.png *.jpg *.svg *.gif *.ttf *.otf *.woff*`), every archive/video (`*.zip *.tar.gz *.bundle
*.mp4` — note `mesa-llvmpipe-x64.zip` is 22 MB and must NEVER land in the zip),
`__pycache__`, `*.pyc`, `.git`, `.github`, `node_modules`, `.DS_Store`, and the generated
`adom-bridge-kicad-manifest.json`.

Compute `sha256` + byte `size` for the manifest. **Verify before publishing:** every local
import resolves inside the zip, and the data files above are all present — then deploy and
call `kicad_describe` (verb count) + one data-file-dependent verb on a real target.

Manifest fields: `manifest_version:1, name:"kicad", version, url` (the `/blob/app/.../adom-bridge-kicad-v<ver>.zip`), `sha256, size, verbPrefixes:["kicad_"], healthEndpoint:"/status", released_at, hero, languages`.

## 3. Publish the runtime (CLI)

```bash
adom-wiki repo push adom/kicad-bridge \
  --files adom-bridge-kicad-v<ver>.zip adom-bridge-kicad-manifest.json bridge.json \
  -m "v<ver>: <what changed>"
adom-wiki release create adom/kicad-bridge <ver> \
  --title "KiCad bridge v<ver>" --changelog "..." \
  --binary-path adom-bridge-kicad-v<ver>.zip
```

`repo push` writes the files to the page `/files` (same place Bridge's bridge_cache fetches from). `release create` also registers a proper Release (SDK Artifact 1). For a field with no dedicated verb use `adom-wiki api -X PUT /api/v1/pages/... --body ...`, not curl.

## 4. Publish the skills pkg (container docs)

**The pkg is skills-only — it is NOT the bridge.** The pkg teaches a container agent the `kicad_*`
verbs; the **release zip** is what Bridge downloads and runs as the bridge runtime. Users conflate them
constantly, so say it — but say it in **ONE LINE**.

⚠️ **`description` is rendered inside the page's Install card. Keep it to one or two sentences.**
A paragraph there is worse than saying nothing — it buries the install command in a wall of text.
(Learned the hard way 2026-07-19: a 486-char description explaining the whole two-artifact model
turned the Install card into an unreadable block; John: *"you're overdoing it with that install
description."* Cut to 145 chars.) The full explanation belongs in the README body, not the card.

Canonical description — copy this shape:

> 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.

The longer version (the "Two artifacts on this page — which one do you want?" comparison table:
what it is / who loads it / contains / do you install it manually, closing with **"The package is
not the bridge."**) lives near the TOP of `README.md`, where there's room for it.

**No images in the pkg.** The README references page art by ABSOLUTE
`https://wiki.adom.inc/blob/app/kicad-bridge/<name>.png` URLs, so the PNGs render on
the page without riding in the install tarball. (Audited 2026-07-15: `files[]` listed
`hero.png` + `arch.png` + `verbs.png` + `outcomes.png` = **496 KB** downloaded by every
`pkg install`, referenced by nothing. Removing them took the tarball to 29.5 KB.) Push page art
with `repo push`, never list it in `files[]`. Before publishing, **stage only the declared
`files[]` into a clean dir and pack from there** — packing from the page repo sweeps up art,
zips and videos.

Stage a dir with `package.json` (name/version/`files[]`), a ROOT `SKILL.md`, and a `skills/<name>/SKILL.md` for **every** skill. **SKILLPACK convention (SDK, replaces the dead `dev-skills/*.md` rule): EVERY skill — user, dev, AND publish — is a real `skills/<name>/SKILL.md` and ships in the tarball.** Dev/publish skills are scoped by AUDIENCE, not filename: frontmatter `user-invocable: false` + a description that opens DEVELOPER-only, so everyday users never get them offered but maintainers still install them. **List every skill path EXPLICITLY (no globs) in `package.json` `files[]` AND `install.sh`/`uninstall.sh`.** Then:

```bash
cd <staging> && adom-wiki pkg pack --out /tmp/v.tgz   # verify: tar lists every skills/<x>/SKILL.md, 0 binaries
adom-wiki pkg publish --org adom --skip-lint --yes     # moves dist-tag latest
```

The runtime SKILL.md (`adom-desktop-kicad`, ships in the zip) and the pkg's root SKILL.md are DIFFERENT docs — update both when a change affects users.

## 5. Push to a running desktop + verify

```bash
adom-desktop --target <name> refresh_bridges '{"name":"kicad"}'   # pulls new cache
adom-desktop --target <name> bridge_kill '{"name":"kicad"}'       # force fresh spawn (old instance keeps old code)
adom-desktop --target <name> bridge_check_updates '{}'            # current == latest?
adom-wiki repo show adom/kicad-bridge adom-bridge-kicad-manifest.json  # served version matches?
```

Verify the served bridge.json (`repo show ... bridge.json`) has the fields you expect and the zip's sha matches. A fresh verb call after a kill returns `bridge_starting` — retry.

## 6. Refreshing the README screenshots (window tour)

The README embeds screenshots hosted on the page `/files` (referenced as
`https://wiki.adom.inc/blob/app/kicad-bridge/<name>.png`). Regenerate them on a **real
VM** (e.g. ADOMBASELINE) whenever the UI/flow changes — never hand-mock them:

1. On the VM: `kicad_enable_software_opengl` (if GPU-less) → open each window with sample data from
   `tour-pack-rp2040/` (`AdomRP2040` symbol, `QFN-56_AdomRP2040` footprint, the breakout board).
2. For each: `kicad_dismiss_dialogs {all:true}` → `kicad_screenshot_all` → `pull_file` the matching
   `.bmp` → PIL `bmp→png`, `thumbnail((1400,1400))`.
3. Save into `docs/img/` with the canonical names the README uses: `schematic-editor.png`,
   `symbol-editor.png`, `footprint-editor.png`, `pcb-editor-2d.png`, `3d-viewer.png`,
   `dialog-firstrun-wizard.png`, `control-surfaces.svg`.
4. `adom-wiki repo push adom/kicad-bridge --files docs/img/*.png ...` then
   `curl -so /dev/null -w '%{http_code}'` each blob URL to confirm 200.
5. `shotlog paste <png> -c kicad-bridge -d "<caption>"` to show John the live captures.

## 7. Showing the published page to John (pup)

**pup opens windows in the BACKGROUND by default.** `foreground: true` on `browser_open_window` is
the ONLY thing that puts a window on his screen — maximizing, sizing, `browser_alert_window`
(taskbar flash) and `browser_raise_os_window` do NOT. (2026-07-19: he asked "show me in pup" three
times because the window was open, correct and maximized — but behind everything.)

- He asked to be shown → open with `foreground: true`, then `desktop_set_window_state maximize` ONCE.
  (`state` accepts `maximize|minimize|restore` — there is **no** `"foreground"` state.)
- The standing "never foreground a window he already has" rule protects windows **he** is using; it
  does not apply to a window you just opened because he asked to see something.
- Sessions die between turns — `browser_list_windows` first; if the session is gone, open fresh
  rather than `browser_navigate` into a dead sessionId.
- **Never touch a session another AI thread owns** (you'll see unfamiliar sessionIds like
  `wiki-lockdemo`, `plate-out`). Open your own.
- Multiple pages → ONE maximized window, `browser_open_tab` per page, land on the important tab.
- Then `adom-shotlog inject` each capture and hand him the phone URL
  (`SHOTLOG_AD_TARGET=AdomLapper adom-shotlog open --channel <ch>` when several desktops are connected).

## 8. Upstream: what the SDK still owes every bridge

Two issues are open on `adom/adom-bridge-sdk` (filed 2026-07-19) — if you hit these problems,
they're known, and the fix belongs in the SDK, not just here:

1. **SDK should require every bridge to explain pkg-vs-zip** (one line, on the page + in
   `package.json.description`). The SDK documents the artifacts ("Artifact 1 — the RUNTIME…") but
   never tells authors to explain them to users, so no page does.
2. **SDK should document artifact hygiene** — the KEEP/EXCLUDE policy in §2 + the no-images-in-pkg
   rule in §4, ideally enforced by a `bridge lint` that fails on images/videos/archives in either
   artifact.

## 9. Standing rules

- Commit source to `main` in lockstep with each publish (drift = the bug that once dropped `updateManifestUrl`).
- After ANY wiki change, refresh the wiki pup window showing the page.
- The changelog must be real (≥2 words, no placeholders) — the server enforces it.
