app
Pup - Puppeteer Bridge
Public Made by Adomby adom
pup is the AI's own browser: a real, full Chrome on the user's desktop that the AI fully controls (a sandbox, not the user's signed-in browser). Rides Bridge; pup_* verbs open windows and tabs, navigate, screenshot, and eval JS.
// Identity card: version stamp from pup /health when reachable (cosmetic only).
(async () => {
// Medium identity card per the identity-card skill: real name bold, @handle ยท email muted,
// org pills (max 2 + N) with org avatars, fields only when the identity API returns them.
for (const port of [64230, 8851]) {
try {
const r = await fetch(`http://127.0.0.1:${port}/identity`, { signal: AbortSignal.timeout(2500) });
const id = await r.json();
if (!id || !id.ok) break;
if (id.displayName) document.getElementById('who').textContent = id.displayName;
const handle = id.username ? '@' + id.username : '';
const parts = [handle, id.email].filter(Boolean).join(' \u00b7 ');
if (parts) document.getElementById('sub').textContent = parts;
const av = document.querySelector('img.avatar');
if (id.avatarUrl) av.src = id.avatarUrl; else if (id.avatarB64) av.src = id.avatarB64.startsWith('data:') ? id.avatarB64 : 'data:image/png;base64,' + id.avatarB64;
const orgsEl = document.getElementById('orgs');
const orgs = (id.orgs || []).slice(0, 2);
for (const o of orgs) {
const pill = document.createElement('span');
pill.style.cssText = 'display:inline-flex;align-items:center;gap:5px;background:rgba(0,184,177,.12);border:1px solid rgba(0,184,177,.4);color:#00d4cb;border-radius:999px;padding:2px 9px 2px 3px;font-size:11px;';
pill.title = 'Organization you belong to: ' + (o.displayName || o.name);
if (o.avatarUrl) { const im = document.createElement('img'); im.src = o.avatarUrl; im.style.cssText = 'width:14px;height:14px;border-radius:50%;'; pill.appendChild(im); }
else { const dt = document.createElement('span'); dt.style.cssText = 'width:8px;height:8px;border-radius:50%;background:#00b8b1;margin-left:4px;'; pill.appendChild(dt); }
pill.appendChild(document.createTextNode(o.displayName || o.name));
orgsEl.appendChild(pill);
}
if ((id.orgs || []).length > 2) { const n = document.createElement('span'); n.textContent = '+' + (id.orgs.length - 2); n.title = id.orgs.slice(2).map(o => o.displayName || o.name).join(', '); n.style.cssText = 'color:#8b949e;font-size:11px;align-self:center;'; orgsEl.appendChild(n); }
break;
} catch (e) {}
}
for (const port of [64230, 8851]) {
try {
const r = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(1000) });
const j = await r.json();
if (j && j.bridge === 'puppeteer') { document.getElementById('ver').textContent = 'pup ' + (j.version || ''); return; }
} catch (e) {}
}
})();