@ -7,7 +7,7 @@
@@ -7,7 +7,7 @@
connected : false ,
loopsLeft : 0 , loopsMax : 0 ,
dailyCount : 0 , dailyMax : 0 ,
resetCbs : [ ] , stopCbs : [ ] , saveCbs : [ ] , startCbs : [ ] , dotMode : null , transport : 'dom' , accLimit : 900000 , lastMetrics : null , forceInject : false , mcpTimer : null
resetCbs : [ ] , stopCbs : [ ] , saveCbs : [ ] , startCbs : [ ] , dotMode : null , transport : 'dom' , accLimit : 900000 , lastMetrics : null , forceInject : false , mcpTimer : null , togglePending : false
} ;
var el = { } ;
function byId ( id ) { return document . getElementById ( id ) ; }
@ -27,14 +27,13 @@
@@ -27,14 +27,13 @@
var title = mk ( 'span' , 'dshmem-title' , 'DSH Memory' ) ;
el . phase = mk ( 'span' , 'dshmem-phase' , 'Off' ) ;
el . phase . id = 'dshmem-phase' ;
el . toggl e = mk ( 'span' , 'dshmem-toggle' , '-' ) ;
head . appendChild ( el . dot ) ; head . appendChild ( title ) ; head . appendChild ( el . phase ) ; head . appendChild ( el . toggl e) ;
el . collaps e = mk ( 'span' , 'dshmem-toggle' , '-' ) ;
head . appendChild ( el . dot ) ; head . appendChild ( title ) ; head . appendChild ( el . phase ) ; head . appendChild ( el . collaps e) ;
el . body = mk ( 'div' , 'dshmem-body' ) ;
root . appendChild ( head ) ; root . appendChild ( el . body ) ;
var row1 = mk ( 'div' , 'dshmem-row' ) ;
el . start = mk ( 'button' , 'dshmem-btn primary' , 'Start' ) ; el . restart = mk ( 'button' , 'dshmem-btn' , 'Restart' ) ;
el . stop = mk ( 'button' , 'dshmem-btn danger' , 'Stop' ) ;
row1 . appendChild ( el . start ) ; row1 . appendChild ( el . stop ) ; row1 . appendChild ( el . restart ) ;
el . toggle = mk ( 'button' , 'dshmem-btn primary' , 'Start' ) ; el . restart = mk ( 'button' , 'dshmem-btn' , 'Restart' ) ;
row1 . appendChild ( el . toggle ) ; row1 . appendChild ( el . restart ) ;
el . body . appendChild ( row1 ) ; el . stats = mk ( 'div' , 'dshmem-stats' ) ; el . stats . id = 'dshmem-stats' ; el . body . appendChild ( el . stats ) ; el . metrics = mk ( 'div' , 'dshmem-stats' ) ; el . metrics . id = 'dshmem-metrics' ; el . metrics . textContent = 'metrics: —' ; el . body . appendChild ( el . metrics ) ;
var setBox = mk ( 'div' , 'dshmem-fold-box' ) ;
el . settingsHead = mk ( 'div' , 'dshmem-fold-head' ) ;
@ -88,15 +87,25 @@
@@ -88,15 +87,25 @@
document . body . appendChild ( root ) ;
}
function wire ( ) {
el . toggl e. addEventListener ( 'click' , function ( ) {
el . collaps e. addEventListener ( 'click' , function ( ) {
el . body . style . display = el . body . style . display === 'none' ? '' : 'none' ;
} ) ;
el . settingsHead . addEventListener ( 'click' , function ( ) {
var open = el . settingsBox . classList . toggle ( 'open' ) ;
el . settingsArrow . textContent = open ? '\u25BC' : '\u25B6' ;
} ) ; el . transportToggle . addEventListener ( 'click' , function ( ) { state . transport = state . transport === 'dom' ? 'sse' : 'dom' ; el . transportToggle . textContent = state . transport === 'dom' ? 'DOM' : 'SSE' ; try { chrome . storage . local . set ( { 'dshmem-transport' : state . transport } ) } catch ( e ) { } } ) ;
el . stop . addEventListener ( 'click' , function ( ) { el . start . disabled = false ; state . stopCbs . forEach ( function ( cb ) { try { cb ( ) ; } catch ( e ) { } } ) ; } ) ;
el . restart . addEventListener ( 'click' , function ( ) { API . restartBridge ( ) ; } ) ; el . start . addEventListener ( 'click' , function ( ) { el . start . disabled = true ; state . startCbs . forEach ( function ( cb ) { try { cb ( ) ; } catch ( e ) { } } ) ; } ) ;
el . toggle . addEventListener ( 'click' , function ( ) {
if ( state . togglePending ) return ;
state . togglePending = true ;
setTimeout ( function ( ) { state . togglePending = false ; } , 400 ) ;
var running = ( state . phase && state . phase !== 'off' ) ;
if ( running ) {
state . stopCbs . forEach ( function ( cb ) { try { cb ( ) ; } catch ( e ) { } } ) ;
} else {
state . startCbs . forEach ( function ( cb ) { try { cb ( ) ; } catch ( e ) { } } ) ;
}
} ) ;
el . restart . addEventListener ( 'click' , function ( ) { API . restartBridge ( ) ; } ) ;
el . accLimit . addEventListener ( 'change' , function ( ) { var n = parseInt ( el . accLimit . value , 10 ) ; if ( ! n || n < 1000 ) n = 900000 ; state . accLimit = n ; try { chrome . storage . local . set ( { 'dshmem-acc-limit' : n } ) } catch ( e ) { } API . setMetrics ( state . lastMetrics ) ; } ) ; el . save . addEventListener ( 'click' , function ( ) { var v = el . token . value || '' ; if ( ! v ) { API . log ( 'token not changed (empty)' ) ; return ; } state . saveCbs . forEach ( function ( cb ) { try { cb ( v ) ; } catch ( e ) { } } ) ; } ) ;
el . stg . addEventListener ( 'click' , function ( ) { API . toggleForceInject ( ) ; } ) ;
el . health . addEventListener ( 'click' , function ( ) {
@ -119,9 +128,17 @@
@@ -119,9 +128,17 @@
el . mcpRescan . addEventListener ( 'click' , function ( ) { API . mcpRescan ( ) ; } ) ;
}
var API = {
setPhase : function ( p ) { state . phase = p ; if ( el . phase ) el . phase . textContent = p ; } ,
setPhase : function ( p ) {
state . phase = p ;
if ( el . phase ) el . phase . textContent = p ;
if ( el . toggle ) {
var running = ( p && p !== 'off' ) ;
el . toggle . textContent = running ? 'Stop' : 'Start' ;
el . toggle . className = 'dshmem-btn ' + ( running ? 'danger' : 'primary' ) ;
}
} ,
setConnected : function ( b ) { state . connected = ! ! b ; API . _applyDot ( ) ; } , setDot : function ( m ) { state . dotMode = m || null ; API . _applyDot ( ) ; } , _applyDot : function ( ) { if ( ! el . dot ) return ; var cls = 'dshmem-dot' ; if ( ! state . connected ) { cls += ' err' ; } else { var m = state . dotMode || 'off' ; if ( m === 'busy' || m === 'ok-busy' ) cls += ' busy' ; else if ( m === 'error' ) cls += ' error' ; else if ( m === 'stopped' ) cls += ' stopped' ; else if ( m === 'ok' ) cls += ' ok' ; else cls += ' off' ; } el . dot . className = cls ; } ,
setStartEnabled : function ( b ) { if ( el . start ) el . start . disabled = ! b ; } , setStats : function ( ws , memN , skillN ) { if ( ! el . stats ) return ; el . stats . textContent = 'WS: ' + ( ws || '?' ) + ' mem: ' + ( memN || 0 ) + ' skills: ' + ( skillN || 0 ) ; } , setMetrics : function ( m ) { if ( ! el . metrics ) return ; if ( ! m ) { el . metrics . textContent = 'metrics: —' ; return ; } state . lastMetrics = m ; var _ _pct = 0 ; if ( state . accLimit > 0 ) _ _pct = Math . round ( ( m . accum || 0 ) * 100 / state . accLimit ) ; var _ _cls = 'dshmem-acc-ok' ; if ( _ _pct > 100 ) _ _cls = 'dshmem-acc-crit' ; else if ( _ _pct >= 80 ) _ _cls = 'dshmem-acc-err' ; else if ( _ _pct >= 40 ) _ _cls = 'dshmem-acc-warn' ; el . metrics . className = 'dshmem-stats ' + _ _cls ; el . metrics . textContent = 'acc: ' + m . accum + ' · turn: ' + m . delta + ' · msg: ' + m . chars + 'ch (~' + m . est _tok + 't) ctx ' + ( m . ctx _tok || 0 ) + 't ' + ( m . ctx _pct || 0 ) + 'pct' ; } ,
setStartEnabled : function ( b ) { if ( el . toggle ) el . toggle . disabled = ! b ; } , setStats : function ( ws , memN , skillN ) { if ( ! el . stats ) return ; el . stats . textContent = 'WS: ' + ( ws || '?' ) + ' mem: ' + ( memN || 0 ) + ' skills: ' + ( skillN || 0 ) ; } , setMetrics : function ( m ) { if ( ! el . metrics ) return ; if ( ! m ) { el . metrics . textContent = 'metrics: —' ; return ; } state . lastMetrics = m ; var _ _pct = 0 ; if ( state . accLimit > 0 ) _ _pct = Math . round ( ( m . accum || 0 ) * 100 / state . accLimit ) ; var _ _cls = 'dshmem-acc-ok' ; if ( _ _pct > 100 ) _ _cls = 'dshmem-acc-crit' ; else if ( _ _pct >= 80 ) _ _cls = 'dshmem-acc-err' ; else if ( _ _pct >= 40 ) _ _cls = 'dshmem-acc-warn' ; el . metrics . className = 'dshmem-stats ' + _ _cls ; el . metrics . textContent = 'acc: ' + m . accum + ' · turn: ' + m . delta + ' · msg: ' + m . chars + 'ch (~' + m . est _tok + 't) ctx ' + ( m . ctx _tok || 0 ) + 't ' + ( m . ctx _pct || 0 ) + 'pct' ; } ,
toggleForceInject : function ( ) {
state . forceInject = ! state . forceInject ;
try { chrome . storage . local . set ( { 'dshmem-force-inject' : state . forceInject } ) } catch ( e ) { }