From acb08d3c6a83463050bceed93579d8b099e09e9b Mon Sep 17 00:00:00 2001 From: nathaninline Date: Fri, 10 Jul 2026 09:49:06 +0200 Subject: [PATCH] =?UTF-8?q?v0.2.19=20:=20preset=20actif=20de=20nouveau=20d?= =?UTF-8?q?=C3=A9tect=C3=A9=20(empreinte=20ignore=20les=20cl=C3=A9s=20appa?= =?UTF-8?q?reil=20MEM=5FMODE/CRAWL4AI=5FURL)=20+=20surbrillance=20bleue=20?= =?UTF-8?q?du=20preset=20actif?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 2 +- presets.go | 45 ++++++++++++++++++++++++++++++++---- resource_windows_amd64.syso | Bin 1196 -> 1196 bytes resource_windows_arm64.syso | Bin 1196 -> 1196 bytes ui/index.html | 8 +++---- versioninfo.json | 6 ++--- 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 57ccfdd..94f4373 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ import ( "strings" ) -const Version = "0.2.18" +const Version = "0.2.19" func main() { // Migration one-shot des anciens skills (SKILLS//SKILL.md) vers la diff --git a/presets.go b/presets.go index ed88179..44fa67d 100644 --- a/presets.go +++ b/presets.go @@ -51,15 +51,51 @@ func withDisplayName(content, name string) string { return line + "\n" + content } +// presetFingerprint hashes config content while IGNORING the device-level keys +// (preservedKeys) that SwitchToPreset re-applies on top of a freshly copied +// preset. Without this, those injected MEM_MODE/CRAWL4AI_URL lines make +// config.env differ from every preset file, so no preset is ever detected as +// active (regression introduced when preservedKeys were added). We strip those +// assignment lines symmetrically from both sides before hashing so a plain +// content match still identifies the active preset. +func presetFingerprint(content []byte) string { + var b strings.Builder + for _, line := range strings.Split(string(content), "\n") { + if isPreservedAssignment(line) { + continue + } + b.WriteString(line) + b.WriteByte('\n') + } + h := sha1.Sum([]byte(b.String())) + return hex.EncodeToString(h[:]) +} + +// isPreservedAssignment reports whether a line assigns one of the preservedKeys +// (commented or not), e.g. `MEM_MODE=off` or `# CRAWL4AI_URL=...`. +func isPreservedAssignment(line string) bool { + t := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(line), "#")) + eq := strings.IndexByte(t, '=') + if eq < 0 { + return false + } + key := strings.TrimSpace(t[:eq]) + for _, k := range preservedKeys { + if key == k { + return true + } + } + return false +} + // ListPresets returns all configs/*.env, marking the one whose contents match -// the current config.env (by SHA-1), sorted by display name. +// the current config.env (ignoring device-level preservedKeys), sorted by name. func ListPresets() ([]Preset, error) { dir := presetsDir() _ = os.MkdirAll(dir, 0o755) cur := "" if b, err := os.ReadFile(confPath()); err == nil { - h := sha1.Sum(b) - cur = hex.EncodeToString(h[:]) + cur = presetFingerprint(b) } entries, err := os.ReadDir(dir) if err != nil { @@ -75,13 +111,12 @@ func ListPresets() ([]Preset, error) { if err != nil { continue } - h := sha1.Sum(b) id := strings.TrimSuffix(e.Name(), ".env") out = append(out, Preset{ ID: id, Name: presetDisplayName(string(b), id), Path: p, - Active: hex.EncodeToString(h[:]) == cur, + Active: presetFingerprint(b) == cur, }) } sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name }) diff --git a/resource_windows_amd64.syso b/resource_windows_amd64.syso index f1903fd3bf834f31a358982af63c9c4518cd6243..fc5dc4065ddec7d7b9e2e6d2976fd52fc2d6e0ff 100644 GIT binary patch delta 33 mcmZ3(xrTGXDNbPqCI%1?-gsGspan{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .preset>button{flex-shrink:0} .preset-info{flex:1;min-width:0} diff --git a/versioninfo.json b/versioninfo.json index 5328b42..12b4d0b 100644 --- a/versioninfo.json +++ b/versioninfo.json @@ -3,13 +3,13 @@ "FileVersion": { "Major": 0, "Minor": 2, - "Patch": 18, + "Patch": 19, "Build": 0 }, "ProductVersion": { "Major": 0, "Minor": 2, - "Patch": 18, + "Patch": 19, "Build": 0 }, "FileFlagsMask": "3f", @@ -25,7 +25,7 @@ "LegalCopyright": "Copyright (c) 2026 Jean contributors. MIT License.", "OriginalFilename": "jean.exe", "ProductName": "Jean", - "ProductVersion": "0.2.18", + "ProductVersion": "0.2.19", "Comments": "https://github.com/nathaninline/jean — projet open source (MIT)" }, "VarFileInfo": {