mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-17 20:26:35 +02:00
Socle du renommage jean -> AJEAN, sans aucun impact visible pour le parc installe. Trois briques : - module github.com/nathaninline/ajean, cmd/ajean, internal/ajean, package ajean. Purement interne. - AjeanHome() remplace JeanHome(). Les defauts deviennent %ProgramData%\ajean et /etc/ajean, avec migration du dossier existant au premier lancement. La migration est un os.Rename dans le dossier parent de l'ancien chemin : intra-volume, donc atomique et instantane meme avec des .gguf de plusieurs dizaines de Go. Si le rename echoue (handle ouvert sous Windows, droits, volume en lecture seule) on CONTINUE sur l'ancien chemin et on retentera : jamais de copie, jamais de suppression, le pire cas est "rien n'a bouge". $AJEAN_HOME et $JEAN_HOME restent tous deux honores, ainsi que /etc/default/ajean et /etc/default/jean : un chemin impose a la main est un ordre, on ne le migre pas. - l'auto-MAJ accepte desormais ajean-<os>-<arch> ET jean-<os>-<arch>, dans cet ordre. Indispensable dans les deux sens : les binaires deja installes ne connaissent que jean-*, et ce binaire-ci doit pouvoir s'installer depuis une release anterieure au renommage. Couvert par des tests, dont le repli quand un handle ouvert bloque le rename sous Windows.
80 lines
2.6 KiB
Go
80 lines
2.6 KiB
Go
package ajean
|
|
|
|
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 ajeanPaths 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(AjeanHome(), "bin", "jean.exe")
|
|
}
|
|
return "/usr/local/bin/jean"
|
|
}
|
|
|
|
func currentPaths() ajeanPaths {
|
|
exe, _ := os.Executable()
|
|
if resolved, err := filepath.EvalSymlinks(exe); err == nil {
|
|
exe = resolved
|
|
}
|
|
return ajeanPaths{
|
|
Home: AjeanHome(),
|
|
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())
|
|
}
|