← Commit history

Publish 2.0.317

John Lauer ·fc61f57a06 ·1mo ago ·parent 6d9eb5d
3 files changed +41−47
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "pup-bridge",-  "version": "2.0.316",+  "version": "2.0.317",   "type": "app",   "description": "The pup SKILL PACK \u2014 the AI skills that teach a cloud/container AI how to drive the Adom Desktop Puppeteer (pup) bridge (browser_* verbs): the everyday `pup` skill plus focused sub-skills for windows/sessions/tabs, screenshots+recording, browsers+Chrome install, and driving the Adom wiki. Installs into ~/.claude/skills + ~/.codex/skills. DOCS ONLY \u2014 this is NOT the bridge runtime. The bridge itself (the Node program that drives the browser) runs on the DESKTOP: Adom Desktop bundles it and auto-installs/updates it, and it's published separately on the Releases tab as adom-bridge-puppeteer-v<ver>.zip. The pkg version is kept in lockstep with the Release version so the page's max version row always carries BOTH a pkg tarball (skills) and a runtime zip (bridge) \u2014 a skills-only or runtime-only bump on the top row breaks constraint installs. TL;DR: pkg install = the skills for your AI; the bridge = the Release zip, which Adom Desktop manages for you.",   "keywords": [
page.json+1−1
@@ -4,7 +4,7 @@   "slug": "pup-bridge",   "title": "Pup - Puppeteer Bridge",   "brief": "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.",-  "version": "2.0.316",+  "version": "2.0.317",   "tags": [     "skills",     "pup",
tools/pup-dashboard+39−45
@@ -334,69 +334,63 @@ load(); setInterval(load,15000);  // ── demo ──────────────────────────────────────────────────────────────────────────────────────── async function runDemo() {-  // The dock-card showcase (John: "shouldn't your pup demo be a bit cooler? show off your-  // annotation feature, your jump lists, how cool your icons are"). The user CLICKED Run the demo,-  // so the finale may come to their screen: the raise is captioned with exactly that reason.+  // The dock-card showcase. v2.0.317 (John: "you lost me in that demo. i had no idea what was going+  // on... show non-stop ab captions step by step, take over the cursor so i see you moving"): the+  // narration lives ON THE DESKTOP now. Every act announces itself with an on-screen caption BEFORE+  // it happens (duration scaled to reading speed), the foreground act glides the visible Adom cursor+  // with intent labels, and the drawing is slow enough to watch. The console lines mirror the+  // captions for the record; the show itself is on screen.   const lines = [];   const sid = 'pup-dock-demo';   const sleep = (ms) => new Promise(r => setTimeout(r, ms));   const tgt = await resolveTarget();+  const cap = async (text) => {+    const ms = Math.min(12000, Math.max(2500, 900 + text.trim().split(/\s+/).length * 350));+    await ab('desktop_caption', { text, duration: ms, id: 'pup-demo', position: 'bottom', size: 'medium' }, 8000, tgt.name);+    lines.push('   [caption] ' + text);+    return ms;+  };+  const capWait = async (text, extra) => { const ms = await cap(text); await sleep(ms + (extra || 0)); }; -  lines.push('1. Opening a window in the BACKGROUND. pup births it off-screen and parks it behind');-  lines.push('   your work in under 50ms, so it can never steal your screen or your keystrokes.');+  lines.push('The demo narrates ON YOUR SCREEN with captions, step by step. Watch the desktop.');+  await capWait('pup demo, step 1 of 6: I am opening a browser window IN THE BACKGROUND. Watch your TASKBAR, not your screen. Nothing will pop over your work.', 500);   const open = await ab('pup_open_window', { sessionId: sid, url: 'https://wiki.adom.inc/adom/pup-bridge', owner: 'pup dock demo' }, 120000, tgt.name);-  if (open._err) { lines.push('   could not open: ' + open._err); return lines; }+  if (open._err) { await cap('The demo could not open a window: ' + open._err); lines.push('   could not open: ' + open._err); return lines; }   lines.push('   open: ' + (open.sessionId || sid)); -  lines.push('');-  lines.push('2. LOOK AT YOUR TASKBAR right now. The new button is not a generic Chrome icon: it is');-  lines.push('   the Adom teal tile wearing this thread\'s NAME ("pup dock demo"), with the live page');-  lines.push('   favicon badged in the corner. Every AI thread gets its own named button, so your');-  lines.push('   taskbar reads as a list of your threads. While the icon lands you will see a small');-  lines.push('   PROGRESS BAR under the button: pup times every operation and fills the bar over how');-  lines.push('   long it usually takes, instead of flashing orange at you.');-  await sleep(3500);+  await capWait('Step 2: look at the NEW TASKBAR BUTTON at the bottom of your screen. It is a teal tile wearing this thread\'s name, "pup dock demo", with the page favicon badged on its corner. Every AI thread gets its own named button.', 1000);+  await capWait('The small bar FILLING UNDER that button is pup\'s progress signal: it times every operation and fills over how long it usually takes. No orange flashing.', 800); -  lines.push('');-  lines.push('3. Screenshot, without touching your screen: the window renders in the background and');-  lines.push('   pup reads the pixels off-screen (watch the button, the progress bar runs again).');+  await capWait('Step 3: I am taking a SCREENSHOT of that background window right now. Watch the progress bar run under its button. Your screen is not touched: the page renders off-screen.', 300);   const shot = await ab('pup_screenshot', { sessionId: sid }, 60000, tgt.name);-  lines.push(shot._err ? '   screenshot failed: ' + shot._err : '   screenshot: ' + shot.width + 'x' + shot.height + ' (the AI can read any page without disturbing you)');+  lines.push(shot._err ? '   screenshot failed: ' + shot._err : '   screenshot: ' + shot.width + 'x' + shot.height); -  lines.push('');-  lines.push('4. RIGHT-CLICK that taskbar button when you get a moment: pup installs a jump list on');-  lines.push('   every window: Annotate this page, Switch to logged-in/public view (wiki windows),');-  lines.push('   Open pup dashboard, Move to my workspace, Close ALL Adom Pup windows.');-  await sleep(2500);+  await capWait('Step 4: that button also carries a RIGHT-CLICK menu. Try it later: Annotate this page, switch wiki views, open the pup dashboard, move the page to your workspace, close all pup windows.', 500); -  lines.push('');-  lines.push('5. The finale: ANNOTATION, live. Bringing the window up (with the on-screen caption');-  lines.push('   pup always shows before a foreground, naming who and why), then drawing on the page.');-  await ab('pup_raise_os_window', { sessionId: sid, foregroundReason: 'you clicked Run the demo on the pup dashboard: watch the annotation feature draw on the page' }, 30000, tgt.name);-  await sleep(1200);+  await capWait('Step 5, the finale: I am about to bring the window UP ON YOUR SCREEN to demonstrate annotation. pup always captions a foreground with who is doing it and why, like this.', 500);+  await ab('pup_raise_os_window', { sessionId: sid, foregroundReason: 'the pup demo you started: watch the annotation feature draw on this page' }, 30000, tgt.name);+  await sleep(800);+  // glide the visible Adom cursor so the eye lands where the action will be+  await ab('pup_hover', { sessionId: sid, x: 700, y: 380, intent: 'the demo is about to draw HERE', steps: 14 }, 20000, tgt.name);+  await sleep(600);   const arm = await ab('pup_annotate', { sessionId: sid, tool: 'pen' }, 30000, tgt.name);   if (!arm._err) {-    await sleep(600);-    const draw = "(async()=>{const r=document.getElementById('__pup_annotate');if(!r)return 'no overlay';const cv=r.querySelector('canvas');if(!cv)return 'no canvas';const mk=(t,x,y)=>new PointerEvent(t,{bubbles:true,cancelable:true,clientX:x,clientY:y,pointerId:1,isPrimary:true,button:0,buttons:t==='pointerup'?0:1});const cx=Math.round(innerWidth*0.35),cy=Math.round(innerHeight*0.4),rad=Math.min(140,Math.round(innerHeight*0.18));cv.dispatchEvent(mk('pointerdown',cx+rad,cy));for(let a=0.25;a<=6.55;a+=0.22){cv.dispatchEvent(mk('pointermove',cx+rad*Math.cos(a),cy+rad*Math.sin(a)));await new Promise(q=>setTimeout(q,16));}cv.dispatchEvent(mk('pointerup',cx+rad,cy));return 'drew';})()";-    const drew = await ab('pup_evaluate', { sessionId: sid, expression: draw }, 30000, tgt.name);+    await cap('Drawing on the live page with the annotation pen now. Watch the red ink.');+    await sleep(400);+    const draw = "(async()=>{const r=document.getElementById('__pup_annotate');if(!r)return 'no overlay';const cv=r.querySelector('canvas');if(!cv)return 'no canvas';const mk=(t,x,y)=>new PointerEvent(t,{bubbles:true,cancelable:true,clientX:x,clientY:y,pointerId:1,isPrimary:true,button:0,buttons:t==='pointerup'?0:1});const cx=Math.round(innerWidth*0.35),cy=Math.round(innerHeight*0.4),rad=Math.min(150,Math.round(innerHeight*0.2));cv.dispatchEvent(mk('pointerdown',cx+rad,cy));for(let a=0.12;a<=6.55;a+=0.12){cv.dispatchEvent(mk('pointermove',cx+rad*Math.cos(a),cy+rad*Math.sin(a)));await new Promise(q=>setTimeout(q,55));}cv.dispatchEvent(mk('pointerup',cx+rad,cy));return 'drew';})()";+    const drew = await ab('pup_evaluate', { sessionId: sid, expression: draw }, 40000, tgt.name);     const drewOk = !drew._err && String(drew.result || '') === 'drew';     if (drewOk) {-      lines.push('   A red circle was just drawn on the page. On the pen-up, pup captured the marked');-      lines.push('   region, put the PNG ON YOUR CLIPBOARD with a caption strip naming the thread and');-      lines.push('   page (paste it into any AI chat), and showed the confirmation toast.');-    } else lines.push('   annotation draw did not run: ' + (drew._err || drew.result || 'unknown'));-  } else lines.push('   annotate did not arm: ' + arm._err);-  await sleep(3500);+      lines.push('   drew the red circle live');+      await capWait('The pen-up CAPTURED the circled region: it is on your CLIPBOARD right now, with a caption strip naming the thread and the page. Paste it into any AI chat. The ink fades; the capture persists.', 1200);+    } else { lines.push('   annotation draw did not run: ' + (drew._err || drew.result || 'unknown')); await cap('The drawing step did not run on this page; the rest of the demo continues.'); }+  } else { lines.push('   annotate did not arm: ' + arm._err); await cap('The annotation overlay did not arm on this page; the rest of the demo continues.'); }+  await capWait('Step 6: and back to the BACKGROUND, out of your way. The window stays open. That is pup: real browser windows an AI drives without ever stealing your screen.', 300);   await ab('pup_lower_os_window', { sessionId: sid }, 20000, tgt.name);+  await cap('pup demo done. Right-click the "pup dock demo" taskbar button to explore, or say: close the pup demo window.');   lines.push('');-  lines.push('6. And back to the background, out of your way. The drawing fades once captured (the');-  lines.push('   capture is what persists, on your clipboard). The window stays open: right-click its');-  lines.push('   taskbar button to explore the jump list, or close it there (or say: close the pup');-  lines.push('   demo window).');-  lines.push('');-  lines.push('Not shown: recording a window to video (full frame rate in the background with highFps),');-  lines.push('the credential vault that signs into sites with no Chrome popups, and the gliding Adom');-  lines.push('cursor that narrates what the AI is doing. Say "show me in pup" to any Adom AI.');+  lines.push('Not shown: window recording (full frame rate in the background with highFps), the');+  lines.push('credential vault that signs into sites with no Chrome popups. Say "show me in pup".');   return lines; }