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
Lint a malformed wiki URL and name the real cause, instead of letting the caller invent one. The HD build thread opened https://wiki.adom.inc/adom-wiki-skillpack, got 'Page not found', and reported to John that 'org pages are invisible to logged-out readers'. That conclusion was WRONG and cost trust: the window was signed in as John the entire time (pup's auto-login had worked), the page exists and is public, and the URL was simply missing its OWNER segment — wiki.adom.inc pages are owner-qualified as /<owner>/<slug> (and /<owner>/<slug>/blob/<path> for a file). pup already knew the URL 404'd and knew the host, so it could have named the cause. It now does: on a render failure, a new wikiUrlLint() detects a wiki URL with no owner segment (including the /blob/ form), suggests the corrected URL, tells the caller to confirm the real owner with 'adom-wiki page get <slug>' rather than trust the guess, and explicitly says NOT to conclude anything about permissions or login until the URL is right and re-checked. Known non-page routes (apps, skills, components, discover, login, api, ...) are excluded. Unit-tested 6/6 against the thread's three real URLs plus valid controls.
4 files changed
+50−6
adom-bridge-puppeteer-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "puppeteer",- "version": "1.9.116",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.116/adom-bridge-puppeteer-v1.9.116.zip",- "sha256": "193d05dce1477d58bcd60713e379b8d2f4e24a22f56ff156162b403b7e24f8ea",- "size": 383561,+ "version": "1.9.117",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.117/adom-bridge-puppeteer-v1.9.117.zip",+ "sha256": "d55dfaff688935039ceb2a6651fe80b00ffa08240acb8e0ea71e7900a72d4f29",+ "size": 384688, "verbPrefixes": [ "browser_", "desktop_recorder_",
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.116+1.9.117
src/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "puppeteer", "displayName": "Puppeteer (Chrome for Testing + Native)",- "version": "1.9.116",+ "version": "1.9.117", "description": "Drives a browser ALREADY on the machine \u2014 installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) \u2014 launched with a FRESH isolated profile, so the common case has NO ~150 MB Chrome-for-Testing download and it never touches the user's real tabs/logins. Binds its local server to LOOPBACK (127.0.0.1) only, so no Windows Firewall 'allow Node through the firewall' prompt ever pops. Chrome for Testing is fetched only as a LAST RESORT if the machine has no Chromium browser at all. SPAWN-VERIFIED fallback: pup tries each detected browser (Chrome \u2192 Edge \u2192 CfT) and actually launches it, falling through to the next if one won't start (and handling browsers like Edge that relaunch onto another PID), so a corrupt/partial install never hard-fails an open. The browser that launches is cached as the default (persisted across restarts) so it isn't re-probed each time. On spawn the bridge SELF-WARMS: detects browsers + disk, and only if the box has no Chrome/Edge and no cached CfT does it background-fetch CfT so the first open is instant. browser_use pins a specific browser (chrome | edge | cft | auto); {browser:'chrome',install:true} downloads & installs REAL Google Chrome (user-scoped, no admin) on an Edge-only box. browser_readiness (READ-ONLY) reports which browser will be used + the full candidate list + the default + free disk. Every failure returns a specific errorCode + _hint (chrome_install_no_disk, chrome_download_network, chrome_install_permission, chrome_stable_not_detected, \u2026). Launches with FULL browser permissions by default for full debug (strictPermissions:true opts out). Headful automation: open/close windows+tabs, navigate, screenshot, eval JS, record. pup is a GENERIC, non-profile browser only \u2014 every session is a fresh isolated Chrome/Edge process, never the user's real signed-in browser; profile defaults to sessionId. To drive the user's REAL Chrome/Edge (their profile, cookies, SSO), use the Adom browser EXTENSION's nbrowser_* verbs \u2014 a separate bridge, not pup's job. macOS (v1.9.74+): full parity with mac-native mechanics \u2014 background-by-default is the app-level hide (windows stay drivable/screenshottable while hidden), raise/lower map to unhide+activate/hide, browser_alert_window posts a native toast whose click focuses the window, browser_use {browser:'chrome',install:true} installs Chrome from the official dmg, and taskbar identity/badging remains Windows-only.", "homepage": "https://wiki.adom.inc/adom/adom-desktop", "author": "Adom Inc.",
src/server.js+44@@ -5825,6 +5825,42 @@ const PUP_ISSUES_REF = 'adom/adom-desktop-puppeteer-bridge'; // NOTHING, and the AI reported success. pup HAS the page, so it can just LOOK. This probes the loaded // document and returns a verdict, making a broken render a FACT in the response instead of a suggestion // the caller may skip. One evaluate, no screenshot, and it never throws into the caller's path.+// v1.9.117 (John, after the HD thread wasted a round trip on this) — LINT A MALFORMED WIKI URL.+// The HD build thread opened https://wiki.adom.inc/adom-wiki-skillpack, got "Page not found", and+// concluded (and told John) that "org pages are invisible to logged-out readers". That was WRONG and+// cost real trust: the window was logged in as John the whole time, the page exists and is public, and+// the URL was simply missing its OWNER segment. wiki.adom.inc pages are owner-qualified:+// https://wiki.adom.inc/<owner>/<slug> e.g. /adom/adom-wiki-skillpack+// https://wiki.adom.inc/<owner>/<slug>/blob/<path> e.g. /adom/adom-wiki-skillpack/blob/SKILL.md+// pup KNOWS the URL 404'd and knows the host, so it can name the actual cause instead of leaving the+// caller to invent one. Guessing "adom" is deliberate: it owns the overwhelming majority of pages, and+// the hint says to verify rather than trust the guess.+function wikiUrlLint(u) {+ try {+ if (!u) return null;+ const url = new URL(u);+ if (!/(^|\.)wiki\.adom\.inc$/i.test(url.hostname)) return null;+ const segs = url.pathname.split('/').filter(Boolean);+ if (!segs.length) return null;+ // Known non-page routes that legitimately have a single segment.+ const ROUTES = new Set(['apps', 'skills', 'components', 'bootstraps', 'discover', 'login', 'search', 'api', 'download', 'static', 'hero']);+ if (ROUTES.has(segs[0].toLowerCase())) return null;+ // /<slug> -> owner missing+ // /<slug>/blob/... -> owner missing (a real blob path is /<owner>/<slug>/blob/...)+ const ownerMissing = segs.length === 1 || (segs.length >= 2 && segs[1].toLowerCase() === 'blob');+ if (!ownerMissing) return null;+ const slug = segs[0];+ const rest = segs.slice(1).join('/');+ const fixed = `${url.origin}/adom/${slug}${rest ? '/' + rest : ''}${url.search || ''}`;+ return `WIKI URL LOOKS MALFORMED, and that is the most likely reason for this 404 — NOT a permissions or `+ + `login problem. wiki.adom.inc pages are OWNER-QUALIFIED: https://wiki.adom.inc/<owner>/<slug> `+ + `(and /<owner>/<slug>/blob/<path> for a file). Your URL has no owner segment. Most pages are owned `+ + `by "adom", so try: ${fixed} . Confirm the real owner first with `+ + `\`adom-wiki page get ${slug}\` (read the page's "owner" field) rather than assuming, then reopen. `+ + `Do NOT conclude the page is private or that logged-out users cannot see it until the URL is right — `+ + `check whether this window is signed in before blaming auth.`;+ } catch (e) { return null; }+} async function probeRender(page, httpStatus) { const out = { httpStatus: (httpStatus === undefined ? null : httpStatus), ok: true, signals: [] }; try {@@ -5880,6 +5916,14 @@ function renderVerifyHint(sessionId, url, rc) { // A DETECTED failure outranks advice: say what is wrong in the first words the caller reads. if (rc && rc.ok === false && (rc.signals || []).length) { const sig = rc.signals.join(', ');+ // v1.9.117: a malformed wiki URL is a KNOWN cause, so lead with it rather than generic advice.+ const lint = wikiUrlLint(url);+ if (lint) {+ return 'THIS PAGE DID NOT RENDER CORRECTLY (' + sig + '). ' + lint+ + ' See it yourself: `adom-desktop --ai-thread "<your thread>" browser_screenshot {"sessionId":"'+ + sid + '"}`. Do NOT report success, and do NOT report a conclusion about permissions or login'+ + ' until the URL is owner-qualified and you have re-checked.';+ } const st = (typeof rc.httpStatus === 'number') ? ' (HTTP ' + rc.httpStatus + ')' : ''; const ex = rc.excerpt ? ' The page says: "' + String(rc.excerpt).replace(/\s+/g, ' ').slice(0, 140) + '".' : ''; return 'THIS PAGE DID NOT RENDER CORRECTLY — pup checked it, so do NOT report success. Detected: '