mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-21 05:58:13 +02:00
Hauteur : bulles techniques en rangée, sections groupées, accès distant retiré
Trois gains de place, mesurés au navigateur en 1500×900. - Raisonnement, outils et mémoire se posent CÔTE À CÔTE dans une rangée qui déborde à la ligne : un tour d'agent en enchaîne parfois dix, et empilées elles repoussaient la réponse hors de l'écran alors qu'elles ne portent qu'une étiquette tant qu'elles sont repliées. Mesuré : 8 bulles occupent 2 lignes au lieu de 8. Dépliée, une bulle reprend toute la largeur — son contenu ne doit pas être comprimé dans une colonne étroite. - Les sections de la barre latérale sont réunies en DEUX cartes (réglages d'IA / réglages d'application) au lieu d'une carte chacune : onze arrondis et autant de gouttières faisaient déborder la colonne. Mesuré : 876 px de contenu pour 876 px visibles — plus d'ascenseur. - Section « Accès distant » supprimée, ainsi que son module JS (13-remote.js) et son chargement : elle pilotait le tunnel ajean.link, sans objet ici. Le code serveur du relais reste en place mais inerte (aucun jeton) : le retirer créerait des conflits à chaque reprise de l'amont.
This commit is contained in:
6 files changed
+112
-254
No files matched your search
@@ -491,7 +491,7 @@ async function loadAll(){
|
||||
// allSettled et pas all : un seul chargement en échec (accès distant coupé,
|
||||
// clé API absente…) ne doit pas empêcher la suite — et surtout pas laisser les
|
||||
// hauteurs réservées en place pour toujours.
|
||||
await Promise.allSettled([loadStatus(),loadVram(),loadRam(),loadCfg(),loadPresets(),loadConversations(),loadIdentity(),loadAgent(),loadInternet(),loadMCP(),loadNode(),loadApiKey(),loadNetwork(),loadPrefs(),loadLlamacpp(),loadRemote()]);
|
||||
await Promise.allSettled([loadStatus(),loadVram(),loadRam(),loadCfg(),loadPresets(),loadConversations(),loadIdentity(),loadAgent(),loadInternet(),loadMCP(),loadNode(),loadApiKey(),loadNetwork(),loadPrefs(),loadLlamacpp()]);
|
||||
releaseHeights(); // tout est en place : on rend la main et on mesure pour la prochaine fois
|
||||
}
|
||||
async function act(a){ toast(a+'…'); await jpost('/api/'+a); setTimeout(loadAll,1500); }
|
||||
@@ -56,7 +56,22 @@ function addMsg(role, text){
|
||||
}
|
||||
}
|
||||
el.querySelector('.body').textContent=text;
|
||||
chatEl().appendChild(el);
|
||||
// Bulles techniques (raisonnement, outils, mémoire) : elles se posent CÔTE À
|
||||
// CÔTE dans une rangée qui déborde à la ligne. Un tour d'agent en enchaîne
|
||||
// parfois dix ; empilées, elles repoussaient la réponse hors de l'écran alors
|
||||
// qu'elles ne portent qu'une étiquette tant qu'elles sont repliées. Dépliée,
|
||||
// une bulle reprend toute la largeur de la rangée (CSS .toolrow).
|
||||
if(collapsible){
|
||||
let row = chatEl().lastElementChild;
|
||||
if(!row || !row.classList.contains('toolrow')){
|
||||
row = document.createElement('div');
|
||||
row.className = 'toolrow';
|
||||
chatEl().appendChild(row);
|
||||
}
|
||||
row.appendChild(el);
|
||||
} else {
|
||||
chatEl().appendChild(el);
|
||||
}
|
||||
scrollMaybe();
|
||||
return el;
|
||||
}
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Accès distant (ajean.link) — piloté depuis l'UI, sans terminal.
|
||||
// « Connecter » ouvre une popup app.ajean.link/connect.html qui gère compte +
|
||||
// abonnement, puis renvoie une clé de liaison par postMessage. On la POSTe à
|
||||
// l'agent local (/api/link/connect) qui fait le `loki link` (token + service).
|
||||
|
||||
const LOKI_APP_ORIGIN = 'https://app.ajean.link';
|
||||
|
||||
function renderRemote(d){
|
||||
const off = document.getElementById('remote-off'), on = document.getElementById('remote-on');
|
||||
const badge = document.getElementById('remote-badge');
|
||||
if(!d || !d.linked){
|
||||
// Serveur jamais lié : on l'affiche explicitement plutôt que de laisser la
|
||||
// pastille vide, qui se lisait comme « je ne sais pas ».
|
||||
off.style.display=''; on.style.display='none';
|
||||
setBadge(badge, false, 'non connecté');
|
||||
return;
|
||||
}
|
||||
off.style.display='none'; on.style.display='';
|
||||
document.getElementById('remote-url').value = d.machineURL || '';
|
||||
const st = document.getElementById('remote-status');
|
||||
if(d.active){ st.textContent='● en ligne — accessible à distance'; st.style.color='var(--accent)'; }
|
||||
else { st.textContent='○ tunnel arrêté (l\'accès distant ne répondra pas)'; st.style.color='var(--warn)'; }
|
||||
const sb = document.getElementById('remote-start');
|
||||
if(sb){ sb.style.display = d.active ? 'none' : ''; }
|
||||
setBadge(badge, d.active ? true : 'warn', d.active ? 'connecté' : 'arrêté');
|
||||
}
|
||||
|
||||
async function loadRemote(){
|
||||
// Le panneau ne vaut qu'en LOCAL : il pilote /api/link/* que le tunnel bloque
|
||||
// (boîte noire). Sur le portail distant (app.ajean.link/server.html), on le cache.
|
||||
const det = document.getElementById('remote-details');
|
||||
if(location.hostname === 'app.ajean.link'){ if(det) det.style.display='none'; return; }
|
||||
// Statut injoignable : on retombe sur « non connecté » plutôt que de garder
|
||||
// l'affichage précédent, qui pourrait annoncer « connecté » à tort.
|
||||
try{ renderRemote(await jget('/api/link/status')); }catch(e){ renderRemote(null); }
|
||||
}
|
||||
|
||||
// Ouvre la popup de connexion et attend la clé renvoyée par postMessage.
|
||||
function remoteConnect(){
|
||||
const params = new URLSearchParams({ origin: window.location.origin, host: window.location.hostname || 'ce serveur' });
|
||||
const url = LOKI_APP_ORIGIN + '/connect.html?' + params.toString();
|
||||
const pop = window.open(url, 'loki-connect', 'width=440,height=640');
|
||||
if(!pop){ toast('autorisez les popups pour connecter ajean.link'); return; }
|
||||
|
||||
async function onMsg(ev){
|
||||
// Anti-usurpation : n'accepte QUE des messages du portail ajean.link.
|
||||
if(ev.origin !== LOKI_APP_ORIGIN) return;
|
||||
const d = ev.data || {};
|
||||
if(d.type !== 'loki-link' || !d.token) return;
|
||||
window.removeEventListener('message', onMsg);
|
||||
try{
|
||||
const r = await jpost('/api/link/connect', { token: d.token });
|
||||
if(r && r.linked){
|
||||
toast('✓ accès distant connecté');
|
||||
if(r.serviceErr){ toast('token enregistré (service : '+r.serviceErr+')'); }
|
||||
loadRemote();
|
||||
} else {
|
||||
toast((r && r.error) || 'échec de la connexion');
|
||||
}
|
||||
}catch(e){ toast('erreur : '+e); }
|
||||
}
|
||||
window.addEventListener('message', onMsg);
|
||||
}
|
||||
|
||||
// Relance le tunnel avec la clé déjà enregistrée (sans repasser par la popup).
|
||||
async function remoteStart(){
|
||||
const b = document.getElementById('remote-start');
|
||||
if(b){ b.disabled = true; b.textContent = 'démarrage…'; }
|
||||
try{
|
||||
const r = await jpost('/api/link/start', {});
|
||||
if(r && r.active){ toast('✓ tunnel démarré'); }
|
||||
else { toast((r && r.error) || 'le tunnel n\'a pas démarré'); }
|
||||
}catch(e){ toast('erreur : '+e); }
|
||||
if(b){ b.disabled = false; b.textContent = 'démarrer le tunnel'; }
|
||||
loadRemote();
|
||||
}
|
||||
|
||||
async function remoteDisconnect(){
|
||||
const ok = await askConfirm('Couper l\'accès distant et oublier la clé de liaison de ce serveur ?', {title:'Accès distant', okLabel:'Déconnecter'});
|
||||
if(!ok) return;
|
||||
try{ await jpost('/api/link/disconnect', {}); toast('accès distant coupé'); loadRemote(); }
|
||||
catch(e){ toast('erreur : '+e); }
|
||||
}
|
||||
|
||||
async function remotePairCode(){
|
||||
const box = document.getElementById('remote-pair');
|
||||
box.style.display=''; box.textContent='génération du code…';
|
||||
try{
|
||||
const r = await jpost('/api/link/paircode', {});
|
||||
if(r && r.code){
|
||||
box.innerHTML = 'Empreinte : <b>'+(r.fingerprint||'—')+'</b><br>Code d\'appairage (valable 10 min, usage unique) : <b>'+r.code+'</b>';
|
||||
} else {
|
||||
box.textContent = (r && r.error) || 'code indisponible';
|
||||
}
|
||||
}catch(e){ box.textContent='erreur : '+e; }
|
||||
}
|
||||
Reference in new issue
Block a user