diff --git a/CHANGELOG.md b/CHANGELOG.md index 3658648..96b992e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog - FlowDeck +## v7.83.1 (2026-10-26) — Panneau Spark : version du service d'agents visible en mode sidebar + +- **Panneau Spark** (`static/js/draco-panneau.js`) : le pied du panneau + affiche désormais la ligne discrète et permanente « Service d'agents + vX », comme la console pleine page. La version est lue **en direct** + dans la santé du service (`GET /healthz` de l'origine que le panneau + connaît déjà), à l'ouverture du panneau, avec cache de session — + jamais une valeur codée en dur ; service injoignable = rien + d'affiché, aucune erreur visible. Carte fusion #64. + ## v7.83.0 (2026-10-26) — Fusion : serveur MCP complété (ACC-5.1) et pont MCP vers ObsiGate (ACC-2.2) - **ACC-5.1 — serveur MCP Flowdeck complété** (`app/routers/mcp_server.py`, diff --git a/VERSION b/VERSION index 22bce22..de3f8e8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.83.0 +7.83.1 diff --git a/app/main.py b/app/main.py index 1f9fdb7..3ec4d37 100644 --- a/app/main.py +++ b/app/main.py @@ -216,7 +216,7 @@ def _lire_version() -> str: # Littéral de version synchronisé avec le fichier VERSION : -# version="7.83.0" +# version="7.83.1" # Patron historique des bumps (voir scripts/bump_version.py, qui cherche # ce littéral) et contrôle de tests/test_pwa_offline.py. La version # runtime reste lue dynamiquement depuis VERSION par _lire_version() diff --git a/static/js/draco-panneau.js b/static/js/draco-panneau.js index e4062ed..a7229a4 100644 --- a/static/js/draco-panneau.js +++ b/static/js/draco-panneau.js @@ -46,6 +46,7 @@ var etatConnu = false; var root = null, msgsEl = null, etatEl = null, inputEl = null, sendBtn = null; var titreEl = null, tiroirEl = null; + var versionEl = null, versionConnue = "", versionMaj = 0; function domaine() { try { return localStorage.getItem("draco_domain") || "pro"; } catch (e) { return "pro"; } @@ -274,6 +275,7 @@ ' ' + ' ' + '
Conversation réelle, sous-agents (J3) et missions longues (J5) vers les exécuteurs configurés ; toute écriture dans les apps passe par une approbation.
' + + ' ' + ''; document.body.appendChild(root); msgsEl = root.querySelector(".draco-panneau-msgs"); @@ -282,6 +284,7 @@ sendBtn = root.querySelector("button[type=submit]"); titreEl = root.querySelector(".d-titre"); tiroirEl = root.querySelector(".draco-discussions"); + versionEl = root.querySelector(".draco-panneau-version"); root.querySelector(".fermer").addEventListener("click", fermer); root.querySelector('[data-disc="liste"]').addEventListener("click", basculerTiroir); root.querySelector('[data-disc="nouvelle"]').addEventListener("click", nouvelleDiscussion); @@ -336,6 +339,35 @@ titreEl.title = titreEl.textContent; } + /* ── Version du service : lue en direct dans la santé de + * l'agent (GET /healthz → champ « version », la même source que + * la console) à l'origine que le panneau connaît déjà. Cache de + * session (5 min), rafraîchie à l'ouverture du panneau, au même + * rythme que la vérification d'identité. Jamais de valeur codée + * en dur : source injoignable ou réponse illisible = la ligne + * reste masquée — pas de fausse version, pas d'erreur visible. */ + function afficherVersion() { + if (!versionEl) return; + if (versionConnue) { + versionEl.textContent = "Service d'agents v" + versionConnue; + versionEl.hidden = false; + } + } + function chargerVersion() { + if (!API || !versionEl) return; + if (versionConnue && Date.now() - versionMaj < 300000) { afficherVersion(); return; } + fetch(API + "/healthz") + .then(function (r) { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); }) + .then(function (d) { + if (d && typeof d.version === "string" && /^[0-9]+\.[0-9]+\.[0-9]+/.test(d.version)) { + versionConnue = d.version; + versionMaj = Date.now(); + afficherVersion(); + } + }) + .catch(function () { /* service injoignable : rien d'affiché */ }); + } + function verifierIdentite() { if (etatConnu) return; fetch(API + "/api/v1/me", { credentials: "include" }) @@ -812,6 +844,7 @@ root.classList.add("open"); appliquerTheme(); verifierIdentite(); + chargerVersion(); setTimeout(function () { inputEl.focus(); }, 300); } function fermer() { if (root) root.classList.remove("open"); }