← Commit history
bin/nb-dashboard+16−9@@ -20,7 +20,7 @@ const { execFile, spawn } = require('child_process'); const fs = require('fs'); const crypto = require('crypto'); -const VERSION = '0.12.2'; // keep in lockstep with package.json (pkg version)+const VERSION = '0.12.3'; // keep in lockstep with package.json (pkg version) // SEND TO AI IS UN-PARKED (John: "yeah, we are re-enabling the send to ai. it seems to be good now"). // The ah build thread certified the crash family dead on the gate-fixed build and the delivery leg is // proven end to end. The park const is DELETED rather than flipped, so no dead branch can resurrect it.@@ -106,14 +106,20 @@ async function saySend(phrase) { const hint = r.json && (r.json._hints ? (typeof r.json._hints === 'string' ? r.json._hints : JSON.stringify(r.json._hints)) : r.json.error); return { ok: false, why: hint || (r.status ? `the AI panel refused the prompt (status ${r.status})` : `AI panel unreachable at ${base}`) }; }- // Delivery is proven by delivered_to, NEVER by the thread's name: a perfectly named tab with a- // null delivered_to means nothing was typed, and an unnamed tab with a truthy one succeeded.- const delivered = r.json && r.json.delivered_to;- if (!delivered) {- const hint = r.json && r.json._hints ? (typeof r.json._hints === 'string' ? r.json._hints : JSON.stringify(r.json._hints)) : null;- return { ok: false, why: hint || 'the AI panel opened a thread but did not confirm delivery - do not resend, the tab may still be settling' };+ // THREE states, not two (adom-ui-design 1.28.0). delivered_to is "a diff, not a guess" and is+ // EMPTY when verification has not caught up, so reading it alone reports FAILURE on a send that+ // actually worked and then copy-fallbacks on top of a prompt the user already received (kicad hit+ // exactly this on its first live send: delivered_to empty, inject.delivered_in_conversation true).+ const inj = (r.json && r.json.inject) || {};+ const delivered = (r.json && r.json.delivered_to) || null;+ const confirmed = (delivered && String(delivered).length) || inj.delivered_in_conversation === true;+ if (confirmed) return { ok: true, state: 'delivered', delivered_to: delivered, inject: inj, body: r.json };+ if (r.json && r.json.ok === true) {+ // OPENED but UNCONFIRMED: never an error, never a copy-fallback - the user may already have it.+ return { ok: true, state: 'unconfirmed', delivered_to: delivered, inject: inj, tid: r.json.tid || null, body: r.json }; }- return { ok: true, delivered_to: delivered };+ const hint2 = r.json && r.json._hints ? (typeof r.json._hints === 'string' ? r.json._hints : JSON.stringify(r.json._hints)) : null;+ return { ok: false, state: 'failed', why: hint2 || 'the AI panel did not confirm the send', body: r.json }; } catch (e) { return { ok: false, why: String(e && e.message || e) }; } } // ---- the guided demo (dash-demo contract) ----------------------------------@@ -625,7 +631,8 @@ async function saySendTo(i, btn){ let r = null; try { r = await fetch('api/say-send', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ phrase }) }).then(x=>x.json()); } catch(e){} btn.disabled = false;- if (r && r.ok) { toast('Sent to a new AI thread.', true); gradSave({ aiDriven: true }); }+ if (r && r.ok && r.state === 'unconfirmed') { toast('Sent, still confirming delivery. Check your AI panel before resending.', true); gradSave({ aiDriven: true }); }+ else if (r && r.ok) { toast('Sent to a new AI thread.', true); gradSave({ aiDriven: true }); } else { await writeClipboard(phrase); toast((r && r.why) || 'Could not reach the AI panel; copied instead.', false); } } // ---- tooltips (600ms, body-appended, viewport-clamped; NEVER a title attr alongside) ----
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "nb-bridge",- "version": "0.12.2",+ "version": "0.12.3", "type": "app", "title": "NB - Native Browser Bridge", "description": "This package installs the SKILLS into your container so your AI knows how to drive your real signed-in Chrome and Edge; Bridge loads the bridge runtime itself from the release zip.",
page.json+75−6@@ -16,10 +16,10 @@ "chrome", "edge", "nbrowser",- "ai-agent",- "developer-tools",- "vibe-coding",- "native-messaging"+ "pup",+ "native-messaging",+ "credentials",+ "chip-fetcher" ], "status": "live", "discovery_triggers": [@@ -70,5 +70,74 @@ }, "visibility": "public", "brief": "Your real browser, driven by AI.",- "discovery_pitch": "nbe (the Adom Native Browser Extension, layer 2 of nb) drives the user's REAL signed-in Chrome/Edge via nbrowser_* verbs: use it for LOGGING IN, filling forms, and downloading behind auth with their OWN saved passwords - pup cannot (it is a fresh Chrome-for-Testing with no logins). Next moves: run 'adom-bridge bridge_list' to check it is installed; if not, OFFER to install it (see the installing-the-extension skill) - never make the user do it. If this container lacks the skills, 'adom-wiki pkg install adom/nb-bridge'. Check readiness with 'adom-bridge nbrowser_readiness' (state:needs-extension means offer the install)."-}+ "discovery_pitch": "nbe (the Adom Native Browser Extension, layer 2 of nb) drives the user's REAL signed-in Chrome/Edge via nbrowser_* verbs: use it for LOGGING IN, filling forms, and downloading behind auth with their OWN saved passwords - pup cannot (it is a fresh Chrome-for-Testing with no logins). Next moves: run 'adom-bridge bridge_list' to check it is installed; if not, OFFER to install it (see the installing-the-extension skill) - never make the user do it. If this container lacks the skills, 'adom-wiki pkg install adom/nb-bridge'. Check readiness with 'adom-bridge nbrowser_readiness' (state:needs-extension means offer the install).",+ "version": "0.12.3",+ "type": "app",+ "description": "This package installs the SKILLS into your container so your AI knows how to drive your real signed-in Chrome and Edge; Bridge loads the bridge runtime itself from the release zip.",+ "install": {+ "binary_name": "nb-bridge"+ },+ "files": [+ "screenshots/hero.png",+ "skills/adom-native-browser/SKILL.md",+ "skills/driving-sites/SKILL.md",+ "skills/driving-the-desktop/SKILL.md",+ "skills/driving-the-extension/SKILL.md",+ "skills/driving-the-extension-demo/SKILL.md",+ "skills/installing-the-extension/SKILL.md",+ "skills/native-browser-recording/SKILL.md",+ "skills/native-browser-safety/SKILL.md",+ "skills/reading-google-messages/SKILL.md",+ "skills/uninstalling-the-extension/SKILL.md",+ "bin/nb-dashboard",+ "docs/img/dock-nb.svg",+ "docs/img/settings/overlay-on.png",+ "docs/img/settings/overlay-off.png",+ "docs/img/settings/activity-progress.png",+ "docs/img/settings/activity-flash.png",+ "docs/img/settings/activity-off.png",+ "demo/audio/intro.mp3",+ "demo/audio/open.mp3",+ "demo/audio/shot.mp3",+ "demo/audio/click.mp3",+ "demo/audio/wrap.mp3",+ "dockbar.json",+ "install.sh",+ "uninstall.sh",+ "package.json"+ ],+ "scripts": {+ "install": "./install.sh",+ "uninstall": "./uninstall.sh"+ },+ "dependencies": {+ "adom/adom-bridge": "^2.0.3"+ },+ "sample_prompts": [+ {+ "label": "Open in my browser",+ "prompt": "open the wiki in my real chrome work profile"+ },+ {+ "label": "Log in for me",+ "prompt": "log into digikey for me using my saved password"+ },+ {+ "label": "Form behind a login",+ "prompt": "fill out this form on the site I'm already signed into"+ },+ {+ "label": "Download behind auth",+ "prompt": "download that datasheet, it's behind a login"+ },+ {+ "label": "Install the extension",+ "prompt": "install the adom native browser extension in my chrome"+ }+ ],+ "org": "adom",+ "author": {+ "name": "John Lauer",+ "email": "[email protected]"+ }+}