app
Pup - the AI's own browser
Public Made by Adomby adom
pup gives your AI a real browser on your desktop that it drives completely, in the background, signed in as you: windows that never jump in front of your work, one shared profile that learns your logins, and every window labeled on the taskbar with its AI thread's name.
← Commit history
mode-ralph: expectations derive from LIVE session owners, not a hardcoded thread list (a stale list failed every tiles round while the bar was perfect)
1 file changed
+31−8
tools/mode-ralph.sh+31−8@@ -18,6 +18,20 @@ export ADOM_CONTAINER_NAME="${ADOM_CONTAINER_NAME:-galliaApril}" CLI="adom-bridge --target $TARGET" PASS=0; FAIL=0 SHOTDIR="${SHOTDIR:-/tmp/mode-ralph-shots}"; mkdir -p "$SHOTDIR"+# v2: the expected thread-tile names come from the LIVE sessions, never a hardcoded list. A stale+# list made every tiles round fail with "only 1 thread-name buttons" while the bar was perfect.+OWNERS=$(timeout 40 $CLI pup_status '{}' 2>&1 | python3 -c "+import sys,json+raw=sys.stdin.read();i=raw.find('{')+d=json.loads(raw[i:]) if i>=0 else {}+seen=[]+for s in d.get('sessions',[]):+ o=(s.get('owner') or '').strip()+ if o and o not in seen: seen.append(o)+print('|'.join(seen))" 2>/dev/null)+[ -z "$OWNERS" ] && OWNERS="pup bridge maintenance"+echo "live threads expected as tiles: $OWNERS"+export OWNERS evaljs() { # evaljs <expression> -> prints result timeout 60 $CLI pup_eval "{\"sessionId\":\"cn-dash\",\"expression\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$1")}" 2>&1 \@@ -66,7 +80,8 @@ def load(f): return [l.split('|',4) for l in open(f).read().splitlines() if l.count('|')>=4] def pick(rows): if mode=='plain': return [r for r in rows if 'Chrome for Testing' in r[4]]- return [r for r in rows if r[4].startswith('Adom Pup') or re.match(r'^(ti-crawl|mouser-run|digikey-run|wiki-in|wiki-out|dash-app|reclaimed|pup bridge)', r[4])]+ owners=[o for o in (os.environ.get('OWNERS') or '').split('|') if o]+ return [r for r in rows if r[4].startswith('Adom Pup') or any(r[4].startswith(o) for o in owners)] rows=load(f'{SHOTDIR}/rects.txt') tgt=pick(rows) if not tgt: print('PIXELGATE FAIL: no target button found'); sys.exit(1)@@ -90,11 +105,14 @@ im=Image.open(f'{SHOTDIR}/{label}.png') import json as _json def _map(x,w): try:+ # imageToScreen describes the SAFE image, not the full.png we open — map via screenRect+ # against THIS image's width (the 3-button-drift bug caught in the six-state evidence walk) cm=_json.load(open(f'{SHOTDIR}/{label}.json')).get('coordMap') or dict()- i2s=cm.get('imageToScreen') or dict()- sx=float(i2s.get('sx') or 0); ox=float(i2s.get('ox') or 0)- if not sx: raise ValueError('no sx')- a,b=int((x-ox)/sx),int((x+w-ox)/sx)+ sr=cm.get('screenRect') or dict()+ srw=float(sr.get('w') or 0); srx=float(sr.get('x') or 0)+ if not srw: raise ValueError('no screenRect')+ sc=im.width/srw+ a,b=int((x-srx)*sc),int((x+w-srx)*sc) except Exception: sc=im.width/2560.0; a,b=int(x*sc),int((x+w)*sc) a=max(0,min(im.width-2,a)); b=max(a+2,min(im.width,b))@@ -157,7 +175,11 @@ verify_state() { # verify_state <mode> <label> — retries while the bar is stil for attempt in 1 2 3 4 5; do B=$(uia_buttons rects.txt) N_PUP=$(echo "$B" | grep -c "Adom Pup" || true)- N_THREAD=$(echo "$B" | grep -Ec "^(ti-crawl|mouser-run|digikey-run|wiki-in|wiki-out|dash-app|reclaimed|pup bridge maintenance|pup-dashboard)" || true)+ N_THREAD=$(echo "$B" | python3 -c "+import sys,os+owners=[o for o in (os.environ.get('OWNERS') or '').split('|') if o]+n=sum(1 for l in sys.stdin if any(l.startswith(o) for o in owners))+print(n)") N_CFT=$(echo "$B" | grep -c "Chrome for Testing" || true) shot_tray "$label" uia_buttons rects2.txt >/dev/null@@ -176,8 +198,9 @@ verify_state() { # verify_state <mode> <label> — retries while the bar is stil if [ "$N_PUP" -ge 5 ] && [ $PGOK -eq 0 ]; then PASS=$((PASS+1)); echo " PASS [$label] aumid: $N_PUP 'Adom Pup' per-window buttons + pixel gate"; return 0 else FAIL=$((FAIL+1)); echo " FAIL [$label] aumid: only $N_PUP 'Adom Pup' buttons"; return 1; fi ;; tiles)- if [ "$N_THREAD" -ge 4 ] && [ $PGOK -eq 0 ]; then PASS=$((PASS+1)); echo " PASS [$label] tiles: $N_THREAD thread-name buttons + pixel gate"; return 0- else FAIL=$((FAIL+1)); echo " FAIL [$label] tiles: only $N_THREAD thread-name buttons"; return 1; fi ;;+ WANT=$(python3 -c "import os;o=[x for x in (os.environ.get('OWNERS') or '').split('|') if x];print(max(1,len(o)-1))")+ if [ "$N_THREAD" -ge "$WANT" ] && [ $PGOK -eq 0 ]; then PASS=$((PASS+1)); echo " PASS [$label] tiles: $N_THREAD thread-name buttons + pixel gate"; return 0+ else FAIL=$((FAIL+1)); echo " FAIL [$label] tiles: $N_THREAD thread-name button(s), wanted >= $WANT of [$OWNERS]"; return 1; fi ;; esac }