personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chat: unify talent markdown rendering

+24 -7
+3 -1
apps/chat/tests/test_routes.py
··· 172 172 assert "chat had trouble" in html 173 173 174 174 175 - def test_chat_day_marks_talent_summary_for_markdown_bootstrap( 175 + def test_chat_day_emits_raw_talent_markdown_source_for_bootstrap( 176 176 journal_copy, monkeypatch 177 177 ): 178 178 day = "20990102" ··· 212 212 '<div class="chat-talent-card-detail ' 213 213 'chat-talent-card-detail--markdown" data-markdown="1">**bad args**</div>' 214 214 ) in html 215 + assert "<strong>done</strong>" not in html 216 + assert "<strong>bad args</strong>" not in html 215 217 216 218 217 219 def test_chat_event_anchor_ids_are_stable(journal_copy, monkeypatch):
+21 -6
apps/chat/workspace.html
··· 74 74 75 75 insertTimeSeparators(transcript); 76 76 decorateBubbles(transcript); 77 - bootstrapMarkdownDetails(transcript); 77 + document.addEventListener('DOMContentLoaded', () => { 78 + bootstrapMarkdownDetails(transcript); 79 + }, { once: true }); 78 80 79 81 if (isToday && window.appEvents) { 80 82 chatEventsCleanup = window.appEvents.listen('chat', { ··· 170 172 } 171 173 172 174 function bootstrapMarkdownDetails(list) { 173 - list.querySelectorAll('[data-markdown="1"]').forEach((node) => { 174 - const text = node.textContent || ''; 175 - node.innerHTML = window.AppServices.renderMarkdown(text); 176 - node.removeAttribute('data-markdown'); 175 + const nodes = Array.from(list.querySelectorAll('[data-markdown="1"]')); 176 + nodes.forEach((node) => { 177 + renderTalentMarkdownInto(node, node.textContent || ''); 177 178 }); 179 + const remaining = list.querySelectorAll('[data-markdown="1"]'); 180 + if (remaining.length) { 181 + throw new Error('unrendered talent markdown details remain'); 182 + } 183 + } 184 + 185 + function renderTalentMarkdownInto(node, source) { 186 + // Single path from markdown source to rendered HTML for talent card details. 187 + // SSR initial-transcript bootstrap and live-append flow both route here. 188 + if (!window.AppServices || typeof window.AppServices.renderMarkdown !== 'function') { 189 + throw new Error('talent markdown renderer is unavailable'); 190 + } 191 + node.innerHTML = window.AppServices.renderMarkdown(source || ''); 192 + node.removeAttribute('data-markdown'); 178 193 } 179 194 180 195 function appendEventFromLive(msg, list) { ··· 295 310 if (status === 'finished' || status === 'errored') { 296 311 const detailNode = document.createElement('div'); 297 312 detailNode.className = 'chat-talent-card-detail chat-talent-card-detail--markdown'; 298 - detailNode.innerHTML = window.AppServices.renderMarkdown(detail || ''); 313 + renderTalentMarkdownInto(detailNode, detail || ''); 299 314 card.appendChild(detailNode); 300 315 } else { 301 316 const detailNode = document.createElement('span');