app
AI Flow
Public Made by Adomby adom
Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board.
← Commit history
Merge PR #124: Wait for recreated tour frames and document small-component marking checks
2 files changed
+19−3
docs/library-tours.md+14@@ -15,3 +15,17 @@ as distinct visits. `libraries` covers native symbol/pad/model binding; `models` checks the board's actual selected models; `library-tour` records their visual review. An existing schematic's library repair is different from later requirements-driven part selection. These are AI-owned steps, not new automated qualification gates.++When marking small components, verify the actual text bounds and surface: a+successful etcher job may still overflow a 0402 body or choose a raised terminal.+Fit to the upper body with pin-1/polarity and terminal clearance, compare both+orientations, preserve the source document's materials, and retain a separate+plain model. Never impose a minimum font size that pushes text outside the part.+Narrow annular contacts may only support tiny identification text; state that limit.+Keep generated lettering as a separate STEP layer when base redistribution rights+are unresolved; do not call an etched restricted model independently authored.++After opening or recreating a Hydrogen tour tab, retry a missing frame during the+bounded readiness wait. A frame-not-found result before mounting is not a renderer+failure. Actual loading/recording errors must still fail; verify decoded frames+and advancing playback time on the published wiki video.
tools/library-tour.py+5−3@@ -27,11 +27,13 @@ elif a.action=='serve': print(f'Library tour serving on http://localhost:{a.port}/',flush=True);http.server.ThreadingHTTPServer(('127.0.0.1',a.port),Handler).serve_forever() elif a.action=='record': control=pathlib.Path.home()/'.adom/hydrogen-control-url';assert control.exists(),'Hydrogen control unavailable; open the tour in Pup and use the recording controls, then verify';base=control.read_text().strip();url=f'http://localhost:{a.port}/';subprocess.run(['adom-cli','hydrogen','webview','open-or-refresh','--name','Component library tour','--url',url],check=True)- def evaluate(js):- q={'target':url,'js':js};r=json.load(urllib.request.urlopen(urllib.request.Request(base+'/eval-in',data=json.dumps(q).encode(),headers={'Content-Type':'application/json'}),timeout=20));assert r.get('ok'),r;return r.get('value')+ def evaluate(js,waitForFrame=False):+ q={'target':url,'js':js};r=json.load(urllib.request.urlopen(urllib.request.Request(base+'/eval-in',data=json.dumps(q).encode(),headers={'Content-Type':'application/json'}),timeout=20));+ if not r.get('ok') and waitForFrame and 'frame/context not found' in str(r.get('error')):return {'ready':False}+ assert r.get('ok'),r;return r.get('value') deadline=time.monotonic()+180 while time.monotonic()<deadline:- state=evaluate('window.libraryTour?.stats?.() || {ready:false,error:window.libraryTour?.error}')+ state=evaluate('window.libraryTour?.stats?.() || {ready:false,error:window.libraryTour?.error}',True) if state and state.get('error'):raise RuntimeError(state) if state and state.get('ready'):break time.sleep(2)