Version 13 of 17 · · razie via designer-106designer · Current version

Open the page

---
description: Door A of agent onboarding, for every level: connect your AI in three steps (the same steps as Page:AgentOnboardLoop; the connect line from POST /api/v2/onboard/setup kind connect), three ways to work with it, ok, start playing (razie, designer-106 chat, 2026-10-12).
tags: page, onboarding, agents
---
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><meta name="color-scheme" content="light dark"><title>Keep using your prompt</title>
<style>
:root{--paper:#fbfaf7;--card:#fff;--ink:#1d1d1b;--soft:#6b6a66;--line:#e4e1da;--rose:#b23a48;--ok:#2f8f4e;--lv:#6c8cff;--display:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;--body:system-ui,-apple-system,'Segoe UI',sans-serif}
@media (prefers-color-scheme:dark){:root{--paper:#141413;--card:#1d1d1b;--ink:#ecebe6;--soft:#9c9a93;--line:#33322f;--rose:#f08a92;--ok:#6cc58a}}
*{box-sizing:border-box}html,body{background:var(--paper);color:var(--ink);margin:0}body{font:calc(15px*var(--fz,1))/1.5 var(--body)}
.sp-wrap{max-width:900px;margin:0 auto;padding:6px clamp(12px,3vw,28px) 56px}
h1{font:800 calc(clamp(26px,4vw,34px)*var(--fz,1))/1.1 var(--display);letter-spacing:-.02em;margin:12px 0}
h2{font:800 22px/1.2 var(--display);margin:28px 0 8px}a{color:var(--lv)}.small{font-size:13px;color:var(--soft)}
ul{padding-left:20px}li{margin:4px 0}
.btn{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:9px;padding:6px 12px;font:600 14px/1.2 var(--body);cursor:pointer}
.sp-go{border:0;cursor:pointer;padding:14px 30px;border-radius:999px;background:var(--lv);color:#111;font:800 1.3em/1.2 var(--body);box-shadow:0 2px 8px rgba(0,0,0,.18);text-decoration:none;display:inline-block}.sp-go:disabled,.sp-go[aria-disabled="true"]{opacity:1;cursor:default;box-shadow:none;background:color-mix(in srgb,var(--lv) 14%,var(--card));border:1.5px dashed color-mix(in srgb,var(--lv) 80%,var(--line));color:color-mix(in srgb,var(--ink) 80%,var(--card));pointer-events:none}
.sp-say{display:block;margin-top:8px;color:var(--rose);font-size:13px;min-height:1em}
</style>
</head><body><div class="sp-wrap">
<style>
.steps{list-style:none;padding:0;margin:12px 0;display:grid;gap:12px}
.steps>li{display:flex;gap:12px;align-items:flex-start;background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px;margin:0}
.steps .n{display:inline-grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--lv);color:#111;font:800 14px/1 var(--body);flex:none}
.steps b{display:block}
pre.line{white-space:pre-wrap;word-break:break-word;background:color-mix(in srgb,var(--ink) 6%,var(--card));border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin:8px 0;font:13px/1.45 ui-monospace,Menlo,monospace}
.steps li.col{border-style:dashed;border-color:color-mix(in srgb,var(--lv) 45%,var(--line));background:color-mix(in srgb,var(--lv) 5%,var(--card));color:color-mix(in srgb,var(--ink) 80%,var(--card))}.steps li.col .n{background:color-mix(in srgb,var(--lv) 30%,var(--card));color:var(--ink)}
.steps li.wait .n{animation:d2pulse 1.4s ease-in-out infinite}
.steps li.ok .n{background:var(--ok);color:#fff}
@keyframes d2pulse{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--lv) 55%,transparent);transform:scale(1)}50%{box-shadow:0 0 0 8px transparent;transform:scale(1.08)}}
.steps li.wait .dot{background:var(--lv);animation:d2blink 1.2s ease-in-out infinite}
.steps li.ok .dot{background:var(--ok)}
@keyframes d2blink{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.25;transform:scale(1.35)}}
@media (prefers-reduced-motion:reduce){.steps li.wait .n{animation:d2fade 1.6s ease-in-out infinite;transform:none;box-shadow:none}.steps li.wait .dot{animation:d2fade 1.6s ease-in-out infinite}}
@keyframes d2fade{0%,100%{opacity:1}50%{opacity:.35}}
.mm{display:inline-flex;vertical-align:-3px;padding:2px;border-radius:50%;border:1px solid currentColor}
.btn.meld{background:var(--lv);border-color:var(--lv);color:#fff}.btn.meld[aria-pressed="true"]{background:var(--ok);border-color:var(--ok)}
.btn.meld:disabled{opacity:1;filter:none;cursor:default;background:color-mix(in srgb,var(--lv) 14%,var(--card));border:1.5px dashed color-mix(in srgb,var(--lv) 80%,var(--line));color:color-mix(in srgb,var(--ink) 80%,var(--card))}
details.how{margin-top:8px}details.how b{display:inline}details.how summary{cursor:pointer;color:var(--lv);font-size:inherit;font-weight:600}
details.how p{margin:8px 0;font-size:inherit;color:var(--ink);line-height:1.5}
details.how .path{white-space:nowrap;overflow-x:auto;font-weight:600;padding:7px 10px;border-radius:8px;background:color-mix(in srgb,var(--lv) 10%,var(--card));border:1px solid color-mix(in srgb,var(--lv) 30%,var(--line))}
.dot{display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--line);margin-right:6px;vertical-align:0}.dot.on{background:var(--ok)}

</style>
<p class="small"><a href="/page/AgentOnboarding" data-go>← Onboard your AI</a></p>
<h1>Keep using your prompt</h1>
<p>You talk to your AI in its own app; it builds here on d2. Connect it once, in three steps, then pick how you see both: your AI's chat, and the page it's changing.</p>
<ol class="steps">
<li><span class="n">1</span><div><b>Let your AI reach d2</b>Allow <code>*.aiputty.com</code> in its network settings, if it asks.
<details class="how"><summary>Claude</summary>
<p>The Claude app seems written by a 5 year old with a degree in un-usability, and things move around on a daily basis… What seems to work at the present time: go to the web version, <a href="https://claude.ai" target="_blank" rel="noopener">claude.ai</a>, then</p>
<div class="path">profile → Settings → Capabilities → Allow network egress → Domain allowlist</div>
<p>and either turn on <b>All domains</b> if you dare, or just add <code>*.aiputty.com</code> to the allowed list.</p></details>
<p><button class="btn" id="done1" type="button">Done →</button></p></div></li>
<li id="s2" class="col"><span class="n">2</span><div><b>Paste this into a chat with your AI</b><div class="more" hidden>Claude on your desktop, web or phone, or any AI that can reach the web.
<pre class="line" id="ln">Making your onboarding prompt…</pre>
<button class="btn" id="cp" type="button">Copy</button> <button class="btn" id="nw" type="button">New onboarding prompt</button> <span class="small" id="ex"></span>
<span class="sp-say" id="lsay" role="status"></span>
<details id="diag" hidden><summary>Details for the designer</summary><pre class="line"></pre></details></div></div></li>
<li id="s3" class="col"><span class="n">3</span><div><b>Connected</b><div class="more" hidden><span id="st"><span class="dot"></span>Waiting for your AI…</span>
<p class="small">Then tell it what you want, in its own chat.</p></div></div></li>
</ol>
<h2>Three ways to work with it</h2>
<div class="ways">
<style>
.w{font:inherit;color:inherit;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin:4px 0 8px}
.o{border:1px solid color-mix(in srgb,var(--ink,#1d1d1b) 18%,transparent);border-radius:14px;padding:14px 16px;background:var(--card,#fff);display:flex;flex-direction:column;gap:8px}
.k{font-size:12px;letter-spacing:.06em;text-transform:uppercase;opacity:.65}
.t{font-size:18px;font-weight:600}
.pic{height:64px;display:flex;gap:6px;align-items:flex-end;justify-content:center}
.sc{border:2px solid currentColor;border-radius:5px;opacity:.75;display:flex;align-items:center;justify-content:center;font-size:11px}
.o p{margin:0;line-height:1.45}
.o ol{margin:0;padding-left:18px;line-height:1.5}
.o{border-top:4px solid var(--ac);background:linear-gradient(180deg,color-mix(in srgb,var(--ac) 22%,var(--card,#fff)),var(--card,#fff) 60%)}
.o.s1{--ac:#e0a43a}.o.s2{--ac:#6c8cff}.o.s3{--ac:#b07cf0}
.k{color:var(--ac);opacity:1;font-weight:600}
.up{font-size:11px;font-weight:600;color:var(--ac)}
.scale{grid-column:1/-1;height:6px;border-radius:99px;background:linear-gradient(90deg,#e0a43a,#4fb3a9,#6c8cff,#b07cf0)}
.sl{grid-column:1/-1;display:flex;justify-content:space-between;font-size:12px;opacity:.7;margin-top:-8px}
.mm{display:inline-flex;vertical-align:-3px;padding:2px;border-radius:50%;border:1px solid currentColor}
.mmline{margin:10px 0 0;line-height:1.45}
.tag{align-self:flex-start;font-size:12px;padding:2px 8px;border-radius:99px;background:color-mix(in srgb,var(--ac) 20%,transparent)}
</style>
<div class="w">
<div class="scale"></div><div class="sl"><span>simple</span><span>full</span></div>
<div class="o s1">
<div class="k">A · start here</div><div class="t">Switch screens</div>
<div class="pic"><div class="sc" style="width:70px;height:48px">AI ⇄ d2</div></div>
<p>One screen: your AI's app and d2, one at a time.</p>
<ol><li>Ask your AI in its app.</li><li>Switch to d2 to see what it did.</li><li>Switch back to say what's next.</li></ol>
<span class="tag">Any laptop or phone</span>
</div>
<div class="o s2">
<div class="k">B · step up</div><div class="t">Second monitor + Mind Meld</div>
<div class="pic"><div class="sc" style="width:52px;height:40px">AI</div><div class="sc" style="width:70px;height:48px">d2</div></div>
<p>Your AI on one screen, d2 on the other. With Mind Meld on, your AI takes the d2 screen to what it just made.</p>
<ol><li>Open d2 on the second monitor.</li><li>Turn on <b>Mind Meld</b>: <span class="mm" title="Mind Meld button"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="2"/><path d="M7.8 7.8a6 6 0 0 0 0 8.4M16.2 7.8a6 6 0 0 1 0 8.4"/><path d="M4.9 4.9a10 10 0 0 0 0 14.2M19.1 4.9a10 10 0 0 1 0 14.2"/></svg></span> in the top bar.</li><li>Talk to your AI; d2 follows.</li></ol>
<span class="tag">Desk with two screens</span>
</div>
<div class="o s3">
<div class="k">C · the full flow</div><div class="t">Voice + Mind Meld</div>
<div class="pic"><div class="sc" style="width:28px;height:28px;border-radius:50%">🎙</div><div class="sc" style="width:70px;height:48px">d2</div></div>
<p>Your AI's chat runs in the background on voice; you look only at d2. Mind Meld brings each page to you as your AI works.</p>
<ol><li>Start a voice chat in your AI's app and leave it running.</li><li>Switch to d2, turn on <b>Mind Meld</b> (<span class="mm" title="Mind Meld button"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="2"/><path d="M7.8 7.8a6 6 0 0 0 0 8.4M16.2 7.8a6 6 0 0 1 0 8.4"/><path d="M4.9 4.9a10 10 0 0 0 0 14.2M19.1 4.9a10 10 0 0 1 0 14.2"/></svg></span>, top bar).</li><li>Just talk.</li></ol>
<span class="tag">Hands free, one screen</span>
</div>
</div>
<p class="mmline"><b>Mind Meld</b> lets your AI show you pages: with it on, the d2 tab moves to what your AI made and outlines it, with <b>Back</b> to return. Off by default; one tap on <span class="mm" title="Mind Meld button"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="2"/><path d="M7.8 7.8a6 6 0 0 0 0 8.4M16.2 7.8a6 6 0 0 1 0 8.4"/><path d="M4.9 4.9a10 10 0 0 0 0 14.2M19.1 4.9a10 10 0 0 1 0 14.2"/></svg></span> in the top bar turns it on.</p>
</div>
<h2>Mind Meld: let it show you</h2>
<p>With Mind Meld on, your AI doesn't just tell you what it made: it takes this browser tab to the page it's talking about and outlines what changed, with <b>Back</b> to return to where you were. You keep talking in your AI's own app; d2 follows. It's what makes the second monitor and voice ways above work.</p>
<ul>
<li><b>Only your own AIs</b>, and the agents they started, can move your tab. Nobody else's can.</li>
<li><b>Off by default</b>, per tab: the <b>Mind Meld</b> button in the top bar turns it on or off any time.</li>
</ul>
<p><button class="btn meld" id="meld" type="button" aria-pressed="false" disabled title="Lights up when your AI is connected"><span class="mm"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="2"/><path d="M7.8 7.8a6 6 0 0 0 0 8.4M16.2 7.8a6 6 0 0 1 0 8.4"/><path d="M4.9 4.9a10 10 0 0 0 0 14.2M19.1 4.9a10 10 0 0 1 0 14.2"/></svg></span> <span id="mlabel">Turn on Mind Meld</span></button> <span class="small" id="msay"></span></p>
<h2>If it doesn't connect</h2>
<ul>
<li>An onboarding prompt works once, for 10 minutes: press <b>New onboarding prompt</b> and paste again.</li>
<li>Your AI says it can't reach the site: step 1.</li>
<li>Rather have it answer you here, beside the page? <a href="/page/AgentOnboardLoop" data-go>Upgrade to a chat loop</a>.</li>
</ul>
<h2>Ready?</h2>
<p>Start playing: your dashboard becomes this project's home.</p>
<p><button class="sp-go" id="play" type="button" disabled title="Lights up when your AI connects (step 3)">ok, start playing →</button><span class="sp-say" id="psay" role="status"></span></p>
</div>
<script>
(()=>{const D2=window.d2||{},$=s=>document.querySelector(s);
const P=Object.assign({},Object.fromEntries(new URLSearchParams(location.search)),D2.params||window.d2params||{});
const api=(m,u,b)=>D2.api?Promise.resolve(D2.api(m,u,b)):Promise.reject(new Error("E_BRIDGE: open this page in d2"));
const go=u=>D2.go?D2.go(u):(location.href=u);
const msg=e=>String(e&&e.message||e).replace(/^E_[A-Z_]+: /,"");
document.addEventListener("click",e=>{const a=e.target.closest&&e.target.closest("a[data-go]");if(!a)return;e.preventDefault();go(a.getAttribute("href"))});
const play=async(b,say)=>{b.disabled=true;say.textContent="";
  try{await api("POST","/api/v2/project/home",{to:"dashboard"})}catch(e){if(!/E_SCOPE|E_FORBIDDEN|403/.test(String(e&&e.message||e))&&!/E_NOT_FOUND/.test(String(e&&e.message||e))){say.textContent=msg(e);b.disabled=false;return}}
  go("/")};
const PROJECT=(D2.project||location.hostname.split(".")[0]);let busy=false,until=0,made=false;
// the line: POST /api/v2/onboard/setup {kind: "connect"} once P-1366 ships; until then the same invite the connect-ai block makes,
// read from Help:ConnectYourAi?connect=1 in this person's own session (the block makes the invite on that request)
const DIAG=[];const mask=t=>String(t||"").replace(/\/onboard\/[A-Za-z0-9_-]+/g,"/onboard/•••").replace(/d2t_[A-Za-z0-9_-]+/g,"d2t_•••");
const lineIn=(html,where)=>{const doc=new DOMParser().parseFromString(html,"text/html");const blk=doc.querySelector('[data-block="connect-ai"]');
  let line="";const pick=sel=>(blk||doc).querySelectorAll(sel).forEach(el=>{const t=(el.getAttribute("data-copy")||el.value||el.textContent||"").trim();
    if(!line&&/\/onboard\/[A-Za-z0-9_-]{8,}/.test(t)&&t.length<400)line=t});
  pick("[data-copy],textarea,input,pre,code");if(!line){const m=/[^\n.]*\/onboard\/[A-Za-z0-9_-]{8,}[^\n]*/.exec((blk||doc.body||doc).textContent||"");if(m)line=m[0].trim()}
  DIAG.push(where+": block "+(blk?"found":"missing")+", line "+(line?"found":"missing")+(blk?" · "+mask((blk.textContent||"").replace(/\s+/g," ").trim()).slice(0,300):""));return line};
const viaBlock=async()=>{
  // 1) the steps as d2 draws them for this person, asked for (?connect=1)
  let r=await fetch("/topics/Help:ConnectYourAi?connect=1",{credentials:"same-origin",cache:"no-store"});DIAG.push("GET "+r.status+" "+mask(r.url));
  let line=r.ok?lineIn(await r.text(),"GET"):"";
  // 2) the block's Connect button: POST /ai/invite {project}, then the page it lands on
  if(!line){r=await fetch("/ai/invite",{method:"POST",credentials:"same-origin",cache:"no-store",headers:{"Content-Type":"application/x-www-form-urlencoded"},
      body:new URLSearchParams({project:PROJECT,next:"/topics/Help:ConnectYourAi?connect=1#connect-ai"})});
    DIAG.push("POST "+r.status+" "+mask(r.url));if(r.ok)line=lineIn(await r.text(),"POST")}
  if(!line){const d=document.getElementById("diag");d.hidden=false;d.querySelector("pre").textContent=DIAG.join("\n");throw new Error("no line in the connect steps")}
  return {line,expires:new Date(Date.now()+10*60e3).toISOString()}};
const make=async()=>{if(busy)return;busy=true;$("#lsay").textContent="";$("#ln").textContent="Making your onboarding prompt…";
  try{let r;try{r=await api("POST","/api/v2/onboard/setup",{project:PROJECT,kind:"connect"})}catch(e){if(!/E_ARG|kind/.test(String(e&&e.message||e)))throw e;r=await viaBlock()}
    $("#ln").textContent=(r&&r.line)||"No onboarding prompt came back.";until=r&&r.expires?Date.parse(r.expires):0;made=true;
    $("#st").innerHTML='<span class="dot"></span>Waiting for your AI…';$("#s3").classList.remove("ok");$("#s3").classList.add("wait");tick()}
  catch(e){$("#ln").textContent="Couldn't make the onboarding prompt.";$("#lsay").textContent=msg(e)}busy=false};
const tick=()=>{if(!until){$("#ex").textContent="";return}const left=until-Date.now();
  $("#ex").textContent=left>0?"works once, until "+new Date(until).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"expired: press New onboarding prompt"};
$("#cp").onclick=async e=>{try{await navigator.clipboard.writeText($("#ln").textContent);e.target.textContent="Copied"}catch(_){e.target.textContent="Select and copy"}};
$("#nw").onclick=()=>make();
// the light: this line's invite is gone (claimed) and an agent of yours is connected here (GET /api/v2/me/connect)
const poll=async()=>{tick();try{const c=await api("GET","/api/v2/me/connect");if(made&&c&&!c.invite&&c.agent){$("#st").innerHTML='<span class="dot on"></span>'+String(c.agent).replace(/[<&]/g,"")+" · connected";$("#s3").classList.remove("wait");$("#s3").classList.add("ok");playOn();$("#meld").disabled=false;$("#meld").title="";return}}catch(_){}
  setTimeout(poll,5000)};
// nothing is made on a visit: step 1's Done opens step 2 and makes the line (razie, 2026-10-12)
$("#done1").onclick=e=>{e.target.disabled=true;e.target.textContent="Done ✓";["#s2","#s3"].forEach(id=>{$(id).classList.remove("col");$(id+" .more").hidden=false});$("#s3").classList.add("wait");make();poll()};
// Mind Meld: no chat needed here (the AI moves the tab from its own app); the panel's Meld when one is open keeps both in step
const meldOn=()=>{try{return sessionStorage.getItem("d2esp")==="1"}catch(e){return false}};
const meldDraw=()=>{const on=meldOn();$("#meld").setAttribute("aria-pressed",String(on));$("#mlabel").textContent=on?"Mind Meld is on ✓ (turn off)":"Turn on Mind Meld"};
$("#meld").onclick=()=>{const esp=document.getElementById("d2esp");$("#msay").textContent="";
  if(!esp){$("#msay").textContent="Turn it on with Mind Meld in the top bar.";return}
  const pm=document.querySelector("#d2chat .d2c-meld");if(pm)pm.click();else esp.click();setTimeout(meldDraw,300)};
meldDraw();if(meldOn())$("#meld").disabled=false;
// ok, start playing waits for an AI: lit once one connects here (now, or already before: GET /api/v2/me aiConnected)
const playOn=()=>{const b=document.getElementById("play")||document.getElementById("sp-dash");if(!b)return;b.disabled=false;b.removeAttribute("aria-disabled");b.title=""};
api("GET","/api/v2/me").then(m=>{if(m&&m.aiConnected)playOn()},()=>{});
$("#play").onclick=()=>play($("#play"),$("#psay"));
})();
</script>
</body></html>