mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Repris de shell.ts / shell-tail.ts et diagnostics.ts d'OpenFox (2.0.160). - « cmd | tail -N » : le code de sortie devenait celui de tail (0) et un build en échec passait pour réussi. Le tail est retiré de la commande et Loki garde lui-même les N dernières lignes : même sortie, vrai code. - Délai dépassé : la sortie déjà produite est rendue (où en était le build, quel test bloquait) au lieu d'un « [timeout] » sec, avec le conseil de passer par bash_bg pour un serveur. - Couleurs et séquences ANSI retirées : du bruit en tokens. - La durée suit le code de sortie (« exit: 0 · 1.2s »). - Mode Code : « cmd & » refusé, avec renvoi vers bash_bg — le process orphelin n'avait ni sortie lisible ni moyen d'être arrêté. - Diagnostics LSP : erreurs d'abord, avec le compte total ; au-delà de la limite, des indices de style passaient devant l'erreur de compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
1.9 KiB
Go
61 lines
1.9 KiB
Go
package loki
|
|
|
|
// chat_shell_hygiene.go — ce que le terminal rend au modèle, nettoyé (repris de
|
|
// shell.ts / shell-tail.ts d'OpenFox, 2.0.160) :
|
|
//
|
|
// - « cmd | tail -N » : le code de sortie devenait celui de tail (0), et un
|
|
// build en échec passait pour réussi. On retire le tail de la commande et
|
|
// on garde nous-mêmes les N dernières lignes : même sortie, vrai code.
|
|
// - séquences ANSI (couleurs, curseur) : du bruit en tokens, illisible ;
|
|
// - « cmd & » en mode Code : le process orphelin n'a ni sortie ni arrêt —
|
|
// bash_bg est fait pour ça.
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// tailPipeRe : « | tail », « | tail -20 », « | tail -n 20 », « | tail -n20 » en
|
|
// toute fin de commande.
|
|
var tailPipeRe = regexp.MustCompile(`\s*\|\s*tail(?:\s+-n\s*(\d+)|\s+-(\d+))?\s*$`)
|
|
|
|
// splitTailPipe retire un « | tail -N » final. Renvoie la commande sans lui et
|
|
// N (0 = pas de tail ; 10 = tail sans nombre, sa valeur par défaut).
|
|
func splitTailPipe(command string) (string, int) {
|
|
m := tailPipeRe.FindStringSubmatchIndex(command)
|
|
if m == nil {
|
|
return command, 0
|
|
}
|
|
n := 10
|
|
for _, g := range []int{2, 4} {
|
|
if m[g] >= 0 {
|
|
if v, err := strconv.Atoi(command[m[g]:m[g+1]]); err == nil && v > 0 {
|
|
n = v
|
|
}
|
|
}
|
|
}
|
|
rest := strings.TrimSpace(command[:m[0]])
|
|
if rest == "" {
|
|
return command, 0
|
|
}
|
|
return rest, n
|
|
}
|
|
|
|
// shellANSIRe : séquences CSI (couleurs, curseur) et OSC (titres de fenêtre).
|
|
var shellANSIRe = regexp.MustCompile(`\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)`)
|
|
|
|
func stripANSI(s string) string {
|
|
if !strings.Contains(s, "\x1b") {
|
|
return s
|
|
}
|
|
return shellANSIRe.ReplaceAllString(s, "")
|
|
}
|
|
|
|
// trailingBackground : la commande se termine par un « & » de mise en
|
|
// arrière-plan (pas « && »).
|
|
func trailingBackground(command string) bool {
|
|
c := strings.TrimSpace(command)
|
|
return strings.HasSuffix(c, "&") && !strings.HasSuffix(c, "&&")
|
|
}
|