v0.6.10 : dossier de travail pour l'agent, lancement Windows explicite, mise à jour lisible, icône noire

- mode agent : les outils write/edit/bash résolvent les chemins relatifs dans
  JEAN_HOME/workspace et le shell y démarre, au lieu du répertoire courant du
  processus (Bureau, ProgramData\jean\bin). Les chemins absolus demandés
  explicitement restent honorés.
- Windows : le double-clic n'installe plus en silence. Boîte de dialogue unique,
  raccourcis menu Démarrer + Bureau, puis relance depuis la copie installée — un
  seul binaire fait foi. Désinstallation : retrait des raccourcis.
- update : contrôle des droits AVANT le téléchargement (l'échec tombait sur le
  fichier temporaire, avec un message brut), message donnant la commande exacte,
  timeout UI porté de 30 s à 10 min.
- jean where + bouton « Où sont mes fichiers ? » : emplacements, et alerte quand
  le binaire lancé n'est pas celui installé.
- icônes : source unique (sys_brand_icon.go) pour la zone de notification, la
  barre de menus macOS et l'icône du .exe, alignée sur le favicon noir. macOS en
  icône template (une icône noire figée disparaît sur une barre sombre).
- CI : le bundle macOS part de icon.png au lieu de convertir le .ico via sips,
  dont l'échec était masqué par « || true » ; notes de release versionnées.
This commit is contained in:
nathaninline committed 2026-08-04 11:17:43 +02:00
1 parent 6e7fe7d4a6
commit 1f3961eaa9
28 files changed
+742 -130

No files matched your search

+2
View File
@@ -231,6 +231,8 @@
<div class="slist pad">
<div class="row"><button id="upd-check" onclick="checkUpdate()">↥ Vérifier les mises à jour</button></div>
<div id="upd-msg" class="muted"></div>
<div class="row"><button onclick="showPaths()">📁 Où sont mes fichiers ?</button></div>
<div id="paths-msg" class="muted"></div>
<div class="row">
<button onclick="loadAll()">↻ refresh</button>
<button onclick="resetChat()">⌫ clear chat</button>
+21 -1
View File
@@ -61,11 +61,31 @@ async function checkUpdate(){
}catch(e){ msg.textContent='Erreur réseau'; }
b.disabled=false;
}
// Emplacements : la question « où sont mes fichiers / est-ce que ça a été
// installé ? » revient assez souvent pour mériter une réponse dans l'UI.
async function showPaths(){
const el=document.getElementById('paths-msg');
el.textContent='…';
try{
const p=await jget('/api/paths');
const rows=[['Données',p.home],['Configuration',p.config],['Fichiers créés par l\'agent',p.workspace],['Mémoire',p.memory],['Programme en cours',p.exe]];
el.innerHTML=rows.map(r=>'<div><b>'+r[0]+'</b><br><code>'+escHtml(r[1]||'')+'</code></div>').join('');
if(p.exe && p.installed && p.exe!==p.installed){
el.innerHTML+='<div style="color:var(--warn);margin-top:8px">Vous exécutez une copie du programme, pas celle installée (<code>'+escHtml(p.installed)+'</code>). La mise à jour ne modifiera que la copie lancée.</div>';
}
}catch(e){ el.textContent='Erreur'; }
}
async function applyUpdate(){
const msg=document.getElementById('upd-msg');
msg.textContent='Téléchargement et installation…';
try{
const r=await jpost('/api/update/apply',{});
// Signal dédié : le timeout par défaut (30 s) coupe le téléchargement du
// binaire sur une connexion lente et fait croire à un échec alors que la
// mise à jour aboutit côté serveur.
const ac=new AbortController(); const t=setTimeout(()=>ac.abort(), 10*60*1000);
let r;
try{ r=await (await jfetch('/api/update/apply',{method:'POST',headers:{'Content-Type':'application/json'},body:'{}',signal:ac.signal})).json(); }
finally{ clearTimeout(t); }
if(r.ok){
msg.innerHTML='✓ Installé en <b>v'+r.version+'</b>.<br>'+(r.restart||'');
// Redémarrage auto du service côté serveur : le flux va se couper puis