master
John Lauer v2.0.727 (insiders): A pup window waiting on a slow page now explains itself instead of showing a blank PUPBIRTH tab: w… b75d102 22d ago
// pup birth page script (2.0.632). Lives in its own file because an extension page's default content
// security policy refuses inline scripts: an inline version left every title at plain "PUPBIRTH", so pup's
// token lookup timed out on every open and the window showed for the 3 s it waited (measured, 2.0.631).
// 2.0.726: fills in who opened the window, why and where it is going, and counts the wait (John, 2026-10-19).
const q = new URLSearchParams(location.search);
const t = q.get('token') || '';
if (t) document.title = 'PUPBIRTH-' + t;

const thread = (q.get('t') || '').trim();
const reason = (q.get('r') || '').trim();
const target = (q.get('u') || '').trim();
const born = Number(q.get('at')) || Date.now();
const real = /^https?:\/\//i.test(target);
let host = '';
try { if (real) host = new URL(target).host; } catch (e) { host = ''; }

function fill() {
  const $ = (id) => document.getElementById(id);
  $('head').textContent = host ? 'Opening ' + host : 'Opening a page';
  $('thread').textContent = thread ? 'the AI thread "' + thread + '"' : 'an AI thread that did not give its name';
  $('reason').textContent = reason || 'The thread did not say why when it opened this window.';
  const tv = $('target');
  if (real) {
    const a = document.createElement('a');
    a.href = target; a.textContent = target;   // clicking it goes there now, in this same tab
    tv.appendChild(a);
  } else {
    tv.textContent = 'pup has not been told the address yet; the thread will send it next.';
  }
  const st = $('status');
  const tick = () => {
    const s = Math.max(0, Math.round((Date.now() - born) / 1000));
    const slow = s >= 20;
    st.className = 'status' + (slow ? ' slow' : '');
    st.textContent = real
      ? (slow ? 'Still waiting for ' + host + ' to answer (' + s + ' s). The site is slow right now; pup keeps waiting and tries again on its own.'
              : 'Waiting for ' + host + ' to answer (' + s + ' s).')
      : 'Waiting for the thread to say where to go (' + s + ' s).';
  };
  tick(); setInterval(tick, 1000);
  $('card').classList.remove('hidden');
  // The PUPBIRTH-<token> title is how pup finds this window, and it binds within 3 s of the create. Once that is
  // long done, give the tab and the taskbar a title a person can read.
  setTimeout(() => { document.title = (host ? 'Opening ' + host : 'Opening a page') + (thread ? ' for ' + thread : '') + ' (pup)'; }, 10000);
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fill); else fill();