diff --git a/buildfilter_test.go b/backend_buildfilter_test.go similarity index 100% rename from buildfilter_test.go rename to backend_buildfilter_test.go diff --git a/catalog.go b/backend_catalog.go similarity index 96% rename from catalog.go rename to backend_catalog.go index cde8fbb..bd88487 100644 --- a/catalog.go +++ b/backend_catalog.go @@ -1,6 +1,6 @@ package main -// catalog.go — récupère la liste de modèles curatée servie par ajean.link et la +// backend_catalog.go — récupère la liste de modèles curatée servie par ajean.link et la // combine avec les infos matérielles locales, pour que l'écran d'accueil (à // venir) propose « en un clic » un modèle adapté à la machine. // diff --git a/config.go b/backend_config.go similarity index 100% rename from config.go rename to backend_config.go diff --git a/gpu.go b/backend_gpu.go similarity index 97% rename from gpu.go rename to backend_gpu.go index bbb454c..d53cbc8 100644 --- a/gpu.go +++ b/backend_gpu.go @@ -9,14 +9,14 @@ import ( "strings" ) -// gpu.go — sélection du/des GPU utilisés par llama-server. +// backend_gpu.go — sélection du/des GPU utilisés par llama-server. // // jean gpu liste les GPU et montre la sélection courante // jean gpu 1 n'utilise que le GPU d'index 1 // jean gpu 0 1 utilise les GPU 0 et 1 // jean gpu all réinitialise (tous les GPU visibles) // -// La sélection est stockée dans config.env sous CUDA_VISIBLE_DEVICES ; serve.go +// La sélection est stockée dans config.env sous CUDA_VISIBLE_DEVICES ; backend_serve.go // l'exporte (avec CUDA_DEVICE_ORDER=PCI_BUS_ID pour que les index correspondent // à ceux affichés par nvidia-smi). diff --git a/llamacpp.go b/backend_llamacpp.go similarity index 99% rename from llamacpp.go rename to backend_llamacpp.go index 2e67cbd..5a25fe4 100644 --- a/llamacpp.go +++ b/backend_llamacpp.go @@ -15,7 +15,7 @@ import ( "time" ) -// llamacpp.go — gestion du backend llama.cpp (clone, build, mise à jour). +// backend_llamacpp.go — gestion du backend llama.cpp (clone, build, mise à jour). // // `jean llamacpp install` installe un build neuf, détecte automatiquement // l'accélérateur (CUDA / ROCm / Metal / CPU) et la diff --git a/models.go b/backend_models.go similarity index 99% rename from models.go rename to backend_models.go index e1c3e0b..607f42e 100644 --- a/models.go +++ b/backend_models.go @@ -56,7 +56,7 @@ func presetReasoning(content string) string { return "" } -// reasoningActive reports whether a REASONING= value enables reasoning. serve.go +// reasoningActive reports whether a REASONING= value enables reasoning. backend_serve.go // passes the flag whenever the value is non-empty, but an explicit off/none is // treated here as disabled so the UI badge isn't misleading. func reasoningActive(v string) bool { diff --git a/presets.go b/backend_presets.go similarity index 100% rename from presets.go rename to backend_presets.go diff --git a/serve.go b/backend_serve.go similarity index 96% rename from serve.go rename to backend_serve.go index bb985e8..0ccbe21 100644 --- a/serve.go +++ b/backend_serve.go @@ -64,7 +64,7 @@ func cmdServe(args []string) error { // budget illimité par défaut (-1) : on laisse le modèle réfléchir jusqu'au // bout au lieu de le couper à 2048, ce qui tronquait la vraie réponse (la // réflexion atteignait le plafond et il ne restait plus de marge pour le - // contenu). L'anti-boucle côté llm.go reste le garde-fou. NE PAS forcer 0 : + // contenu). L'anti-boucle côté llm_client.go reste le garde-fou. NE PAS forcer 0 : // sur llama.cpp vanilla, 0 = "immediate end" → coupe tout le raisonnement // (le fork ik_llama.cpp l'ignore). Configurable via REASONING_BUDGET. llmArgs = append(llmArgs, "--reasoning", r, "--reasoning-budget", get("REASONING_BUDGET", "-1")) @@ -91,6 +91,6 @@ func cmdServe(args []string) error { bin, filepath.Base(model), get("PORT", "8080")) // Hand off to the llama-server process. On Unix this replaces the current - // process (exec); on Windows it runs as a child and waits. See platform_*.go. + // process (exec); on Windows it runs as a child and waits. See sys_platform_*.go. return execServer(bin, llmArgs) } diff --git a/agent.go b/chat_agent.go similarity index 100% rename from agent.go rename to chat_agent.go diff --git a/chat.go b/chat_cmd.go similarity index 100% rename from chat.go rename to chat_cmd.go diff --git a/compact.go b/chat_compact.go similarity index 100% rename from compact.go rename to chat_compact.go diff --git a/compact_test.go b/chat_compact_test.go similarity index 100% rename from compact_test.go rename to chat_compact_test.go diff --git a/conversation.go b/chat_conversation.go similarity index 100% rename from conversation.go rename to chat_conversation.go diff --git a/conversation_test.go b/chat_conversation_test.go similarity index 100% rename from conversation_test.go rename to chat_conversation_test.go diff --git a/internet.go b/chat_internet.go similarity index 99% rename from internet.go rename to chat_internet.go index 835d972..52db311 100644 --- a/internet.go +++ b/chat_internet.go @@ -41,7 +41,7 @@ func crawl4aiURL() string { } // internetEnabled : accès internet actif = drapeau .internet_enabled présent ET -// une URL Crawl4AI configurée. Même modèle que agentEnabled() (agent.go). +// une URL Crawl4AI configurée. Même modèle que agentEnabled() (chat_agent.go). func internetEnabled() bool { if crawl4aiURL() == "" { return false @@ -539,7 +539,7 @@ func duckduckgoSearch(query string, limit int) ([]searchResult, error) { return results, nil } -// ─── définitions d'outils (schémas OpenAI, comme llm.go) ──────────────────── +// ─── définitions d'outils (schémas OpenAI, comme llm_client.go) ──────────────────── func webSearchTool() Tool { return Tool{Type: "function", Function: ToolFunction{ @@ -614,7 +614,7 @@ func webGrepTool() Tool { }} } -// ─── exécution des outils (appelée par le dispatch de llm.go) ─────────────── +// ─── exécution des outils (appelée par le dispatch de llm_client.go) ─────────────── func toolWebSearch(args map[string]any) string { query, _ := args["query"].(string) diff --git a/memory.go b/chat_memory.go similarity index 100% rename from memory.go rename to chat_memory.go diff --git a/tools.go b/chat_tools.go similarity index 99% rename from tools.go rename to chat_tools.go index b0f19b0..7125d97 100644 --- a/tools.go +++ b/chat_tools.go @@ -117,7 +117,7 @@ func machineSystemPrompt(caps Caps) string { } // runShell executes a command via the platform shell (bash -c on Unix, cmd /C -// on Windows — see newShellCmd in platform_*.go) with a clamped timeout, +// on Windows — see newShellCmd in sys_platform_*.go) with a clamped timeout, // returning a single string formatted "exit: N\n\nstdout:\n...\n\nstderr:\n..." // truncated to keep tool output bounded. func runShell(command string, timeoutSec int) string { diff --git a/app.go b/cli_app.go similarity index 93% rename from app.go rename to cli_app.go index dff9c0d..db46ae2 100644 --- a/app.go +++ b/cli_app.go @@ -1,11 +1,11 @@ package main -// app.go — expérience « application » de Jean. +// cli_app.go — expérience « application » de Jean. // // Quand on double-clique sur le binaire (aucun argument, console fraîche), au // lieu d'afficher l'aide dans une console qui se ferme, Jean démarre son UI web, // l'ouvre dans le navigateur ET pose une icône dans la zone de notification -// Windows (voir tray_windows.go) : on voit que Jean tourne et on le pilote +// Windows (voir sys_tray_windows.go) : on voit que Jean tourne et on le pilote // (« Ouvrir Jean » / « Quitter »). import ( diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..1b52751 --- /dev/null +++ b/doc.go @@ -0,0 +1,18 @@ +// Jean — binaire unique (package main). Les fichiers sont préfixés par domaine +// (Go n'autorise pas de sous-dossiers dans un même package) : +// +// main.go point d'entrée : dispatch des sous-commandes, chemins (JeanHome…) +// cli_* expérience « application » (double-clic : UI + tray + splash) +// web_* serveur HTTP local :8090 (UI embarquée via go:embed ui/, auth, prefs) +// chat_* chat CLI + conversation serveur partagée, compaction, mémoire, +// outils de l'agent (dont accès internet via Crawl4AI) +// llm_* client llama-server (complétions, endpoint OpenAI, bench, test) +// backend_* gestion llama.cpp : build (llamacpp), GPU, serve (ExecStart), +// modèles/téléchargements, catalogue, presets, config.env +// relay_* accès distant ajean.link : tunnel (link), chiffrement E2E, appairage +// sys_* intégration OS : install, services (systemd/launchd/Windows), +// plateforme, process, tray, splash, tty, auto-update +// +// Les suffixes _windows/_linux/_darwin/_unix/_other portent les contraintes de +// compilation par OS. ui/index.html est GÉNÉRÉ depuis ui/src/ (voir ui/assemble.ps1). +package main diff --git a/bench.go b/llm_bench.go similarity index 100% rename from bench.go rename to llm_bench.go diff --git a/llm.go b/llm_client.go similarity index 99% rename from llm.go rename to llm_client.go index 48564d5..ac1f96a 100644 --- a/llm.go +++ b/llm_client.go @@ -176,7 +176,7 @@ type Caps struct { // specify its own capabilities. func globalCaps() Caps { // Internet inclut la joignabilité du serveur Crawl4AI : « actif ET fonctionnel ». - // Ainsi le prompt système (tools.go) et les outils fournis (EnabledTools) sont + // Ainsi le prompt système (chat_tools.go) et les outils fournis (EnabledTools) sont // gouvernés par la MÊME condition — sinon le prompt promet web_search alors que // l'outil n'existe pas, et le modèle le tape en bash (command not found). // Mémoire et accès internet sont des sous-réglages du mode agent (cf. UI web) : @@ -229,7 +229,7 @@ func EnabledTools(caps Caps) []Tool { tools = append(tools, memSearchTool(), memReadTool(), memAddTool(), memEditTool()) } // Outils web : seulement si le mode agent ET l'accès internet sont actifs. - // caps.Internet intègre déjà la joignabilité (globalCaps / override web.go), + // caps.Internet intègre déjà la joignabilité (globalCaps / override web_server.go), // donc prompt et outils restent cohérents — pas de web_search halluciné. if caps.Agent && caps.Internet { tools = append(tools, webSearchTool(), webOpenTool(), webReadTool(), webGrepTool()) diff --git a/oai.go b/llm_oai.go similarity index 98% rename from oai.go rename to llm_oai.go index bc76bb2..36616f0 100644 --- a/oai.go +++ b/llm_oai.go @@ -24,7 +24,7 @@ import ( "github.com/caddyserver/certmagic" ) -// oai.go — front TLS de l'accès OpenAI public "VPS aveugle" (SNI passthrough). +// llm_oai.go — front TLS de l'accès OpenAI public "VPS aveugle" (SNI passthrough). // // Principe : le SaaS parle HTTPS OpenAI standard vers .oai.ajean.link. // Le VPS relais ne fait que recopier les octets TLS bruts (routage par SNI, sans @@ -127,7 +127,7 @@ func oaiTLSConfig() *tls.Config { // Le relais ouvre soit un stream HTTP normal (UI / E2E), soit un stream "brut" // qui porte une session TLS de bout en bout (accès OpenAI). On les distingue au // 1er octet : un enregistrement TLS commence par 0x16 (handshake), une requête -// HTTP par une lettre ASCII (GET/POST/…). Voir demuxTunnelStream dans link.go. +// HTTP par une lettre ASCII (GET/POST/…). Voir demuxTunnelStream dans relay_link.go. // peekedConn rend un net.Conn dont on a déjà consulté le début, sans perdre ces // octets (ils restent dans le bufio.Reader). diff --git a/test_cmd.go b/llm_testcmd.go similarity index 100% rename from test_cmd.go rename to llm_testcmd.go diff --git a/main.go b/main.go index 51b457e..4b91459 100644 --- a/main.go +++ b/main.go @@ -172,7 +172,7 @@ func mustExit(err error) { // JeanHome resolves the JEAN data directory. // Precedence: $JEAN_HOME → /etc/default/jean (unix only) → defaultJeanHome(). -// defaultJeanHome() is platform-specific (see platform_unix.go / platform_windows.go). +// defaultJeanHome() is platform-specific (see sys_platform_unix.go / sys_platform_windows.go). func JeanHome() string { if h := os.Getenv("JEAN_HOME"); h != "" { return h diff --git a/e2e.go b/relay_e2e.go similarity index 99% rename from e2e.go rename to relay_e2e.go index 0f711d7..5a17ecd 100644 --- a/e2e.go +++ b/relay_e2e.go @@ -1,6 +1,6 @@ package main -// e2e.go — chiffrement bout-en-bout du chat entre le NAVIGATEUR et CET agent, de +// relay_e2e.go — chiffrement bout-en-bout du chat entre le NAVIGATEUR et CET agent, de // sorte que le relais (ajean.link) ne voie que de l'opaque : « boîte noire ». // // Modèle : cet agent a une paire X25519 long-terme (clé privée locale, jamais diff --git a/e2eauth.go b/relay_e2eauth.go similarity index 99% rename from e2eauth.go rename to relay_e2eauth.go index 2a29f90..5d56756 100644 --- a/e2eauth.go +++ b/relay_e2eauth.go @@ -1,6 +1,6 @@ package main -// e2eauth.go — authentification MUTUELLE + anti-rejeu du canal chiffré. +// relay_e2eauth.go — authentification MUTUELLE + anti-rejeu du canal chiffré. // // Le scellé anonyme (boîte scellée) garantit la confidentialité mais PAS // l'authenticité : n'importe qui connaissant la clé publique de l'agent (dont un diff --git a/link.go b/relay_link.go similarity index 99% rename from link.go rename to relay_link.go index ed03500..98b9bee 100644 --- a/link.go +++ b/relay_link.go @@ -1,6 +1,6 @@ package main -// link.go — `jean link ` : connecte ce serveur Jean au relais public +// relay_link.go — `jean link ` : connecte ce serveur Jean au relais public // (ajean.link) par une connexion SORTANTE persistante, pour qu'un utilisateur // y accède depuis n'importe où sans ouvrir de port (CGNAT, box, etc.). // diff --git a/install_darwin.go b/sys_install_darwin.go similarity index 97% rename from install_darwin.go rename to sys_install_darwin.go index a9ed84a..6660878 100644 --- a/install_darwin.go +++ b/sys_install_darwin.go @@ -11,8 +11,8 @@ import ( "strings" ) -// install_darwin.go — installation macOS via launchd (LaunchDaemon), équivalent -// de install_linux.go (systemd). ⚠️ NON TESTÉ sur un vrai Mac : le support macOS +// sys_install_darwin.go — installation macOS via launchd (LaunchDaemon), équivalent +// de sys_install_linux.go (systemd). ⚠️ NON TESTÉ sur un vrai Mac : le support macOS // était totalement absent (le code systemd/Linux tournait par erreur et échouait // sur « systemctl: command not found » / « /etc/default/jean », cf. issue #4). // Implémentation prudente ; à valider sur une machine Apple. diff --git a/install_linux.go b/sys_install_linux.go similarity index 100% rename from install_linux.go rename to sys_install_linux.go diff --git a/install_windows.go b/sys_install_windows.go similarity index 98% rename from install_windows.go rename to sys_install_windows.go index 67bb0d9..51a05d5 100644 --- a/install_windows.go +++ b/sys_install_windows.go @@ -13,7 +13,7 @@ import ( // On Windows there's no systemd unit, sudoers, or /usr/local/bin to populate. // `jean install` simply provisions the data directory and a starter config; the -// service itself is managed by the PID-file supervisor in service_windows.go +// service itself is managed by the PID-file supervisor in sys_service_windows.go // (jean start / stop / status), which needs no admin rights. const configTemplate = `# Configuration JEAN — édite-moi puis: jean restart diff --git a/platform_unix.go b/sys_platform_unix.go similarity index 100% rename from platform_unix.go rename to sys_platform_unix.go diff --git a/platform_windows.go b/sys_platform_windows.go similarity index 100% rename from platform_windows.go rename to sys_platform_windows.go diff --git a/proc_other.go b/sys_proc_other.go similarity index 70% rename from proc_other.go rename to sys_proc_other.go index 66d67db..3c0e8bb 100644 --- a/proc_other.go +++ b/sys_proc_other.go @@ -2,7 +2,7 @@ package main -// proc_other.go — hors Windows, pas de détachement (le mode app double-clic est +// sys_proc_other.go — hors Windows, pas de détachement (le mode app double-clic est // propre à Windows). Défini pour la compilation ; non appelé en pratique car // launchedByDoubleClick renvoie false sur Unix. diff --git a/proc_windows.go b/sys_proc_windows.go similarity index 91% rename from proc_windows.go rename to sys_proc_windows.go index 402d3b2..95cb439 100644 --- a/proc_windows.go +++ b/sys_proc_windows.go @@ -2,7 +2,7 @@ package main -// proc_windows.go — au double-clic, on relance Jean en processus DÉTACHÉ, sans +// sys_proc_windows.go — au double-clic, on relance Jean en processus DÉTACHÉ, sans // console. L'original (qui, lui, possède la console fraîche créée par Explorer) // se termine aussitôt, fermant sa console. Le nouveau process n'a aucune fenêtre // de console : il n'y a donc plus de « terminal noir » et plus rien à fermer qui diff --git a/service.go b/sys_service.go similarity index 86% rename from service.go rename to sys_service.go index e93e27c..50b6050 100644 --- a/service.go +++ b/sys_service.go @@ -8,11 +8,11 @@ import ( "strings" ) -// service.go holds the platform-neutral pieces of service management. The +// sys_service.go holds the platform-neutral pieces of service management. The // actual start/stop/restart/status/logs implementation is platform-specific: -// - service_linux.go → systemd (systemctl/journalctl) -// - service_darwin.go → launchd (launchctl) -// - service_windows.go → PID-file background process supervisor +// - sys_service_linux.go → systemd (systemctl/journalctl) +// - sys_service_darwin.go → launchd (launchctl) +// - sys_service_windows.go → PID-file background process supervisor // // editConfig and showVram live here because they work the same everywhere. diff --git a/service_darwin.go b/sys_service_darwin.go similarity index 94% rename from service_darwin.go rename to sys_service_darwin.go index f9994e6..744ecd6 100644 --- a/service_darwin.go +++ b/sys_service_darwin.go @@ -11,8 +11,8 @@ import ( "time" ) -// service_darwin.go — gestion du service via launchd (LaunchDaemon), équivalent -// macOS de service_linux.go (systemd). ⚠️ NON TESTÉ sur un vrai Mac : jusqu'ici +// sys_service_darwin.go — gestion du service via launchd (LaunchDaemon), équivalent +// macOS de sys_service_linux.go (systemd). ⚠️ NON TESTÉ sur un vrai Mac : jusqu'ici // le support macOS était absent (le code systemd/Linux était utilisé par erreur, // cf. issue #4). Implémentation prudente basée sur launchctl load/unload/list. diff --git a/service_linux.go b/sys_service_linux.go similarity index 100% rename from service_linux.go rename to sys_service_linux.go diff --git a/service_windows.go b/sys_service_windows.go similarity index 100% rename from service_windows.go rename to sys_service_windows.go diff --git a/splash_other.go b/sys_splash_other.go similarity index 66% rename from splash_other.go rename to sys_splash_other.go index 57bf642..90b555a 100644 --- a/splash_other.go +++ b/sys_splash_other.go @@ -2,7 +2,7 @@ package main -// splash_other.go — pas de fenêtre de démarrage hors Windows (no-op). +// sys_splash_other.go — pas de fenêtre de démarrage hors Windows (no-op). type splash struct{} diff --git a/splash_windows.go b/sys_splash_windows.go similarity index 98% rename from splash_windows.go rename to sys_splash_windows.go index 7fa139f..c559092 100644 --- a/splash_windows.go +++ b/sys_splash_windows.go @@ -2,7 +2,7 @@ package main -// splash_windows.go — écran de démarrage « Lancement de Jean… ». +// sys_splash_windows.go — écran de démarrage « Lancement de Jean… ». // // Petite fenêtre sans bordure, à coins arrondis, aux couleurs de la marque // (fond bleu #1f6feb, logo « j » blanc, texte blanc), affichée le temps que le diff --git a/tray_other.go b/sys_tray_other.go similarity index 80% rename from tray_other.go rename to sys_tray_other.go index 4b7c67e..2bc1ed8 100644 --- a/tray_other.go +++ b/sys_tray_other.go @@ -2,7 +2,7 @@ package main -// tray_other.go — pas d'icône de zone de notification hors Windows (la demande +// sys_tray_other.go — pas d'icône de zone de notification hors Windows (la demande // vise le tray Windows). On se contente d'ouvrir l'UI dans le navigateur et de // garder le serveur en vie. Aucun import systray ici → les builds Linux/macOS // restent purs (CGO_ENABLED=0). diff --git a/tray_windows.go b/sys_tray_windows.go similarity index 97% rename from tray_windows.go rename to sys_tray_windows.go index 4f944ca..ed735c1 100644 --- a/tray_windows.go +++ b/sys_tray_windows.go @@ -2,7 +2,7 @@ package main -// tray_windows.go — icône de Jean dans la zone de notification Windows (system +// sys_tray_windows.go — icône de Jean dans la zone de notification Windows (system // tray). Quand on lance l'app (double-clic ou `jean app`), l'UI web s'ouvre dans // le navigateur ET une petite icône apparaît près de l'horloge : elle montre que // Jean tourne et offre un menu « Ouvrir Jean » / « Quitter ». diff --git a/tty.go b/sys_tty.go similarity index 100% rename from tty.go rename to sys_tty.go diff --git a/update.go b/sys_update.go similarity index 100% rename from update.go rename to sys_update.go diff --git a/webauth.go b/web_auth.go similarity index 97% rename from webauth.go rename to web_auth.go index 1aa5d18..a690337 100644 --- a/webauth.go +++ b/web_auth.go @@ -11,7 +11,7 @@ import ( "strings" ) -// webauth.go protège l'API de pilotage (jean web) quand elle est exposée sur +// web_auth.go protège l'API de pilotage (jean web) quand elle est exposée sur // internet — c.-à-d. l'API que tout client (navigateur, app mobile, script…) // utilise pour switcher de preset, redémarrer le service, lire le status, etc. // diff --git a/webprefs.go b/web_prefs.go similarity index 100% rename from webprefs.go rename to web_prefs.go diff --git a/web.go b/web_server.go similarity index 99% rename from web.go rename to web_server.go index b24cf4a..70c04bd 100644 --- a/web.go +++ b/web_server.go @@ -73,7 +73,7 @@ func newWebMux() *http.ServeMux { w.Header().Set("Cache-Control", "public, max-age=86400") w.Write(b) }) - // api enregistre une route /api/* protégée par la clé de pilotage (webauth.go). + // api enregistre une route /api/* protégée par la clé de pilotage (web_auth.go). api := func(path string, h http.HandlerFunc) { mux.HandleFunc(path, requireWebAuth(h)) } api("/api/ping", handlePing) api("/api/status", handleStatus) @@ -224,7 +224,7 @@ func handlePing(w http.ResponseWriter, r *http.Request) { } // handleStatus reports service state cross-platform via serviceIsActive -// (systemd sous Linux, supervision par PID-file sous Windows — voir service_*.go). +// (systemd sous Linux, supervision par PID-file sous Windows — voir sys_service_*.go). func handleStatus(w http.ResponseWriter, r *http.Request) { active := serviceIsActive() state := "inactive" @@ -730,7 +730,7 @@ func handleSwitch(w http.ResponseWriter, r *http.Request) { // svcHandler returns an HTTP handler that triggers a start/stop/restart through // the cross-platform serviceAction (systemd sous Linux, supervision PID-file -// sous Windows — voir service_*.go). C'est ce qui permet à un client distant +// sous Windows — voir sys_service_*.go). C'est ce qui permet à un client distant // de relancer Jean. func svcHandler(action string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) {