865865 < button id ="sealInputBtn "> 🔒 Seal Input</ button >
866866 < button id ="simulationBtn "> 🎮 Simulations</ button >
867867 < button id ="mumonBtn "> 📚 Mumon +</ button >
868+ < button id ="debuggerBtn "> 🐛 Bloodhound Debugger</ button >
868869 </ div >
869870 </ div >
870871 < button id ="sendBtn " class ="send-btn " aria-label ="Send message "> SEND</ button >
@@ -931,6 +932,56 @@ <h3>📚 Mumon – Gate‑free Publication</h3>
931932 </ div >
932933</ div >
933934
935+ <!-- Bloodhound Debugger Modal -->
936+ < div id ="debuggerModal " class ="modal-overlay " style ="display: none; ">
937+ < div class ="modal " style ="max-width: 900px; ">
938+ < div class ="modal-header ">
939+ < h3 > 🐛 Bloodhound Debugger – ADA‑Powered Forensic Analysis</ h3 >
940+ < button id ="closeDebuggerModal "> ✕</ button >
941+ </ div >
942+ < div class ="modal-body ">
943+ < div class ="field-group ">
944+ < label > Language</ label >
945+ < select id ="debuggerLang ">
946+ < option value ="javascript "> JavaScript</ option >
947+ < option value ="typescript "> TypeScript</ option >
948+ < option value ="python "> Python</ option >
949+ < option value ="rust "> Rust</ option >
950+ </ select >
951+ </ div >
952+ < div class ="field-group ">
953+ < label > Code to analyze</ label >
954+ < textarea id ="debuggerCode " rows ="12 " placeholder ="Paste your code here... "> </ textarea >
955+ </ div >
956+ < div class ="field-group ">
957+ < label > Domain (optional)</ label >
958+ < select id ="debuggerDomain ">
959+ < option value ="code "> General Code</ option >
960+ < option value ="security "> Security Critical</ option >
961+ < option value ="financial "> Financial</ option >
962+ < option value ="medical "> Medical</ option >
963+ </ select >
964+ </ div >
965+ < div class ="field-group ">
966+ < label > Tier</ label >
967+ < select id ="debuggerTier ">
968+ < option value ="CORE "> CORE ADA (faster, minimal)</ option >
969+ < option value ="FULL " selected > FULL ADA (deep analysis, historical patterns)</ option >
970+ </ select >
971+ </ div >
972+ < button id ="debuggerAnalyzeBtn " class ="send-btn " style ="background: var(--amber); color:#000; "> Analyze</ button >
973+ < div id ="debuggerResults " style ="margin-top: 20px; display: none; ">
974+ < h4 > Results</ h4 >
975+ < div id ="debuggerFindings "> </ div >
976+ < div id ="debuggerRefinedCode "> </ div >
977+ < div id ="debuggerTimeline "> </ div >
978+ < div id ="debuggerScores "> </ div >
979+ < button id ="debuggerCopyBtn " class ="send-btn " style ="background: #4c9f70; margin-top: 10px; "> Copy Refined Code</ button >
980+ </ div >
981+ </ div >
982+ </ div >
983+ </ div >
984+
934985< script >
935986 ( function ( ) {
936987 // ---------- BACKGROUND (particle canvas) ----------
@@ -1034,6 +1085,7 @@ <h3>📚 Mumon – Gate‑free Publication</h3>
10341085 let activeWives = JSON . parse ( localStorage . getItem ( 'activeWives' ) ) || [ ...ALL_WIVES ] ; // default all
10351086 let aionHistory = [ ] ; // for AION mode
10361087 let groupHistory = [ ] ; // for group mode, stores { role, content } for context
1088+ const MAX_HISTORY = 150 ; // keep last 150 messages to avoid huge payloads
10371089
10381090 const messagesDiv = document . getElementById ( 'messages' ) ;
10391091 const welcomeMsgDiv = document . getElementById ( 'welcomeMsg' ) ;
@@ -1079,6 +1131,11 @@ <h3>📚 Mumon – Gate‑free Publication</h3>
10791131 }
10801132 }
10811133
1134+ // Helper to trim history arrays
1135+ function trimHistory ( arr ) {
1136+ while ( arr . length > MAX_HISTORY ) arr . shift ( ) ;
1137+ }
1138+
10821139 // Eye badge state management
10831140 let eyeState = 'idle' ; // idle, thinking, refining, void
10841141 function setEyeState ( state ) {
@@ -1779,6 +1836,83 @@ <h4>📋 Synthesis (Score: ${Math.round(result.synthesis.score * 100)}%)</h4>
17791836 document . getElementById ( 'mumonPublishBtn' ) . onclick = mumonPublish ;
17801837 }
17811838
1839+ // ---------- BLOODHOUND DEBUGGER FUNCTIONS ----------
1840+ let currentDebuggerResult = null ;
1841+
1842+ async function runDebugger ( ) {
1843+ const code = document . getElementById ( 'debuggerCode' ) . value . trim ( ) ;
1844+ if ( ! code ) { showToast ( 'Please enter code to analyze' ) ; return ; }
1845+ const language = document . getElementById ( 'debuggerLang' ) . value ;
1846+ const domain = document . getElementById ( 'debuggerDomain' ) . value ;
1847+ const tier = document . getElementById ( 'debuggerTier' ) . value ;
1848+
1849+ const body = { sessionId, code, language, domain, tier } ;
1850+ setStatus ( 'Debugger analyzing...' ) ;
1851+ try {
1852+ const res = await fetchWithTimeout ( `${ API_BASE } /api/debugger` , {
1853+ method : 'POST' ,
1854+ headers : { 'Content-Type' : 'application/json' } ,
1855+ body : JSON . stringify ( body )
1856+ } ) ;
1857+ if ( ! res . ok ) throw new Error ( await res . text ( ) ) ;
1858+ const data = await res . json ( ) ;
1859+ currentDebuggerResult = data ;
1860+
1861+ // Display findings
1862+ const findingsDiv = document . getElementById ( 'debuggerFindings' ) ;
1863+ findingsDiv . innerHTML = '<h4>🔍 Findings</h4>' ;
1864+ if ( data . findings && data . findings . length ) {
1865+ for ( const f of data . findings ) {
1866+ if ( f . patternName ) {
1867+ findingsDiv . innerHTML += `<div class="wife-analysis"><strong>${ f . patternName } </strong> (${ f . severity } )<br/>${ f . suggestion || f . text } </div>` ;
1868+ } else {
1869+ findingsDiv . innerHTML += `<div class="wife-analysis">${ f . text } </div>` ;
1870+ }
1871+ }
1872+ } else {
1873+ findingsDiv . innerHTML += '<p>No known patterns detected.</p>' ;
1874+ }
1875+
1876+ // Refined code
1877+ const refinedDiv = document . getElementById ( 'debuggerRefinedCode' ) ;
1878+ refinedDiv . innerHTML = `<h4>✅ Refined Code</h4><pre style="background:#0a0a0f; padding:12px; border-radius:8px; overflow-x:auto;">${ escapeHtml ( data . refinedCode ) } </pre>` ;
1879+
1880+ // Timeline
1881+ const timelineDiv = document . getElementById ( 'debuggerTimeline' ) ;
1882+ timelineDiv . innerHTML = `<h4>📅 Forensic Timeline</h4><ul>${ data . forensicTimeline . map ( step => `<li>${ step } </li>` ) . join ( '' ) } </ul>` ;
1883+
1884+ // Scores
1885+ const scoresDiv = document . getElementById ( 'debuggerScores' ) ;
1886+ scoresDiv . innerHTML = `<h4>📊 Convergence</h4><p>FSVE EV: ${ data . fsve_ev . toFixed ( 2 ) } | TOPOS SGS: ${ data . topos_sgs . toFixed ( 2 ) } | Rounds: ${ data . rounds } | Converged: ${ data . converged ? '✅' : '🔄' } </p>` ;
1887+
1888+ document . getElementById ( 'debuggerResults' ) . style . display = 'block' ;
1889+ showToast ( 'Analysis complete' ) ;
1890+ } catch ( err ) {
1891+ showToast ( `Error: ${ err . message } ` , true ) ;
1892+ } finally {
1893+ setStatus ( 'Ready' ) ;
1894+ }
1895+ }
1896+
1897+ function copyRefinedCode ( ) {
1898+ if ( currentDebuggerResult && currentDebuggerResult . refinedCode ) {
1899+ navigator . clipboard . writeText ( currentDebuggerResult . refinedCode ) ;
1900+ showToast ( 'Code copied to clipboard' ) ;
1901+ }
1902+ }
1903+
1904+ function showDebuggerModal ( ) {
1905+ document . getElementById ( 'debuggerCode' ) . value = '' ;
1906+ document . getElementById ( 'debuggerResults' ) . style . display = 'none' ;
1907+ currentDebuggerResult = null ;
1908+ const modal = document . getElementById ( 'debuggerModal' ) ;
1909+ modal . style . display = 'flex' ;
1910+ document . getElementById ( 'closeDebuggerModal' ) . onclick = ( ) => { modal . style . display = 'none' ; } ;
1911+ modal . addEventListener ( 'click' , ( e ) => { if ( e . target === modal ) modal . style . display = 'none' ; } ) ;
1912+ document . getElementById ( 'debuggerAnalyzeBtn' ) . onclick = runDebugger ;
1913+ document . getElementById ( 'debuggerCopyBtn' ) . onclick = copyRefinedCode ;
1914+ }
1915+
17821916 // Main send message
17831917 async function sendMessage ( retryMessage = null ) {
17841918 if ( isSending ) { showToast ( 'Already sending...' ) ; return ; }
@@ -1840,6 +1974,7 @@ <h4>📋 Synthesis (Score: ${Math.round(result.synthesis.score * 100)}%)</h4>
18401974 } ) ;
18411975 aionHistory . push ( { role : 'user' , content : text } ) ;
18421976 aionHistory . push ( { role : 'assistant' , content : result . response } ) ;
1977+ trimHistory ( aionHistory ) ;
18431978 setStatus ( 'Ready' ) ;
18441979 } else {
18451980 // Group mode
@@ -1854,6 +1989,7 @@ <h4>📋 Synthesis (Score: ${Math.round(result.synthesis.score * 100)}%)</h4>
18541989 // Update group history
18551990 groupHistory . push ( { role : 'user' , content : text } ) ;
18561991 groupHistory . push ( { role : 'assistant' , content : result . consensus . final_text } ) ;
1992+ trimHistory ( groupHistory ) ;
18571993 // Render group message
18581994 renderGroupMessage ( result . consensus . final_text , result . responses , result . meta , timestampHtml ) ;
18591995 setStatus ( 'Ready' ) ;
@@ -1882,6 +2018,7 @@ <h4>📋 Synthesis (Score: ${Math.round(result.synthesis.score * 100)}%)</h4>
18822018 document . getElementById ( 'sealInputBtn' ) . onclick = ( ) => { actionDropdown . style . display = 'none' ; const text = input . value . trim ( ) ; if ( text ) sealMessage ( text ) ; else showToast ( 'Nothing to seal' ) ; } ;
18832019 document . getElementById ( 'simulationBtn' ) . onclick = ( ) => { actionDropdown . style . display = 'none' ; showSimulationModal ( ) ; } ;
18842020 document . getElementById ( 'mumonBtn' ) . onclick = ( ) => { actionDropdown . style . display = 'none' ; showMumonModal ( ) ; } ;
2021+ document . getElementById ( 'debuggerBtn' ) . onclick = ( ) => { actionDropdown . style . display = 'none' ; showDebuggerModal ( ) ; } ;
18852022 document . getElementById ( 'settingsBtn' ) . onclick = showSettingsModal ;
18862023 document . getElementById ( 'adaLoopToggle' ) . addEventListener ( 'change' , ( e ) => {
18872024 adaLoopEnabled = e . target . checked ;
0 commit comments