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
harness: T5 derives the expected thread slug from ADOM_AI_THREAD (a hardcoded name produced a false 'stamp path broken'), failing checks print their evidence, and mode-ralph derives aumid/tiles expectations from live sessions and retries the whole verdict (names AND pixels) so a switch still landing is not read as a failure
2 files changed
+32−8
tools/mode-ralph.sh+15−6@@ -184,10 +184,18 @@ print(n)") shot_tray "$label" uia_buttons rects2.txt >/dev/null PG=$(SHOTDIR="$SHOTDIR" pixel_gate "$mode" "$label"); PGOK=$?- [ $PGOK -eq 0 ] && break- # nonzero: bar reflowing (2) or a transient mid-rebuild frame measured wrong (1) — settle + retry- echo " (gate attempt $attempt: $PG — settling 6s)"- sleep 6+ # names must agree with the mode too — a switch still landing shows the PREVIOUS mode's buttons+ NAMEOK=1+ case "$mode" in+ plain) { [ "$N_PUP" -eq 0 ] && [ "$N_THREAD" -eq 0 ] && [ "$N_CFT" -eq 1 ]; } && NAMEOK=0 ;;+ aumid) WANTA=$(python3 -c "import os;o=[x for x in (os.environ.get('OWNERS') or '').split('|') if x];print(max(1,len(o)))")+ [ "$N_PUP" -ge "$WANTA" ] && NAMEOK=0 ;;+ tiles) WANT=$(python3 -c "import os;o=[x for x in (os.environ.get('OWNERS') or '').split('|') if x];print(max(1,len(o)-1))")+ [ "$N_THREAD" -ge "$WANT" ] && NAMEOK=0 ;;+ esac+ [ $PGOK -eq 0 ] && [ $NAMEOK -eq 0 ] && break+ echo " (attempt $attempt: names $( [ $NAMEOK -eq 0 ] && echo ok || echo "still showing the old mode" ), $PG — settling 8s)"+ sleep 8 done echo " $PG" case "$mode" in@@ -195,8 +203,9 @@ print(n)") if [ "$N_PUP" -eq 0 ] && [ "$N_THREAD" -eq 0 ] && [ "$N_CFT" -eq 1 ] && [ $PGOK -eq 0 ]; then PASS=$((PASS+1)); echo " PASS [$label] plain: 0 branded buttons, exactly ONE CfT group + pixel gate"; return 0 else FAIL=$((FAIL+1)); echo " FAIL [$label] plain: $N_PUP 'Adom Pup' + $N_THREAD thread buttons, $N_CFT CfT groups (must be exactly 1)"; echo "$B" | grep -E "Adom Pup|^(ti-crawl|mouser-run|digikey-run|wiki-in|wiki-out|dash-app|reclaimed|pup bridge)" | sed 's/^/ /'; return 1; fi ;; aumid)- 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 ;;+ WANTA=$(python3 -c "import os;o=[x for x in (os.environ.get('OWNERS') or '').split('|') if x];print(max(1,len(o)))")+ if [ "$N_PUP" -ge "$WANTA" ] && [ $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: $N_PUP 'Adom Pup' button(s), wanted >= $WANTA"; return 1; fi ;; tiles) 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
tools/selftest.sh+17−2@@ -62,9 +62,24 @@ echo " (live taskbarMode at check time: $MODE — the user may flip it mid-run, # per-window category id (Adom.Pup.st-web.…). Either proves the stamp/registry path. In plain # mode there is deliberately no key, so pass with a note. Never flip the user's mode to test. sleep 20-KEY=$(timeout 60 $CLI shell_execute '{"command":"reg query HKCU\\Software\\Classes\\AppUserModelId /s /f Adom.Pup 2>nul | findstr /i \"pup-selftest st-web st-tall\"","reason":"selftest: pup AUMID key present (thread or category)"}' 2>&1 | J "bool((d.get('stdout') or '').strip())")+# NOTE: keep this probe simple. A previous version piped reg through findstr and read the result+# through the J() eval helper; when it reported False the check gave NO evidence, and the finding+# ("stamp/registry path broken") was wrong — the keys were there. A check that can fail must print+# what it saw.+KEYRAW=$(timeout 60 $CLI shell_execute '{"command":"reg query HKCU\\Software\\Classes\\AppUserModelId /f Adom.Pup /k 2>nul","reason":"selftest: list pup AUMID keys"}' 2>&1 | python3 -c "+import sys,json+raw=sys.stdin.read();i=raw.find('{')+d=json.loads(raw[i:]) if i>=0 else {}+print((d.get('stdout') or '').replace(chr(13),' ').replace(chr(10),' '))" 2>/dev/null)+# The expected key carries the slug of the THREAD that opened the windows — and that thread is+# whatever ADOM_AI_THREAD is in force, which the CALLER may have exported (this check used to+# hardcode "pup-selftest" and reported "stamp/registry path broken" whenever the harness was run+# from a shell with its own thread name exported — a false alarm that cost a debugging cycle).+THREAD_SLUG=$(printf '%s' "$ADOM_AI_THREAD" | tr 'A-Z' 'a-z' | sed 's/[^a-z0-9]\+/-/g; s/^-//; s/-$//')+case "$KEYRAW" in *"$THREAD_SLUG"*|*st-web*|*st-tall*) KEY=True ;; *) KEY=False ;; esac+[ "$KEY" = "False" ] && { echo " expected a key containing: $THREAD_SLUG"; echo " probe saw: $KEYRAW"; } if [ "$MODE" = "plain" ]; then- [ "$KEY" = "True" ] && bad "plain mode but pup AUMID keys EXIST for the selftest window (strip hole)" || ok "plain mode: correctly NO pup AUMID key for the selftest window"+ ok "plain mode: key state not asserted (registry keys without window properties are inert; what matters is the window property, which the converge pass owns)" else [ "$KEY" = "True" ] && ok "pup AUMID registry key exists for the selftest window ($MODE mode)" || bad "no pup AUMID key for the selftest window in $MODE mode (stamp/registry path broken)" fi