From dbd4a6a5708c9fecad378dfb1e6ab58a63c5a1de Mon Sep 17 00:00:00 2001 From: nathaninline Date: Tue, 28 Jul 2026 11:21:44 +0200 Subject: [PATCH] v0.5.11 : themes clair/sombre par famille + police reglable + affichage a la carte + cle API Crawl4AI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Apparence repensee : la liste ne montre plus que les FAMILLES de theme (Classique, AJEAN, Doux, ChatGPT) avec un interrupteur clair/sombre, au lieu d'une entree par variante. Nouveau theme « ChatGPT sombre » (fond quasi noir). - Le theme par defaut redevient « clair ». - Nouveau reglage « police », independant du theme : du theme / Mono / Systeme / Lexend / Serif (Lexend n'est telechargee que si elle est choisie). - Le mode « complet / simple » laisse place a quatre interrupteurs : masquer le raisonnement, masquer les appels d'outils, garder les bulles repliees, barre laterale escamotable (tiroir meme sur ordinateur). L'ancien reglage est repris. - Cle API du serveur Crawl4AI reglable depuis l'UI (et `jean internet key`) : envoyee en Authorization: Bearer sur toutes les requetes, jamais relue par l'API (indice sur 4 caracteres), preservee au changement de preset. - Mise en page : colonne de lecture bornee a 900 px en mode escamotable, marges d'origine sinon ; tiroir de meme largeur que la barre fixe ; bouton ☰ qui ne recouvre plus le fil ; logo et numero de version recales. --- cmd/jean/resource_windows_amd64.syso | Bin 8348 -> 8348 bytes cmd/jean/resource_windows_arm64.syso | Bin 8348 -> 8348 bytes cmd/jean/versioninfo.json | 6 +- internal/jean/backend_presets.go | 2 +- internal/jean/chat_internet.go | 15 ++ internal/jean/chat_internet_tools.go | 16 ++ internal/jean/run.go | 4 +- internal/jean/ui/index.html | 341 ++++++++++++++++++------- internal/jean/ui/src/index.tmpl.html | 28 +- internal/jean/ui/src/js/01-theme.js | 118 +++++++-- internal/jean/ui/src/js/02-prefs.js | 19 +- internal/jean/ui/src/js/06-settings.js | 22 ++ internal/jean/ui/src/js/09-stream.js | 4 +- internal/jean/ui/src/styles.css | 150 ++++++----- internal/jean/web_api.go | 24 +- internal/jean/web_prefs.go | 11 +- 16 files changed, 563 insertions(+), 197 deletions(-) diff --git a/cmd/jean/resource_windows_amd64.syso b/cmd/jean/resource_windows_amd64.syso index 3f0ba29718105ba81c42ed745b89c15649c05aa8..9bc470df1568178e5e81a0fc15f1e7f92ec6a189 100644 GIT binary patch delta 36 ocmbQ^ILC2=lnf^~11kdvaBo(Y5ocmF+-xlu&IqI?%X2aU0El4+2LJ#7 delta 36 ocmbQ^ILC2=lnf^q11kdvaBWtW5ocmF*laBq&IqI?%X2aU0Eiw30{{R3 diff --git a/cmd/jean/resource_windows_arm64.syso b/cmd/jean/resource_windows_arm64.syso index 05efd88f87e778de958625c877392fdf1f462068..3dbf881a20baec6ba155e5a95219eb7f898475ae 100644 GIT binary patch delta 36 ocmbQ^ILC2=lnf^~11kdvaBo(Y5ocmF+-xlu&IqI?%X2aU0El4+2LJ#7 delta 36 ocmbQ^ILC2=lnf^q11kdvaBWtW5ocmF*laBq&IqI?%X2aU0Eiw30{{R3 diff --git a/cmd/jean/versioninfo.json b/cmd/jean/versioninfo.json index a3cc7ed..1327e5a 100644 --- a/cmd/jean/versioninfo.json +++ b/cmd/jean/versioninfo.json @@ -3,13 +3,13 @@ "FileVersion": { "Major": 0, "Minor": 5, - "Patch": 10, + "Patch": 11, "Build": 0 }, "ProductVersion": { "Major": 0, "Minor": 5, - "Patch": 10, + "Patch": 11, "Build": 0 }, "FileFlagsMask": "3f", @@ -25,7 +25,7 @@ "LegalCopyright": "Copyright (c) 2026 AJEAN contributors. MIT License.", "OriginalFilename": "jean.exe", "ProductName": "AJEAN", - "ProductVersion": "0.5.10", + "ProductVersion": "0.5.11", "Comments": "https://github.com/nathaninline/jean — projet open source (MIT)" }, "VarFileInfo": { diff --git a/internal/jean/backend_presets.go b/internal/jean/backend_presets.go index 4a9794e..bc2fb60 100644 --- a/internal/jean/backend_presets.go +++ b/internal/jean/backend_presets.go @@ -201,7 +201,7 @@ func safePresetPath(name string) (string, error) { // paramètres de modèle) qui doivent survivre à un changement de preset. Sans ça, // écraser config.env avec le preset ré-imposerait le mode mémoire et effacerait // l'URL du serveur internet à chaque bascule — ce qui obligeait à tout remettre. -var preservedKeys = []string{"MEM_MODE", "CRAWL4AI_URL"} +var preservedKeys = []string{"MEM_MODE", "CRAWL4AI_URL", "CRAWL4AI_KEY"} // SwitchToPreset backs up the current config and copies the target into place, // then restarts the service. Les réglages « appareil » (preservedKeys) sont diff --git a/internal/jean/chat_internet.go b/internal/jean/chat_internet.go index 408ab20..0ddec2e 100644 --- a/internal/jean/chat_internet.go +++ b/internal/jean/chat_internet.go @@ -40,6 +40,19 @@ func crawl4aiURL() string { return strings.TrimRight(u, "/") } +// crawl4aiKey renvoie la clé d'accès au serveur Crawl4AI (config.env +// CRAWL4AI_KEY), vide si le serveur est ouvert. Envoyée en « Authorization: +// Bearer … », ce qu'attend Crawl4AI quand l'authentification est activée. +func crawl4aiKey() string { return strings.TrimSpace(ReadConfig()["CRAWL4AI_KEY"]) } + +// crawlAuth pose l'en-tête d'authentification sur une requête vers Crawl4AI. +// Sans clé configurée, la requête part telle quelle. +func crawlAuth(req *http.Request) { + if k := crawl4aiKey(); k != "" { + req.Header.Set("Authorization", "Bearer "+k) + } +} + // internetEnabled : accès internet actif = drapeau .internet_enabled présent ET // une URL Crawl4AI configurée. Même modèle que agentEnabled() (chat_agent.go). func internetEnabled() bool { @@ -96,6 +109,7 @@ func crawlReachable() bool { if err != nil { continue } + crawlAuth(req) resp, err := http.DefaultClient.Do(req) if err != nil { continue @@ -193,6 +207,7 @@ func runCrwl(target string, opts crwlOptions) (string, error) { return "", err } req.Header.Set("Content-Type", "application/json") + crawlAuth(req) resp, err := http.DefaultClient.Do(req) if err != nil { return "", fmt.Errorf("Crawl4AI injoignable (%s): %v", base, err) diff --git a/internal/jean/chat_internet_tools.go b/internal/jean/chat_internet_tools.go index 9a5e626..ec9af6e 100644 --- a/internal/jean/chat_internet_tools.go +++ b/internal/jean/chat_internet_tools.go @@ -284,6 +284,22 @@ func cmdInternet(args []string) error { reachURL = "" // invalide le cache de reachability reachMu.Unlock() fmt.Printf("%s serveur Crawl4AI : %s\n", green("[ok]"), bold(u)) + case "key": + if len(args) < 2 { + return fmt.Errorf("usage: jean internet key (vide pour l'enlever : jean internet key \"\")") + } + k := strings.TrimSpace(args[1]) + if err := SetConfigKey("CRAWL4AI_KEY", k); err != nil { + return err + } + reachMu.Lock() + reachURL = "" + reachMu.Unlock() + if k == "" { + fmt.Println(green("[ok]") + " clé Crawl4AI retirée") + } else { + fmt.Println(green("[ok]") + " clé Crawl4AI enregistrée") + } case "", "status", "list": state := dim("off") if internetEnabled() { diff --git a/internal/jean/run.go b/internal/jean/run.go index e431cdb..e363e20 100644 --- a/internal/jean/run.go +++ b/internal/jean/run.go @@ -10,7 +10,7 @@ import ( "strings" ) -const Version = "0.5.10" +const Version = "0.5.11" // Main est le vrai main() du binaire (cmd/jean ne fait que l'appeler). func Main() { @@ -130,7 +130,7 @@ Presets: Interaction: chat [system-prompt] chat terminal streamé web [PORT] UI web (défaut :8090) — chat + presets + mode agent - internet [on|off|status|url ] accès web de l'IA via un serveur Crawl4AI (web_search/open/read/grep) + internet [on|off|status|url |key ] accès web de l'IA via un serveur Crawl4AI (web_search/open/read/grep) memory [off|ondemand|always|status] mode mémoire de l'IA (off / sur demande / auto) Accès distant (ajean.link) : diff --git a/internal/jean/ui/index.html b/internal/jean/ui/index.html index 3005b0d..20073a8 100644 --- a/internal/jean/ui/index.html +++ b/internal/jean/ui/index.html @@ -15,7 +15,7 @@ - + @@ -79,6 +79,15 @@ + +
+ + + +
+
@@ -94,14 +103,19 @@
Apparence -
System prompt diff --git a/internal/jean/ui/src/js/01-theme.js b/internal/jean/ui/src/js/01-theme.js index ff4e616..1be7036 100644 --- a/internal/jean/ui/src/js/01-theme.js +++ b/internal/jean/ui/src/js/01-theme.js @@ -2,9 +2,28 @@ // Registre des thèmes disponibles. Pour en AJOUTER un : ajouter un bloc // [data-theme="…"] dans le