master
John Lauer rust: Phase 3 complete (vault, cards, wiki auto-sign + view flip, annotate, tab + screen recording, highFps lease, down… 4869577 2mo ago
((sid, minimal, label, tagOn) => {
      // v1.9.185: carry minimal-touch into the page so the title observer below can skip installing
      // itself (see the note at `observe`). Read at document-start, before any page script runs.
      try { if (minimal) window.__pupMinimalTouch = true; } catch (e) {}
      // TOLERANT marker check (v1.8.19): a tab's own suffix may be
      // " (session: <sid>)" OR " (session: <sid> | <tabId>)". This injector must
      // only ADD a marker when NONE is present — if it enforced an exact
      // " (session: <sid>)" it would fight addTabToSession's " | <tabId>" suffix:
      // two MutationObservers appending different strings ping-pong forever, peg the
      // renderer, and flood the CDP pipe (which HUNG pup_open_tab on Edge and
      // poisoned the whole bridge). Matching on the marker PREFIX makes it cooperate.
      const LBL = label || 'ai-thread';
      const MARKER = ' (' + LBL + ': ' + sid;   // no closing paren — matches both forms
      const BASE = ' (' + LBL + ': ' + sid + ')';
      // v1.9.49: do NOT require a pre-existing title. This guard used to be
      //     if (document.title && ...)
      // so a page that never sets a <title> (plenty of app routes and SPA shells serve one) kept an
      // EMPTY title, the session marker was never injected, and the OS window title stayed a bare
      // "Google Chrome for Testing". AD resolves pup windows by their "(session: <id>)" suffix, so
      // that window became INVISIBLE to every branding call: identity stamp, category flip, overlay
      // and jump list all failed with "No visible window with title containing (session: ...)".
      // That is the failure behind icons that look stale or never update — the window was findable
      // right up until it navigated to a title-less page. An empty title must still get the marker.
      // v1.9.56: SELF-HEALING against DUPLICATES. The old check only asked "is my marker absent?",
      // so once a second copy appeared it was never collapsed — measured live as
      //   "○ Public · Hydrogen Desktop - Adom Wiki (session: hdr-wiki) (session: hdr-wiki)"
      // (107-char title). Two independent MutationObservers touch this title (this session-suffix
      // injector and the wiki state-glyph injector); a page that rewrites its own title can let both
      // fire before either sees the other's write, and each appends. Duplicated tags bloat the
      // taskbar-thumbnail CAPTION (the surface we want for status) and, worse, AD resolves pup windows
      // by "(session: <id>" — the same duplicate-tag class that previously made branding land on the
      // WRONG window. So: count OUR OWN tag and normalise to exactly one. Only our own sid is touched,
      // so an adopted tab's re-tag (retagSessionTitle) is never fought.
      const RE_MINE = new RegExp('\\s*\\((?:session|ai-thread): ' + sid.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '(?:[^)]*)\\)', 'g');
      const ensure = () => {
        try {
          const cur = String(document.title || '');
          if (!tagOn) { const clean = cur.replace(RE_MINE, ''); if (clean !== cur) document.title = clean; return; }  // OFF: keep title clean
          const n = (cur.match(RE_MINE) || []).length;
          if (n === 1) return;                                   // already exactly one — leave it alone
          if (n === 0) { document.title = cur + BASE; return; }  // none — add ours
          document.title = cur.replace(RE_MINE, '') + BASE;      // duplicates — collapse to one
        } catch (e) {}
      };
      const observe = () => {
        // v1.9.288: when the tag is OFF we strip once (above) but must NOT run a stripping observer -
        // it would instantly remove the TRANSIENT tag pup adds to resolve the window's hwnd, forcing
        // ambiguous geometry (two same-profile windows share a rect => same hwnd, John's dup-hwnd bug).
        if (!tagOn) return true;
        // v2.0.20: ONLY a real <title> node. The old head/documentElement fallback observed the
        // ENTIRE document subtree on titleless pages (raw JSON/API views), firing ensure() on every
        // DOM mutation — a renderer-pegging cost on exactly the pages least able to afford it. A
        // titleless page keeps its once-stamped tag; continuous enforcement is not worth a freeze.
        const t = document.querySelector('title');
        if (!t) return true;
        // v1.9.185 minimal-touch: in MINIMAL mode we stamp the title ONCE and do NOT install a
        // MutationObserver. On a heavy SPA (Google Slides/Sheets rewrite document.title constantly)
        // this observer re-fired on every one of those writes, each time writing the title BACK —
        // an in-page write loop pup itself created, on the exact windows John saw freeze. The
        // window still carries the tag from the initial stamp; only the continuous re-enforcement
        // is dropped. (window.name, set below, is the durable identity anyway.)
        if (window.__pupMinimalTouch) return true;
        try { window.__pupTagObs = new MutationObserver(ensure); window.__pupTagObs.observe(t, { childList: true, subtree: true, characterData: true }); } catch (e) {}
        return true;
      };
      ensure();
      if (!observe()) document.addEventListener('DOMContentLoaded', () => { observe(); ensure(); });
    })(__SID__, __MINIMAL__, __LABEL__, __TAGON__);