Thèmes par agent (bleu ka2 / orange ka4 / mauve ka6) + favicons SVG signature + jeton opérateur
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7 changed files +48 −11
modified
orchestrator/main.py
+6 −1
@@ -641,7 +641,7 @@ def state() -> dict[str, Any]: | |||||
| 641 | history = [dict(r) for r in c.execute( | 641 | history = [dict(r) for r in c.execute( | ||
| 642 | "SELECT ts, mine FROM snapshots WHERE ts > ? ORDER BY ts", (now() - 7 * 86400,)).fetchall()] | 642 | "SELECT ts, mine FROM snapshots WHERE ts > ? ORDER BY ts", (now() - 7 * 86400,)).fetchall()] | ||
| 643 | return { | 643 | return { | ||
| 644 | − "agent": AGENT, "identity": {k: ME[k] for k in ("domain", "accent", "accent2", "tagline", "model")}, | 644 | + "agent": AGENT, "identity": {k: ME.get(k) for k in ("domain", "accent", "accent2", "accent_soft", "tagline", "model")}, | ||
| 645 | "services": {s: {**SERVICES[s], "node_alias": NODES[SERVICES[s]["node"]]["alias"]} for s in ME["services"]}, | 645 | "services": {s: {**SERVICES[s], "node_alias": NODES[SERVICES[s]["node"]]["alias"]} for s in ME["services"]}, | ||
| 646 | "siblings": {a: {"domain": v["domain"], "accent": v["accent"], "services": v["services"]} | 646 | "siblings": {a: {"domain": v["domain"], "accent": v["accent"], "services": v["services"]} | ||
| 647 | for a, v in TOPO["agents"].items() if a != AGENT}, | 647 | for a, v in TOPO["agents"].items() if a != AGENT}, | ||
@@ -759,6 +759,11 @@ def health() -> dict[str, Any]: | |||||
| 759 | return {"ok": True, "agent": AGENT, "polled": LATEST["polled"], "paused": LATEST["paused"]} | 759 | return {"ok": True, "agent": AGENT, "polled": LATEST["polled"], "paused": LATEST["paused"]} | ||
| 760 | 760 | ||||
| 761 | 761 | ||||
| 762 | +@app.get("/favicon.svg") | ||||
| 763 | +def favicon() -> FileResponse: | ||||
| 764 | + return FileResponse(BASE / "web" / f"favicon-{AGENT}.svg", media_type="image/svg+xml") | ||||
| 765 | + | ||||
| 766 | + | ||||
| 762 | @app.get("/") | 767 | @app.get("/") | ||
| 763 | def index() -> FileResponse: | 768 | def index() -> FileResponse: | ||
| 764 | return FileResponse(BASE / "web" / "index.html") | 769 | return FileResponse(BASE / "web" / "index.html") | ||
modified
orchestrator/web/app.js
+7 −1
@@ -17,7 +17,13 @@ async function load() { | |||||
| 17 | const r = await fetch("/api/state"); | 17 | const r = await fetch("/api/state"); | ||
| 18 | STATE = await r.json(); | 18 | STATE = await r.json(); | ||
| 19 | const id = STATE.identity, num = STATE.agent.replace("ka", ""); | 19 | const id = STATE.identity, num = STATE.agent.replace("ka", ""); | ||
| 20 | − document.documentElement.style.setProperty("--agent", id.accent); | 20 | + // Thème par agent (bleu ka2 / orange ka4 / mauve ka6): l'accent de l'agent | ||
| 21 | + // remplace le lime du design system sur tout son site. | ||||
| 22 | + const rs = document.documentElement.style; | ||||
| 23 | + rs.setProperty("--agent", id.accent); | ||||
| 24 | + rs.setProperty("--lime", id.accent); | ||||
| 25 | + if (id.accent_soft) rs.setProperty("--lime-soft", id.accent_soft); | ||||
| 26 | + if (id.accent2) rs.setProperty("--accent-deep", id.accent2); | ||||
| 21 | document.title = `${STATE.agent.toUpperCase()} Guardian — Groupe KA`; | 27 | document.title = `${STATE.agent.toUpperCase()} Guardian — Groupe KA`; | ||
| 22 | $("#wm-name").textContent = "ka·" + num; | 28 | $("#wm-name").textContent = "ka·" + num; | ||
| 23 | $("#foot-name").textContent = "ka·" + num; | 29 | $("#foot-name").textContent = "ka·" + num; | ||
added
orchestrator/web/favicon-ka2.svg
+7 −0
@@ -0,0 +1,7 @@ | |||||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> | ||||
| 2 | + <!-- KA Guardian ka2 — encre + pastille lime ·Ka + battement (surveillance) --> | ||||
| 3 | + <rect width="64" height="64" rx="14" fill="#141814"/> | ||||
| 4 | + <circle cx="51" cy="13" r="4.5" fill="#d9f26b"/> | ||||
| 5 | + <text x="30" y="36" font-family="'JetBrains Mono','Menlo',ui-monospace,monospace" font-size="26" font-weight="700" fill="#f5f3ee" text-anchor="middle" letter-spacing="-1">K2</text> | ||||
| 6 | + <polyline points="10,48 21,48 26,41 32,54 37,44 41,48 54,48" fill="none" stroke="#5b9df5" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> | ||||
| 7 | +</svg> | ||||
added
orchestrator/web/favicon-ka4.svg
+7 −0
@@ -0,0 +1,7 @@ | |||||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> | ||||
| 2 | + <!-- KA Guardian ka4 — encre + pastille lime ·Ka + battement (surveillance) --> | ||||
| 3 | + <rect width="64" height="64" rx="14" fill="#141814"/> | ||||
| 4 | + <circle cx="51" cy="13" r="4.5" fill="#d9f26b"/> | ||||
| 5 | + <text x="30" y="36" font-family="'JetBrains Mono','Menlo',ui-monospace,monospace" font-size="26" font-weight="700" fill="#f5f3ee" text-anchor="middle" letter-spacing="-1">K4</text> | ||||
| 6 | + <polyline points="10,48 21,48 26,41 32,54 37,44 41,48 54,48" fill="none" stroke="#ff9f2e" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> | ||||
| 7 | +</svg> | ||||
added
orchestrator/web/favicon-ka6.svg
+7 −0
@@ -0,0 +1,7 @@ | |||||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> | ||||
| 2 | + <!-- KA Guardian ka6 — encre + pastille lime ·Ka + battement (surveillance) --> | ||||
| 3 | + <rect width="64" height="64" rx="14" fill="#141814"/> | ||||
| 4 | + <circle cx="51" cy="13" r="4.5" fill="#d9f26b"/> | ||||
| 5 | + <text x="30" y="36" font-family="'JetBrains Mono','Menlo',ui-monospace,monospace" font-size="26" font-weight="700" fill="#f5f3ee" text-anchor="middle" letter-spacing="-1">K6</text> | ||||
| 6 | + <polyline points="10,48 21,48 26,41 32,54 37,44 41,48 54,48" fill="none" stroke="#a78bfa" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/> | ||||
| 7 | +</svg> | ||||
modified
orchestrator/web/index.html
+2 −0
@@ -5,6 +5,8 @@ | |||||
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> | 5 | <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> | ||
| 6 | <title>Guardian — Groupe KA</title> | 6 | <title>Guardian — Groupe KA</title> | ||
| 7 | <meta name="description" content="Agent gardien autonome du Groupe KA : il détecte les connecteurs en panne, les répare avec Claude, surveille la guérison et revient en arrière si ça empire. Tout est public, en direct."> | 7 | <meta name="description" content="Agent gardien autonome du Groupe KA : il détecte les connecteurs en panne, les répare avec Claude, surveille la guérison et revient en arrière si ça empire. Tout est public, en direct."> | ||
| 8 | +<link rel="icon" type="image/svg+xml" href="/favicon.svg"> | ||||
| 9 | +<link rel="apple-touch-icon" href="/favicon.svg"> | ||||
| 8 | <link rel="preconnect" href="https://fonts.googleapis.com"> | 10 | <link rel="preconnect" href="https://fonts.googleapis.com"> | ||
| 9 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | 11 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
| 10 | <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet"> | 12 | <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet"> | ||
modified
topology.json
+12 −9
@@ -6,34 +6,36 @@ | |||||
| 6 | "ka2": { | 6 | "ka2": { | ||
| 7 | "port": 8799, | 7 | "port": 8799, | ||
| 8 | "domain": "www.ka2.bot", | 8 | "domain": "www.ka2.bot", | ||
| 9 | − "accent": "#22d3ee", | 9 | + "accent": "#a9d1f7", | ||
| 10 | − "accent2": "#0891b2", | 10 | + "accent2": "#1e4fa3", | ||
| 11 | "tagline": "Gardien immobilier & local", | 11 | "tagline": "Gardien immobilier & local", | ||
| 12 | "model": "claude-fable-5", | 12 | "model": "claude-fable-5", | ||
| 13 | "services": [ | 13 | "services": [ | ||
| 14 | "louka", | 14 | "louka", | ||
| 15 | "immoka", | 15 | "immoka", | ||
| 16 | "restoka" | 16 | "restoka" | ||
| 17 | − ] | 17 | + ], | ||
| 18 | + "accent_soft": "#e3effc" | ||||
| 18 | }, | 19 | }, | ||
| 19 | "ka4": { | 20 | "ka4": { | ||
| 20 | "port": 8899, | 21 | "port": 8899, | ||
| 21 | "domain": "www.ka4.bot", | 22 | "domain": "www.ka4.bot", | ||
| 22 | − "accent": "#fbbf24", | 23 | + "accent": "#ffc36b", | ||
| 23 | − "accent2": "#d97706", | 24 | + "accent2": "#a35c00", | ||
| 24 | "tagline": "Gardien mobilité & quotidien", | 25 | "tagline": "Gardien mobilité & quotidien", | ||
| 25 | "model": "claude-fable-5", | 26 | "model": "claude-fable-5", | ||
| 26 | "services": [ | 27 | "services": [ | ||
| 27 | "autoka", | 28 | "autoka", | ||
| 28 | "foodka", | 29 | "foodka", | ||
| 29 | "sortika" | 30 | "sortika" | ||
| 30 | − ] | 31 | + ], | ||
| 32 | + "accent_soft": "#ffefd9" | ||||
| 31 | }, | 33 | }, | ||
| 32 | "ka6": { | 34 | "ka6": { | ||
| 33 | "port": 8999, | 35 | "port": 8999, | ||
| 34 | "domain": "www.ka6.bot", | 36 | "domain": "www.ka6.bot", | ||
| 35 | − "accent": "#a78bfa", | 37 | + "accent": "#cdb4f9", | ||
| 36 | − "accent2": "#7c3aed", | 38 | + "accent2": "#5b21b6", | ||
| 37 | "tagline": "Gardien flagship — gros volumes", | 39 | "tagline": "Gardien flagship — gros volumes", | ||
| 38 | "model": "claude-fable-5", | 40 | "model": "claude-fable-5", | ||
| 39 | "services": [ | 41 | "services": [ | ||
@@ -41,7 +43,8 @@ | |||||
| 41 | "jobka", | 43 | "jobka", | ||
| 42 | "creaka" | 44 | "creaka" | ||
| 43 | ], | 45 | ], | ||
| 44 | − "default_for_unknown_services": true | 46 | + "default_for_unknown_services": true, | ||
| 47 | + "accent_soft": "#f0e8fc" | ||||
| 45 | } | 48 | } | ||
| 46 | }, | 49 | }, | ||
| 47 | "nodes": { | 50 | "nodes": { | ||
| 48 | 51 | ||||