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.1.38: taskbar overlay auto-clears after 5 idle minutes
8 files changed
+52−7
CHANGELOG.md+4@@ -1,5 +1,9 @@ # Changelog +## 0.1.38 — 2026-09-01+- **The taskbar overlay badge auto-clears after 5 minutes without a driving verb.** John, seeing the Adom mark still parked on Altium's taskbar icon: *"do you auto-remove that overlay after 5 minutes of verb inactivity?"* The answer was no — the badge was set on the first driving verb and never cleared until the bridge died, while this module's own header PROMISED "cleared when the bridge goes idle". A permanent overlay stops meaning "an AI is driving right now" and starts meaning nothing. An idle watcher (started at boot beside the dialog reaper) now clears it at 5 idle minutes; the next driving verb re-badges instantly.+- For the record, what already worked: every driving verb with a measured estimate ≥3 s runs a REAL taskbar progress bar on Altium's button (percent paced by history, marquee when unmeasured, red flash + clear on failure) and stops it when the verb returns — progress rides the taskbar icon, never toasts, per the house rule.+ ## 0.1.37 — 2026-09-01 - **Altium's dialog text is unreadable — so the reaper stops relying on it.** Measured: the VaultExplorer warning's entire UIA subtree is `Window "Warning" -> panes -> Button "OK"`. The message is PAINTED pixels, absent from `WM_GETTEXT` and from the accessibility tree, so no amount of text classification will ever see it. - **The rule that does work: a dialog whose ONLY button is OK carries no decision.** Dismissing it can acknowledge, never choose. Everything that asks something of the user has two or more buttons — a save prompt (Save / Don't Save / Cancel), a licence chooser (Choose a license / Continue), a confirm (Yes / No). The standing reaper now clears lone-OK dialogs even when their text is unreadable, logging them as `single_ok_acknowledgement`.
adom-bridge-altium-manifest.json+4−4@@ -1,9 +1,9 @@ { "name": "altium",- "version": "0.1.37",- "url": "https://wiki.adom.inc/download/adom/altium-bridge/0.1.37/adom-bridge-altium-v0.1.37.zip",- "sha256": "fa20a659046ef5f8d7a24ff13c871cc0b54885b1ea8e1dbcfbc58f1f64f2c8d4",- "size": 135280,+ "version": "0.1.38",+ "url": "https://wiki.adom.inc/download/adom/altium-bridge/0.1.38/adom-bridge-altium-v0.1.38.zip",+ "sha256": "9468b0d69a824c6ea725a81b3cb800b1ed0e26b870a83ed13b62ac2f7ff8cb9c",+ "size": 135889, "verbPrefixes": [ "altium_" ],
adom-bridge-altium-v0.1.38.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "altium", "displayName": "Altium Designer",- "version": "0.1.37",+ "version": "0.1.38", "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",
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "altium-bridge",- "version": "0.1.37",+ "version": "0.1.38", "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.37+0.1.38
src/handlers/taskbar.py+38@@ -163,3 +163,41 @@ def end_activity_progress(verb: str, failed: bool = False) -> None: _taskbar({"hwnd": int(hwnd), "flash": "stop"}) except Exception: pass+++# ---- idle auto-clear (John, 2026-09-01: "do you auto-remove that overlay after 5 minutes of+# verb inactivity?") ---------------------------------------------------------------------------+#+# He asked because the answer was NO: the badge was set on the first driving verb and never+# cleared until the bridge died — the header above always PROMISED "cleared when the bridge goes+# idle", but nothing implemented it. A permanent overlay is worse than none: it stops meaning+# "an AI is driving right now" and starts meaning nothing.++IDLE_CLEAR_SEC = 300.0+_LAST_DRIVING = [0.0]+_IDLE_WATCHER = [False]+++def note_driving() -> None:+ """Called by dispatch on every driving verb; feeds the idle clock."""+ _LAST_DRIVING[0] = time.time()+++def start_idle_watcher() -> bool:+ """Clear the overlay after IDLE_CLEAR_SEC without a driving verb. Idempotent.+ The next driving verb re-badges instantly (set_driving_badge re-adds after a clear)."""+ if _IDLE_WATCHER[0]:+ return False+ _IDLE_WATCHER[0] = True++ def _loop():+ while True:+ time.sleep(15.0)+ try:+ if badge_active() and _LAST_DRIVING[0] and time.time() - _LAST_DRIVING[0] > IDLE_CLEAR_SEC:+ clear_driving_badge()+ except Exception:+ pass++ threading.Thread(target=_loop, daemon=True, name="altium-badge-idle-clear").start()+ return True
src/server.py+3@@ -2850,6 +2850,7 @@ def dispatch_command(command: str, args: dict) -> dict: try: from handlers import taskbar taskbar.set_driving_badge()+ taskbar.note_driving() # feeds the 5-min idle clock that auto-clears the overlay est, conf = progress.estimate(command, "warm") if est and est >= 3: stopper = taskbar.start_activity_progress(command, est, conf)@@ -2946,6 +2947,8 @@ def main(): try: dialogs.start_reaper() print("[altium] standing dialog reaper started (known nuisances are pre-empted, never save prompts)")+ taskbar.start_idle_watcher()+ print("[altium] badge idle-watcher started (overlay auto-clears after 5 min without a driving verb)") except Exception as e: print(f"[altium] dialog reaper failed to start: {e}") srv = ThreadingHTTPServer((host, port), Handler)