// Co-op UI polish. // The auth form and footer are client-rendered (React), so a plain `load` // listener runs too early — a MutationObserver re-checks on every DOM change. (function () { // One-time pin migration (2026-10-20): before the server sent // interface.defaultPinnedTools, the client eager-seeded PIN_MCP_ and // LAST_WEB_SEARCH_TOGGLE_pinned as 'false' — artifacts of the old default, // not user choices (there is no unpin UI yet). Those stored values override // the new server defaults forever, leaving Tools/Web Search unpinned. // Clear them ONCE per browser; deliberate unpinning afterwards sticks. try { if (!localStorage.getItem('coopPinMigration20261020')) { if (localStorage.getItem('PIN_MCP_') === 'false') localStorage.removeItem('PIN_MCP_'); if (localStorage.getItem('LAST_WEB_SEARCH_TOGGLE_pinned') === 'false') { localStorage.removeItem('LAST_WEB_SEARCH_TOGGLE_pinned'); } localStorage.setItem('coopPinMigration20261020', '1'); } } catch (e) { /* storage unavailable — non-fatal */ } function hideSignupPrompt() { document.querySelectorAll('p').forEach(function (p) { var link = p.querySelector('a[href*="register"]'); var text = (p.textContent || ''); if (link || text.indexOf("Don't have an account") !== -1) { p.style.display = 'none'; } }); } // Footer: turn the plain co-op text (injected at build time) into the // linked version — "Inference Cooperative" links to the homepage. function fixFooter() { var f = document.querySelector('footer'); if (!f || f.dataset.coopFooter) return; f.dataset.coopFooter = '1'; f.innerHTML = 'Inference Cooperative' + ' · Our AI, governed together'; } // PWA chrome bands (Android status bar + navigation bar, iOS safe areas): // LibreChat ships static meta theme-color tags and never updates them, so // the OS bands keep the install-time colors. Sync ONE meta tag to the app's // RESOLVED theme (html.dark class — LibreChat applies it from the user's // theme setting, which defaults to system = the phone's theme). Falls back // to the light/dark media-query pair in index.html when this script is off. var COOP_BG = { light: '#faf8f5', dark: '#22271f' }; function syncThemeColor() { var dark = document.documentElement.classList.contains('dark'); var metas = document.querySelectorAll('meta[name="theme-color"]'); if (!metas.length) return; // Replace the media-query pair with a single tag at the resolved color. metas.forEach(function (m, i) { if (i === 0) { m.removeAttribute('media'); m.setAttribute('content', dark ? COOP_BG.dark : COOP_BG.light); } else { m.remove(); } }); } var themeObserverRunning = false; function startThemeSync() { if (themeObserverRunning) return; themeObserverRunning = true; syncThemeColor(); new MutationObserver(syncThemeColor).observe(document.documentElement, { attributes: true, attributeFilter: ['class'], }); var mq = window.matchMedia('(prefers-color-scheme: dark)'); if (mq && mq.addEventListener) mq.addEventListener('change', syncThemeColor); } function run() { hideSignupPrompt(); fixFooter(); startThemeSync(); } function start() { run(); new MutationObserver(run).observe(document.body, { childList: true, subtree: true, }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); } })();