diff --git a/ui/index.html b/ui/index.html
index 03ca6a6..0265d0a 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -44,6 +44,12 @@ h1{margin:0;font-size:18px;color:var(--accent)}
.skillshead>span{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;font-weight:600}
.addbtn{font-size:11px;padding:3px 11px 4px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;cursor:pointer;line-height:1.2}
.addbtn:hover{border-color:var(--accent);color:var(--accent)}
+.mem-count{font-size:10px;color:var(--dim);font-weight:400;letter-spacing:0;text-transform:none;margin-left:4px}
+.mem-search{width:100%;box-sizing:border-box;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:5px 9px;font:inherit;font-size:12px;margin:0 0 6px}
+.mem-search:focus{outline:none;border-color:var(--accent)}
+.mem-list{max-height:240px;overflow-y:auto;overscroll-behavior:contain}
+.mem-list .preset{margin:3px 0;padding:5px 9px}
+.mem-more{font-size:11px;color:var(--dim);text-align:center;padding:6px 0 2px}
#brand-a{display:inline-block;line-height:1;max-width:0;opacity:0;overflow:hidden;color:#fff;transition:max-width .35s ease,opacity .35s ease}
#brand.agent #brand-a{max-width:1ch;opacity:1;margin-right:.04em}
/* interrupteur (switch) */
@@ -188,8 +194,9 @@ button:disabled{opacity:.5;cursor:not-allowed}
⚠️ active l'accès machine (shell complet via bash sur le serveur) et la mémoire — l'IA peut inspecter, lancer des scripts et lire/écrire ses pages mémoire (timeout 30s, max 300s)
limiter les appels d'outils par tour
activé par défaut : coupe l'IA après ~8 appels d'outils (message [stop: trop d'appels d'outils]). Désactive-le si tu veux la laisser enchaîner sans plafond (l'anti-boucle reste actif).
- Mémoire + ajouter
-
+ Mémoire + ajouter
+
+
System prompt
@@ -420,10 +427,40 @@ async function loadAgent(){
document.getElementById('agent-badge').innerHTML = on
? 'on ' : 'off ';
document.getElementById('brand').classList.toggle('agent', on);
- const pages = s.pages || s.skills || [];
- document.getElementById('mem-list').innerHTML = pages.length
- ? pages.map(x=>''+x.name+' — '+x.desc+' edit
').join('')
- : '(aucune page mémoire)
';
+ memPages = (s.pages || s.skills || []).slice().sort((a,b)=>a.name.localeCompare(b.name));
+ memShown = MEM_PAGE;
+ document.getElementById('mem-count').textContent = memPages.length ? '('+memPages.length+')' : '';
+ document.getElementById('mem-search').style.display = memPages.length > MEM_PAGE ? '' : 'none';
+ renderMemList();
+}
+// Liste mémoire scalable : recherche + rendu plafonné (les milliers de pages ne
+// déroulent plus une barre géante). memShown grimpe par paliers via « voir plus ».
+let memPages=[], memShown=0; const MEM_PAGE=50;
+function renderMemList(){
+ const q=(document.getElementById('mem-search').value||'').trim().toLowerCase();
+ const list=document.getElementById('mem-list');
+ list.textContent='';
+ if(!memPages.length){ list.innerHTML='(aucune page mémoire)
'; return; }
+ const matches = q ? memPages.filter(x=>(x.name+' '+(x.desc||'')).toLowerCase().includes(q)) : memPages;
+ if(!matches.length){ list.innerHTML='(aucun résultat pour « '+q.replace(/[<>&]/g,'')+' »)
'; return; }
+ const shown = matches.slice(0, memShown);
+ shown.forEach(x=>{
+ const row=document.createElement('div'); row.className='preset'; row.style.fontSize='12px';
+ row.onclick=()=>openMem(x.name);
+ const span=document.createElement('span');
+ const b=document.createElement('b'); b.style.color='var(--text)'; b.textContent=x.name; span.appendChild(b);
+ if(x.desc){ const d=document.createElement('span'); d.className='muted'; d.textContent=' — '+x.desc; span.appendChild(d); }
+ const btn=document.createElement('button'); btn.textContent='edit'; btn.style.cssText='margin:0;padding:2px 8px;font-size:11px';
+ btn.onclick=e=>{ e.stopPropagation(); openMem(x.name); };
+ row.appendChild(span); row.appendChild(btn); list.appendChild(row);
+ });
+ if(matches.length > shown.length){
+ const more=document.createElement('div'); more.className='mem-more';
+ more.textContent='+ voir plus ('+(matches.length-shown.length)+' de plus)';
+ more.style.cursor='pointer';
+ more.onclick=()=>{ memShown+=MEM_PAGE; renderMemList(); };
+ list.appendChild(more);
+ }
}
// alias : plusieurs appelants rafraîchissent juste la liste des pages mémoire
const loadMem = loadAgent;