(function () { const blockedPrefixes = ['/login', '/logout', '/register', '/setup']; if (blockedPrefixes.some(prefix => window.location.pathname.startsWith(prefix))) { return; } if (window.__workspaceAssistantInjected) { return; } window.__workspaceAssistantInjected = true; const style = document.createElement('style'); style.textContent = ` @media (min-width: 1200px) { body.workspace-assistant-open { padding-right: 380px !important; box-sizing: border-box; } } #workspace-assistant-shell { position: fixed; top: 0; right: 0; width: 380px; height: 100vh; z-index: 2500; background: #fff; border-left: 1px solid rgba(0,0,0,.12); box-shadow: -8px 0 24px rgba(0,0,0,.12); display: flex; flex-direction: column; } #workspace-assistant-shell.workspace-assistant-collapsed { transform: translateX(calc(100% - 40px)); } #workspace-assistant-shell iframe { flex: 1; width: 100%; border: 0; background: #fff; } #workspace-assistant-toggle { position: absolute; left: -40px; top: 16px; width: 40px; height: 48px; border: 1px solid rgba(0,0,0,.12); border-right: 0; border-radius: 8px 0 0 8px; background: #1976d2; color: #fff; cursor: pointer; font: inherit; } @media (max-width: 1199px) { body.workspace-assistant-open { padding-right: 0 !important; } #workspace-assistant-shell { width: min(92vw, 380px); } } `; document.head.appendChild(style); const shell = document.createElement('div'); shell.id = 'workspace-assistant-shell'; const toggle = document.createElement('button'); toggle.id = 'workspace-assistant-toggle'; toggle.type = 'button'; toggle.textContent = 'AI'; shell.appendChild(toggle); const iframe = document.createElement('iframe'); iframe.src = '/assistant/'; iframe.title = 'Workspace Assistant'; shell.appendChild(iframe); document.body.appendChild(shell); document.body.classList.add('workspace-assistant-open'); toggle.addEventListener('click', () => { const collapsed = shell.classList.toggle('workspace-assistant-collapsed'); document.body.classList.toggle('workspace-assistant-open', !collapsed); }); function buildPayload() { const rawTitle = document.title || ''; const title = rawTitle.replace(/\s*-\s*Wiki\.js\s*$/i, '').trim() || rawTitle; return { apiBaseUrl: window.location.origin + '/api/sidecar', page: { source: 'bootstrap', path: window.location.pathname, title, url: window.location.href } }; } function bootstrapIframe() { try { const bridge = iframe.contentWindow && iframe.contentWindow.WorkspaceSidebar; if (bridge && typeof bridge.bootstrap === 'function') { bridge.bootstrap(buildPayload()); } } catch (err) { console.warn('workspace assistant bootstrap failed', err); } } iframe.addEventListener('load', () => { setTimeout(bootstrapIframe, 150); }); let lastFingerprint = ''; const sync = () => { const fingerprint = window.location.href + '|' + document.title; if (fingerprint !== lastFingerprint) { lastFingerprint = fingerprint; bootstrapIframe(); } }; window.addEventListener('popstate', sync); window.addEventListener('hashchange', sync); setInterval(sync, 1000); })();