app
Altium - the Altium Bridge
Public Made by Adomby adom
Adom Bridge for Altium Designer: a resident DelphiScript agent gives the AI eval, the 1,100-command process launcher, all 8 EDA surfaces with screenshots, compile/ERC, DRC, OutJob outputs, native SchLib/PcbLib authoring with STEP 3D bodies, and dialog handling by PID.
← Commit history
v0.2.32 (insiders): 0.2.32: agent_recover activates the agent script before stopping it and verifies the engine is free; close frees a parked engine; OutJob verbs refuse by name; PUBLISHING.md + Parent skill lines + README facts
4 files changed
+13−7
CHANGELOG.md+10−4@@ -1,5 +1,11 @@ # Changelog +## 0.2.32 (2026-09-21)+- **`altium_agent_recover` actually recovers, and says the truth.** It sent `EditScript:Stop` and answered success without checking. That process only acts when a SCRIPT document is the active document: with a board in front it was a silent no-op, the script stayed on its breakpoint, `altium_selftest_script_error` reported `halted_and_recovered` for an engine that was never freed, and Altium then refused to close (AD 26.10.1; it had only ever worked where the script happened to be in front). Recover now brings each agent script in the workspace to the front (`WorkspaceManager:OpenObject`) and stops it there, warns if a hand-off started a second Altium, and VERIFIES by starting a fresh agent loop: `engineFree:true`, or `errorCode: engine_still_parked` with what to do.+- `altium_close` frees a parked script engine before and during the close (Altium refuses to close "when a script is stopped on a breakpoint"), without starting a new agent loop.+- `altium_run_outjob` / `export_bom` / `export_gerber` refuse a missing OutJob by name (`outjob_not_found`); the agent answered `ok:false` with no text.+- Docs: `PUBLISHING.md`; every sub-skill starts with its `Parent skill:` line; README declares the `altium` keyword, describes the native exe (it still said "Python server") and points installs at `altium_install`; four blunt verbatim quotes in this changelog reworded.+ ## 0.2.31 (2026-09-21) - FIX `altium_board_shape`, which halted Altium's script engine on two builds (AD 26.10.1, Altium Develop). It drew four temporary tracks, ran the editor process `PCB:PlaceBoardOutline`, then read `Board.BoardOutline.BoundingRectangle` with no nil guard; on those builds the process left no outline, the read raised on a nil object and the script parked on a breakpoint with no error box. It now sets the outline the way `altium_test_board` always has (PointCount + Segments[] + Rebuild, which renders correctly on every build), with every access nil-guarded, and refuses `bad_size` / `no_board_outline` by name. @@ -118,7 +124,7 @@ The dedicated freeze-fix release (adom/altium-bridge#6, #7, #8). Every mechanism ## 0.2.6 — 2026-09-02-- **The standing reaper was blind since 0.2.0 — fixed.** John: *"u have not solved this error yet. you MUST"*, with the VaultExplorer startup warning back on his screen. Root cause: ab's `desktop_find_controls` returns buttons under `matches`; the Rust port read `controls`, so every dialog scanned as `buttons: []` and the lone-OK acknowledgement rule could never fire. Parser fixed with a regression test built from the exact reply ab gave for that warning; title-bar controls are dropped so a lone OK still reads as lone. Verified minutes later: two startup warnings reaped before anyone saw them.+- **The standing reaper was blind since 0.2.0 — fixed.** The VaultExplorer startup warning was still reaching the user's screen. Root cause: ab's `desktop_find_controls` returns buttons under `matches`; the Rust port read `controls`, so every dialog scanned as `buttons: []` and the lone-OK acknowledgement rule could never fire. Parser fixed with a regression test built from the exact reply ab gave for that warning; title-bar controls are dropped so a lone OK still reads as lone. Verified minutes later: two startup warnings reaped before anyone saw them. ## 0.2.5 — 2026-09-02 - **`altium_foreground` verifies instead of assuming**: after the raise it reads the z-order and reports `visiblyOnTop` — a raise can "succeed" while another fullscreen window still covers Altium (John watched an entire show that never became visible because his fullscreen Claude window sat on top, and his own typing kept it there — which the foreground-once rule correctly refuses to fight). `demo {live}` surfaces the verdict as `foregroundNote` so the narrating AI can TELL the user the show is running behind their current window rather than silently losing to it.@@ -135,7 +141,7 @@ The dedicated freeze-fix release (adom/altium-bridge#6, #7, #8). Every mechanism ## 0.2.2 — 2026-09-02-- **The live show is code now, not a hand-rolled AI script** (John: "for all the stuff you need for the demo, you better make verbs" — and his diagnosis of the sync jitter was exactly right: "maybe cuz u were doing it via manual ai instead of via code?"). Driven from a container, every camera step paid the full CLI→ab→bridge→agent round trip (~1.4 s, jittery); in-bridge it is one agent file-drop (~40 ms), so choreography holds its timing.+- **The live show is code now, not a hand-rolled AI script** (review feedback: everything the demo needs should be a verb, and the sync jitter came from driving the show step by step from the AI instead of from code). Driven from a container, every camera step paid the full CLI→ab→bridge→agent round trip (~1.4 s, jittery); in-bridge it is one agent file-drop (~40 ms), so choreography holds its timing. - **`altium_animate_view`** — camera/zoom choreography on the current document from NATIVE Altium camera commands (SetCamera/ResetCamera/FlipBoard/Zoom; Altium animates the transitions itself — no synthetic mouse). Steps (orbit_left/right/up/down, isometric, flip, zoom_in/out, pans, rolls…) or presets (punch_in, showcase3d, orbit, flip, finale), each with a pauseMs. - **`altium_foreground`** — the sanctioned exception to the never-foreground rule, for a human who asked to WATCH. Refuses without a human-readable `reason` (>=10 chars), mirroring ab's caption rule. - **`altium_demo {live:true}`** — the narrated, animated, foreground tour: per stop it paints the ab caption, opens the document, holds Altium in front, runs the choreography in-bridge, and returns `narrate` + `nextNarrate` so the caller's TTS speaks over exactly the motion described (fire nextNarrate detached, then make nextCall). When Altium is cold it narrates the launch too: caption + a spoken line + a background launch, `status: "launching"` until up.@@ -216,7 +222,7 @@ The dedicated freeze-fix release (adom/altium-bridge#6, #7, #8). Every mechanism ## 0.1.30 — 2026-09-01 - **Proof captures work with Altium minimized, without ever moving the window.** Windows does not render a minimized window, so a capture of one returned a ~237x39 title-bar sliver — which the bridge handed back as "proof" of a successful import, and which the wiki front-end would have displayed as evidence. Now every capture first makes the window CAPTURABLE: restore it if minimized, push it to the BOTTOM of the z-order, and hand the user's foreground straight back. Measured end to end at ~0.6 s; the capture then reads the occluded window at full size.-- **The rejected alternative, recorded so nobody rebuilds it:** parking the window off-screen. John, 2026-09-01 — *"i hate the idea of parking an altium window off screen cuz if the user wants to manually foreground, you fuck them over."* Never move a window the user might reach for.+- **The rejected alternative, recorded so nobody rebuilds it:** parking the window off-screen. Rejected in review on 2026-09-01: a user who brings Altium forward by hand would not find it. Never move a window the user might reach for. - **A capture narrower than 400 px is refused, not returned.** `_shot_of_main` reports `proofUnavailable` with the reason, and the surface verbs (`show_symbol` / `show_footprint` / `show_3d_chip` / …) return `success: false, errorCode: "proof_unavailable"` rather than a confident nothing. The frame also carries `prepared` — what the bridge had to do to the window — so a caller can say honestly whether the user's screen was touched. ## 0.1.29 — 2026-09-01@@ -282,7 +288,7 @@ The dedicated freeze-fix release (adom/altium-bridge#6, #7, #8). Every mechanism - **The release refuses to build on drift.** `scripts/release.py` lints `bridge.json` against what `server.py` can actually dispatch and fails with both lists rather than shipping a manifest that lies. 106 verbs declared and dispatchable. ## 0.1.19 — 2026-09-01-- **Pre-emption, properly.** John: *"you better pre-empt these from ever showing up"*. Two changes so a script modal cannot reach the user:+- **Pre-emption, properly.** Two changes so a script modal cannot reach the user: 1. **A script lane now refuses when ANY resident loop is alive, in ANY workspace** — not just the current instance's. That gap is exactly how "Another script executing now" got on screen after per-instance workspaces landed: the pre-upgrade loop was still resident under the legacy path, `is_alive()` looked only at `agent/<key>`, saw nothing, and fired a bootstrap into an engine that was already running a script. The refusal names the workspace and heartbeat age so the fix is obvious. 2. **A watcher runs FOR THE DURATION of every `-R` lane** and presses OK the instant one of our own modals appears, so it exists for a few hundred milliseconds instead of sitting on screen until someone goes looking. Cleared modals come back as `modalsPreempted` rather than being hidden. The watcher only ever touches modals this bridge CAUSES (script-busy, another-instance, scripting-system); a save prompt or a licence question is the user's and is never pressed. - Detection was always the weaker half: the engine is single-threaded, so the modal it raises is also what freezes it — which is precisely why watching during the operation works.
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "altium-bridge",- "version": "0.2.31",+ "version": "0.2.32", "type": "app", "description": "Skills for your container so your AI knows how to drive the Altium Designer bridge (altium_* verbs). The bridge runtime itself is the release zip; Adom Bridge loads that.", "tags": [
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.2.31+0.2.32
src/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "altium", "displayName": "Altium Designer",- "version": "0.2.31",+ "version": "0.2.32", "description": "Drive Altium Designer from Adom: a resident DelphiScript agent (eval + the 1,100-command process launcher), the X2 -R command line, UIA over the VCL shell, dialogs by PID, screenshots of every Altium window, and Altium 365.", "homepage": "https://wiki.adom.inc/adom/altium-bridge", "docs": "https://wiki.adom.inc/adom/altium-bridge",