shadok-ai 0.2.32 → 0.2.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/index.html +24 -10
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>shadok-ai — cockpit</title>
|
|
7
|
-
<link rel="icon" id="favicon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%2314161d'/%3E%3Ctext x='
|
|
7
|
+
<link rel="icon" id="favicon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%2314161d'/%3E%3Ctext x='16' y='25' font-family='monospace' font-size='26' font-weight='700' fill='%23f0a848' text-anchor='middle'%3E%E2%80%BA%3C/text%3E%3C/svg%3E">
|
|
8
8
|
<style>
|
|
9
9
|
:root {
|
|
10
10
|
--bg: #14161d;
|
|
@@ -2486,22 +2486,25 @@
|
|
|
2486
2486
|
const favicon = $("favicon");
|
|
2487
2487
|
let titleBase = BASE_TITLE; // current title without the notification badge
|
|
2488
2488
|
/** SVG data-URI favicon: the base mark, plus a coloured corner pip if given. */
|
|
2489
|
-
|
|
2490
|
-
|
|
2489
|
+
/** L'indicateur remplit TOUT le favicon : au repos, fond sombre + chevron
|
|
2490
|
+
* ambre ; pour un état (rouge = à faire, ambre = à lire) tout le carré prend
|
|
2491
|
+
* la couleur, chevron sombre par-dessus. Bien plus visible qu'une pastille. */
|
|
2492
|
+
function faviconSVG(bg) {
|
|
2491
2493
|
const svg =
|
|
2492
2494
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">` +
|
|
2493
|
-
`<rect width="32" height="32" rx="7" fill="#14161d"/>` +
|
|
2494
|
-
`<text x="
|
|
2495
|
-
|
|
2495
|
+
`<rect width="32" height="32" rx="7" fill="${bg || "#14161d"}"/>` +
|
|
2496
|
+
`<text x="16" y="25" font-family="monospace" font-size="26" font-weight="700" fill="${bg ? "#14161d" : "#f0a848"}" text-anchor="middle">›</text>` +
|
|
2497
|
+
`</svg>`;
|
|
2496
2498
|
return "data:image/svg+xml," + encodeURIComponent(svg);
|
|
2497
2499
|
}
|
|
2498
|
-
/** Favicon « en train de bosser » :
|
|
2500
|
+
/** Favicon « en train de bosser » : un GROS spinner centré qui remplit le
|
|
2501
|
+
* favicon (piste faible + arc ambre qui tourne). */
|
|
2499
2502
|
function faviconWorkingSVG(angle) {
|
|
2500
2503
|
const svg =
|
|
2501
2504
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">` +
|
|
2502
2505
|
`<rect width="32" height="32" rx="7" fill="#14161d"/>` +
|
|
2503
|
-
`<
|
|
2504
|
-
`<g transform="rotate(${angle}
|
|
2506
|
+
`<circle cx="16" cy="16" r="11" fill="none" stroke="rgba(240,168,72,0.22)" stroke-width="4"/>` +
|
|
2507
|
+
`<g transform="rotate(${angle} 16 16)"><circle cx="16" cy="16" r="11" fill="none" stroke="#f0a848" stroke-width="4" stroke-linecap="round" stroke-dasharray="34 100"/></g>` +
|
|
2505
2508
|
`</svg>`;
|
|
2506
2509
|
return "data:image/svg+xml," + encodeURIComponent(svg);
|
|
2507
2510
|
}
|
|
@@ -3589,6 +3592,11 @@
|
|
|
3589
3592
|
setTabState(t, "busy", "responding…");
|
|
3590
3593
|
clearLivePreview(t);
|
|
3591
3594
|
t.finalizedNorms = [];
|
|
3595
|
+
// Aucun texte visible produit pour l'instant ce tour. Sert au turn-done à
|
|
3596
|
+
// décider s'il y a vraiment « à lire » : un tour qui ne sort que
|
|
3597
|
+
// NOTHING TO SHOW (filtré par le tail → aucun stream-text) ne doit pas
|
|
3598
|
+
// marquer le canal comme non-lu.
|
|
3599
|
+
t.turnHadText = false;
|
|
3592
3600
|
break;
|
|
3593
3601
|
case "prompt-echo":
|
|
3594
3602
|
// Prompt sent by another tab/interface — or by the server itself
|
|
@@ -3625,6 +3633,9 @@
|
|
|
3625
3633
|
if (fin) (t.finalizedNorms ||= []).push(fin);
|
|
3626
3634
|
}
|
|
3627
3635
|
clearLivePreview(t);
|
|
3636
|
+
// Du texte visible est arrivé (NOTHING TO SHOW est filtré par le tail
|
|
3637
|
+
// avant d'arriver ici) → il y a vraiment quelque chose à lire.
|
|
3638
|
+
t.turnHadText = true;
|
|
3628
3639
|
// Repli sur l'heure locale si le serveur n'a pas envoyé `at` (transcript
|
|
3629
3640
|
// sans timestamp) : un bloc en direct vient d'être écrit, l'écart est nul.
|
|
3630
3641
|
addTurn(t, "claude", "claude", msg.text, "live", msg.at ?? Date.now());
|
|
@@ -3648,7 +3659,10 @@
|
|
|
3648
3659
|
persistChannels();
|
|
3649
3660
|
}
|
|
3650
3661
|
stopTurnTimer(t);
|
|
3651
|
-
|
|
3662
|
+
// « unread » seulement si le tour a produit du texte visible. Un tour
|
|
3663
|
+
// vide (ex. cron qui conclut NOTHING TO SHOW) ne réclame aucune lecture,
|
|
3664
|
+
// ni sur l'onglet ni sur le favicon.
|
|
3665
|
+
setTabMood(t, (t === active || !t.turnHadText) ? null : "unread");
|
|
3652
3666
|
setTabState(t, "ready", "ready");
|
|
3653
3667
|
break;
|
|
3654
3668
|
case "dialog":
|