diff --git a/ui/assemble.ps1 b/ui/assemble.ps1 new file mode 100644 index 0000000..e661a16 --- /dev/null +++ b/ui/assemble.ps1 @@ -0,0 +1,27 @@ +# assemble.ps1 — reconstruit ui/index.html à partir des sources ui/src/. +# +# ui/index.html est un fichier GÉNÉRÉ (mais committé : go:embed et +# ajean-app/build-server-ui.ps1 le lisent tel quel). Pour modifier l'UI : +# éditer ui/src/ (styles.css, js/NN-*.js, index.tmpl.html) puis relancer ce +# script. Les js/ sont concaténés dans l'ordre alphabétique (préfixes NN-), +# tout reste en scope global comme avant le découpage. +# +# Tout est manipulé en octets bruts (fins de ligne/encodage préservés). + +$ErrorActionPreference = 'Stop' +$here = Split-Path -Parent $MyInvocation.MyCommand.Path +$src = Join-Path $here 'src' +$dst = Join-Path $here 'index.html' + +$tmpl = [IO.File]::ReadAllText((Join-Path $src 'index.tmpl.html')) +$css = [IO.File]::ReadAllText((Join-Path $src 'styles.css')) +$js = (Get-ChildItem (Join-Path $src 'js') -Filter '*.js' | Sort-Object Name | + ForEach-Object { [IO.File]::ReadAllText($_.FullName) }) -join '' + +foreach ($m in '@@CSS@@', '@@JS@@') { + if (-not $tmpl.Contains("$m`n")) { throw "marqueur $m introuvable dans index.tmpl.html" } +} +$html = $tmpl.Replace("@@CSS@@`n", $css).Replace("@@JS@@`n", $js) + +[IO.File]::WriteAllText($dst, $html, [Text.UTF8Encoding]::new($false)) +Write-Host "OK -> $dst ($([IO.File]::ReadAllBytes($dst).Length) octets)" diff --git a/ui/src/index.tmpl.html b/ui/src/index.tmpl.html new file mode 100644 index 0000000..4e48bf6 --- /dev/null +++ b/ui/src/index.tmpl.html @@ -0,0 +1,221 @@ + + + + + + + + +Jean + + + + + + + +
+
+
+

ajean

+ … +
+
GPU +
…
+
+
Config active +
…
+
+
Presets +
+
+
Mode agent + + +
+
Mémoire?
+ +
+ ▸ + Pages + +
+ +
+
+
Accès internet?Ajoute les outils web_search / web_open / web_read / web_grep via un serveur Crawl4AI. Actifs seulement si le serveur répond.
+ +
+ + +
+
+
+
+
Paramètres
+ + +
+
+
Apparence + + +
+
System prompt + +
+
Accès OpenAI +
Endpoint compatible OpenAI?Branche n'importe quel client compatible OpenAI (OpenCode, Continue, Cursor…) sur cette URL. Modèle : jean. Si une clé est définie, le client doit envoyer Authorization: Bearer <clé>.
+ + +
+
🏠 local (réseau)
+
+ + +
+
+
modèle : jean
+
Clé API?Protège l'endpoint des complétions (llama-server). Indispensable avant d'exposer le serveur sur internet. Modifier la clé redémarre le service.
+
+ + + +
+
+ + + +
+
+
Service +
+ + + +
+
+
Actions +
+
+
+ + + +
+
+
+
+
+ +
+
+
+ + + contexte 0 / 0 + + +
+
+ + + +
+
Entrée pour envoyer · Maj+Entrée = nouvelle ligne
+
+
+
+ + + + + diff --git a/ui/src/js/00-md.js b/ui/src/js/00-md.js new file mode 100644 index 0000000..a9db1da --- /dev/null +++ b/ui/src/js/00-md.js @@ -0,0 +1,21 @@ +// marked: GFM on, no auto-breaks (single newlines stay inline). +marked.setOptions({ gfm: true, breaks: false }); +// Pre-process to fix common LLM markdown mistakes before handing to marked: +// - code fences glued to preceding text on the same line ("foo ```ruby ...") +// - fences without a closing newline +// - 3+ consecutive blank lines collapsed to one (LLMs love padding) +function fixMd(s){ + if(!s) return ''; + // Force a newline before a fence that's been glued to preceding text + // (common LLM mistake: "...crée le fichier et```ruby"). We do NOT split + // *after* the fence — the part after the fence is the language identifier. + s = s.replace(/([^\n])(\s*)(```+|~~~+)(?=\w*\s*\n)/g, '$1\n$3'); + // Collapse runs of blank lines that LLMs love to emit. + s = s.replace(/\n{3,}/g, '\n\n'); + return s; +} +function md(src){ return src ? marked.parse(fixMd(src)) : ''; } +let msgs = []; +let busy = false; +function toggleSide(){ document.getElementById('side').classList.toggle('open'); document.getElementById('backdrop').classList.toggle('open'); document.body.classList.toggle('drawer-open'); } +function saveSys(){ localStorage.setItem('jean.sys', document.getElementById('sysprompt').value); } diff --git a/ui/src/js/01-theme.js b/ui/src/js/01-theme.js new file mode 100644 index 0000000..883476d --- /dev/null +++ b/ui/src/js/01-theme.js @@ -0,0 +1,43 @@ +// ===== Thèmes ================================================================ +// Registre des thèmes disponibles. Pour en AJOUTER un : ajouter un bloc +// [data-theme="…"] dans le