Files
Loki/internal/jean/sys_paths.go
T
nathaninline 1f3961eaa9 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.
2026-08-04 11:17:43 +02:00

80 lines
2.6 KiB
Go

package jean
import (
"fmt"
"net/http"
"os"
"path/filepath"
"runtime"
)
// « Où sont mes fichiers ? » — la question que personne ne devrait avoir à poser.
// Un binaire unique qui s'auto-installe au premier lancement rend les
// emplacements invisibles : on ne sait plus si le .exe qu'on a double-cliqué EST
// l'application ou seulement un installateur, ni où atterrissent la config, les
// modèles et les fichiers que l'agent écrit. On centralise donc la réponse ici,
// et on l'expose à la fois en ligne de commande (`jean where`) et dans l'UI.
type jeanPaths struct {
Home string `json:"home"` // JEAN_HOME : racine des données
Config string `json:"config"` // config.env
Exe string `json:"exe"` // binaire en cours d'exécution
Installed string `json:"installed"` // binaire installé (peut différer de Exe)
Workspace string `json:"workspace"` // dossier de travail du mode agent
Memory string `json:"memory"`
Presets string `json:"presets"`
}
// installedExePath est l'emplacement canonique du binaire après installation.
// Il diffère par plateforme : sous Unix les installateurs posent /usr/local/bin/jean
// (c'est ce que référencent les unités systemd et le plist launchd) ; sous Windows,
// faute d'équivalent, on utilise JEAN_HOME\bin ajouté au PATH utilisateur.
func installedExePath() string {
if runtime.GOOS == "windows" {
return filepath.Join(JeanHome(), "bin", "jean.exe")
}
return "/usr/local/bin/jean"
}
func currentPaths() jeanPaths {
exe, _ := os.Executable()
if resolved, err := filepath.EvalSymlinks(exe); err == nil {
exe = resolved
}
return jeanPaths{
Home: JeanHome(),
Config: confPath(),
Exe: exe,
Installed: installedExePath(),
Workspace: agentWorkspace(),
Memory: memoryDir(),
Presets: presetsDir(),
}
}
func cmdWhere(args []string) error {
p := currentPaths()
fmt.Printf("Emplacements AJEAN\n\n")
for _, row := range [][2]string{
{"données (JEAN_HOME)", p.Home},
{"configuration", p.Config},
{"binaire en cours", p.Exe},
{"binaire installé", p.Installed},
{"travail de l'agent", p.Workspace},
{"mémoire", p.Memory},
{"presets", p.Presets},
} {
fmt.Printf(" %-20s %s\n", row[0], row[1])
}
if p.Exe != p.Installed {
fmt.Printf("\n%s tu exécutes une copie qui n'est PAS le binaire installé.\n", dim("[info]"))
fmt.Printf(" Les mises à jour depuis l'application ne modifient que la copie lancée.\n")
}
return nil
}
// handlePaths (GET /api/paths) alimente le bloc « Emplacements » de l'UI.
func handlePaths(w http.ResponseWriter, r *http.Request) {
sendJSON(w, 200, currentPaths())
}