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
0.1.10: issue-3 root-cause fix — ServersUp registers PCB/SCH APIs at agent start (fresh-session Undeclared identifier: PostProcess); recover() closes the scratch AdomAgent PrjScr
6 files changed
+37−3
CHANGELOG.md+4@@ -1,5 +1,9 @@ # Changelog +## 0.1.10 — 2026-08-31+- #3 (Colby) root-cause FIX: the agent registers the PCB/SCH scripting APIs at startup (`ServersUp`: `Client.StartServer('PCB')`/`('SCH')` before the first `PCBServer` reference) — on a fresh session that never opened a PCB document the API unit is unregistered and the old template halted with an "Undeclared identifier: PostProcess" modal on the user's screen.+- #3 follow-up: `altium_agent_recover` now closes the scratch `AdomAgent_<digest>.PrjScr` out of the Projects panel after freeing the engine (only there — after a successful start the resident loop runs from it).+ ## 0.1.9 — 2026-08-31 - #2/PR #64 (Colby): detect the ADDevelop build — _TITLE_RE now accepts an optional edition word (Develop/Viewer/…) and optional version parens, with a guard so a bare mid-string "Altium Designer" in a dialog cannot pose as the main window. Proven against six title shapes. - #3 (Colby, partial): the -R helpers now reap Altium's single-instance "another instance is busy" notice in the background (both RunScript/RunScriptText lanes and recover), so a stray helper never leaves that modal on the user's screen.
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "altium-bridge",- "version": "0.1.9",+ "version": "0.1.10", "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.1.9+0.1.10
src/agent/AdomAgent.pas.tmpl+19@@ -3004,12 +3004,31 @@ Begin Result := True; End; +{ Register the PCB and SCH scripting APIs before the first PCBServer/SchServer+ reference. On a fresh session where no PCB document was ever opened, the PCB+ API unit is not registered and the first PCBServer call (TxClear, line ~140)+ halts the engine with an "Undeclared identifier: PostProcess" modal on the+ user's screen (altium-bridge#3, ADDevelop fresh session). Client.StartServer+ loads the editor server, which registers the API — background, no UI. }+Procedure ServersUp;+Begin+ Try+ Client.StartServer('PCB');+ Except+ End;+ Try+ Client.StartServer('SCH');+ Except+ End;+End;+ Procedure StartAgent; Var IdleTicks : Integer; Had : Boolean; SleepMs : Integer; Begin+ ServersUp; TxClear; gRunning := True; gRequests := 0;
src/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "altium", "displayName": "Altium Designer",- "version": "0.1.9",+ "version": "0.1.10", "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",
src/handlers/agent.py+11@@ -470,6 +470,17 @@ def recover(reason: str = "") -> dict: (ws / stale).unlink() except Exception: pass+ # Colby (issue #3): a halted bootstrap leaves its scratch AdomAgent_<digest>+ # project in the user's Projects panel. The engine is free again and the loop+ # is dead (hb.txt just cleared, so the lane accepts), so closing it is safe —+ # never do this after a SUCCESSFUL start, the resident loop runs from it.+ prj = prjscr_path()+ if exe and prj.exists():+ closed = run_script_text_lane(+ "Begin ResetParameters; AddStringParameter('ObjectKind','Project'); "+ "AddStringParameter('FileName','" + str(prj) + "'); "+ "RunProcess('WorkspaceManager:CloseObject'); End;", timeout=15.0)+ steps.append({"scratchProjectClosed": bool(closed.get("success")), "path": prj.name}) if user_fg and not _is_altium_hwnd(user_fg): _restore_fg(user_fg, 2.0) remaining = dialogs.scan(main_pid_only=True)