// Main UI management const UI = { async init() { // Tab switching $$(".tab").forEach(tab => { tab.addEventListener("click", () => { const target = tab.dataset.tab; this.switchTab(target); // Load tab data if (target === "search") this.initSearch(); if (target === "memories") this.loadMemories(); if (target === "findings") this.loadFindings(); if (target === "pipeline" && STORE.currentSessionId) this.loadPipelineSession(STORE.currentSessionId); }); }); // Pipeline mode toggle const pipelineCheck = $("#pipeline-mode"); const pipelineModeSelect = $("#pipeline-output-mode"); if (pipelineCheck) { pipelineCheck.addEventListener("change", () => { const on = pipelineCheck.checked; pipelineModeSelect.style.display = on ? "inline-block" : "none"; const toggles = document.querySelectorAll("#skill-toggles .skill-toggle"); toggles.forEach(t => { const cb = t.querySelector("input"); if (cb) cb.disabled = on; }); }); } // Rebuild pipeline button const rebuildBtn = $("#rebuild-pipeline"); if (rebuildBtn && STORE.currentSessionId) { rebuildBtn.addEventListener("click", () => UI.loadPipelineSession(STORE.currentSessionId)); } // Search $("#execute-search").addEventListener("click", () => this.executeSearch()); $("#search-query").addEventListener("keydown", (e) => { if (e.key === "Enter") this.executeSearch(); }); // Check models $("#check-models").addEventListener("click", () => this.checkModels()); // Load state await loadInitialState(); // Init sub-modules DOC_VIEWER.init(); RESEARCH_UI.init(); DOC_UI.init(); }, switchTab(tabName) { $$(".tab").forEach(t => t.classList.remove("active")); $$(".tab-pane").forEach(p => p.classList.remove("active")); document.querySelector(`[data-tab="${tabName}"]`).classList.add("active"); $(`#tab-${tabName}`).classList.add("active"); }, initSearch() { // Search already bound in HTML }, async executeSearch() { const query = $("#search-query").value.trim(); if (!query) return showToast("Enter a search query", "error"); const type = $("#search-type").value; const resultsEl = $("#search-results"); resultsEl.innerHTML = '
Searching...'; try { let results; if (type === "semantic") { results = await RESEARCH_UI.runSemanticSearch(query, STORE.currentDocId); } else { results = await RESEARCH_UI.runTextSearch(query, STORE.currentDocId); } if (!results.length) { resultsEl.innerHTML = 'Search error: ${e.message}
`; } }, async loadMemories() { const list = $("#memories-list"); list.innerHTML = ''; try { if (STORE.currentSessionId) { const res = await API.get(`/api/research/memories?session_id=${STORE.currentSessionId}`); list.innerHTML = (res.memories || []).map(m => `