mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 06:28:11 +02:00
Rebaptise AJEAN en Loki (fork, lignée conservée)
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki) - LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ; units loki-engine / loki-ui ; binaire et aide CLI - updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les binaires AJEAN amont) Conservé à l'identique : le domaine ajean.link (service de tunnel amont), les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et LICENSE (historique et licence de l'amont). go build/vet/test : verts.
This commit is contained in:
157 files changed
+928
-928
No files matched your search
@@ -0,0 +1,87 @@
|
||||
package loki
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Dossier de travail du mode agent.
|
||||
//
|
||||
// Sans ça, les outils write/edit/bash héritent du répertoire courant du PROCESSUS :
|
||||
// le modèle écrit "meteo.json", et le fichier atterrit là d'où l'utilisateur a
|
||||
// lancé loki — le Bureau quand on double-clique l'installateur, C:\ProgramData\loki\bin
|
||||
// quand on lance le binaire installé. Personne ne s'attend à voir un chat déposer
|
||||
// des fichiers sur son Bureau. On donne donc à l'agent un dossier à lui : les
|
||||
// chemins relatifs y sont résolus, et le shell y démarre. Les chemins ABSOLUS
|
||||
// restent honorés tels quels — quand l'utilisateur demande d'écrire dans un
|
||||
// dossier précis, ça doit marcher.
|
||||
|
||||
const workspaceEnv = "LOKI_WORKSPACE"
|
||||
|
||||
var (
|
||||
workspaceOnce sync.Once
|
||||
workspacePath string
|
||||
)
|
||||
|
||||
// agentWorkspace renvoie le dossier de travail de l'agent, créé au besoin. Il
|
||||
// essaie plusieurs emplacements car LokiHome() vaut %ProgramData%\loki sous
|
||||
// Windows, qui n'est pas inscriptible par un utilisateur non administrateur.
|
||||
func agentWorkspace() string {
|
||||
workspaceOnce.Do(func() {
|
||||
for _, dir := range workspaceCandidates() {
|
||||
if dir == "" {
|
||||
continue
|
||||
}
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
continue
|
||||
}
|
||||
// MkdirAll réussit sur un dossier existant même non inscriptible :
|
||||
// on vérifie l'écriture réelle.
|
||||
f, err := os.CreateTemp(dir, ".probe-*")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
name := f.Name()
|
||||
f.Close()
|
||||
os.Remove(name)
|
||||
workspacePath = dir
|
||||
return
|
||||
}
|
||||
// Dernier recours : le répertoire courant, comportement historique.
|
||||
workspacePath, _ = os.Getwd()
|
||||
})
|
||||
return workspacePath
|
||||
}
|
||||
|
||||
func workspaceCandidates() []string {
|
||||
var c []string
|
||||
if v := strings.TrimSpace(os.Getenv(workspaceEnv)); v != "" {
|
||||
c = append(c, v)
|
||||
}
|
||||
c = append(c, workspaceDir())
|
||||
if home, err := os.UserHomeDir(); err == nil && home != "" {
|
||||
c = append(c, filepath.Join(home, "loki", "workspace"))
|
||||
}
|
||||
c = append(c, filepath.Join(os.TempDir(), "loki-workspace"))
|
||||
return c
|
||||
}
|
||||
|
||||
// resolveAgentPath résout un chemin fourni par le modèle. Absolu → inchangé ;
|
||||
// "~/x" → dans le home de l'utilisateur ; relatif → dans le workspace.
|
||||
func resolveAgentPath(p string) string {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
return p
|
||||
}
|
||||
if p == "~" || strings.HasPrefix(p, "~/") || strings.HasPrefix(p, `~\`) {
|
||||
if home, err := os.UserHomeDir(); err == nil && home != "" {
|
||||
return filepath.Join(home, filepath.FromSlash(strings.TrimPrefix(p[1:], "/")))
|
||||
}
|
||||
}
|
||||
if filepath.IsAbs(p) {
|
||||
return p
|
||||
}
|
||||
return filepath.Join(agentWorkspace(), filepath.FromSlash(p))
|
||||
}
|
||||
Reference in new issue
Block a user