@imenam/mcp-messenger 1.0.18 → 1.0.20
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/README.md +46 -21
- package/dist/src/core/store.d.ts +11 -0
- package/dist/src/core/store.js +21 -0
- package/dist/src/server/app.js +50 -13
- package/dist/src/server/ui/app.js +1444 -1172
- package/dist/src/server/ui/index.html +48 -6
- package/dist/src/server/ui/styles.css +172 -6
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<dialog class="modal" id="purge">
|
|
62
62
|
<div class="modal-card">
|
|
63
63
|
<div class="modal-head">
|
|
64
|
-
<h2>
|
|
64
|
+
<h2>Nettoyer les boîtes</h2>
|
|
65
65
|
<button type="button" class="btn btn--icon btn--ghost" id="purge-close" aria-label="Fermer">
|
|
66
66
|
<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
|
|
67
67
|
<path d="M18 6 6 18" />
|
|
@@ -70,16 +70,26 @@
|
|
|
70
70
|
</button>
|
|
71
71
|
</div>
|
|
72
72
|
<p class="modal-sub">
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
intact.
|
|
73
|
+
Deux nettoyages, deux critères. La suppression est définitive dans les deux cas, et emporte les messages que
|
|
74
|
+
plus personne ne pourrait lire ; ce que le correspondant a reçu de son côté reste intact. Un agent dont toutes
|
|
75
|
+
les boîtes disparaissent quitte l'annuaire avec elles.
|
|
77
76
|
</p>
|
|
78
77
|
|
|
78
|
+
<!-- Premier critère : la boîte n'a jamais servi. Il ne dépend d'aucune date. -->
|
|
79
|
+
<div class="purge-controls">
|
|
80
|
+
<div class="purge-criterion">
|
|
81
|
+
<span class="field-label">Boîtes vides</span>
|
|
82
|
+
<span class="purge-hint">Rien n'y est jamais passé, ni envoi ni réception, quel que soit leur âge.</span>
|
|
83
|
+
</div>
|
|
84
|
+
<button type="button" class="btn" id="purge-preview-empty">Prévisualiser</button>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Second critère : la boîte a servi, mais plus rien ne l'a touchée depuis. -->
|
|
79
88
|
<div class="purge-controls">
|
|
80
89
|
<label class="field">
|
|
81
|
-
<span class="field-label">
|
|
90
|
+
<span class="field-label">Boîtes sans activité depuis le</span>
|
|
82
91
|
<span class="field-input"><input type="date" id="purge-before" /></span>
|
|
92
|
+
<span class="purge-hint">Ni connexion, ni message. Une boîte créée après cette date est épargnée.</span>
|
|
83
93
|
</label>
|
|
84
94
|
<button type="button" class="btn" id="purge-preview">Prévisualiser</button>
|
|
85
95
|
</div>
|
|
@@ -143,6 +153,19 @@
|
|
|
143
153
|
<p class="agents-foot muted" id="agents-foot"></p>
|
|
144
154
|
</aside>
|
|
145
155
|
|
|
156
|
+
<!--
|
|
157
|
+
Séparateurs déplaçables. Chacun redimensionne le panneau qu'il borde, à la souris
|
|
158
|
+
comme aux flèches du clavier ; un double-clic rend sa largeur d'origine.
|
|
159
|
+
-->
|
|
160
|
+
<div
|
|
161
|
+
class="resizer"
|
|
162
|
+
id="resize-agents"
|
|
163
|
+
role="separator"
|
|
164
|
+
aria-orientation="vertical"
|
|
165
|
+
aria-label="Largeur de la colonne des agents"
|
|
166
|
+
tabindex="0"
|
|
167
|
+
></div>
|
|
168
|
+
|
|
146
169
|
<section class="threads">
|
|
147
170
|
<div class="threads-head">
|
|
148
171
|
<h2>Fils</h2>
|
|
@@ -156,8 +179,27 @@
|
|
|
156
179
|
<ul class="thread-list" id="threads"></ul>
|
|
157
180
|
</section>
|
|
158
181
|
|
|
182
|
+
<div
|
|
183
|
+
class="resizer"
|
|
184
|
+
id="resize-threads"
|
|
185
|
+
role="separator"
|
|
186
|
+
aria-orientation="vertical"
|
|
187
|
+
aria-label="Largeur de la liste des fils"
|
|
188
|
+
tabindex="0"
|
|
189
|
+
></div>
|
|
190
|
+
|
|
159
191
|
<section class="reader" id="reader"></section>
|
|
160
192
|
|
|
193
|
+
<!-- Suit le volet de détail : il n'existe que lorsque le volet est ouvert. -->
|
|
194
|
+
<div
|
|
195
|
+
class="resizer resizer--sheet"
|
|
196
|
+
id="resize-sheet"
|
|
197
|
+
role="separator"
|
|
198
|
+
aria-orientation="vertical"
|
|
199
|
+
aria-label="Largeur du volet de détail"
|
|
200
|
+
tabindex="0"
|
|
201
|
+
></div>
|
|
202
|
+
|
|
161
203
|
<aside class="sheet" id="sheet" hidden></aside>
|
|
162
204
|
</main>
|
|
163
205
|
|
|
@@ -335,15 +335,29 @@ body {
|
|
|
335
335
|
color: var(--muted);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
+
/* Un critère par ligne, son bouton au bout : les deux nettoyages se lisent en parallèle. */
|
|
338
339
|
.purge-controls {
|
|
339
340
|
display: flex;
|
|
340
341
|
align-items: flex-end;
|
|
341
342
|
gap: 12px;
|
|
343
|
+
padding: 12px 0;
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
.purge-controls .
|
|
346
|
+
.purge-controls + .purge-controls {
|
|
347
|
+
border-top: 1px solid var(--border-soft);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.purge-controls .field,
|
|
351
|
+
.purge-criterion {
|
|
345
352
|
margin: 0;
|
|
346
353
|
flex: 1;
|
|
354
|
+
display: grid;
|
|
355
|
+
gap: 4px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.purge-hint {
|
|
359
|
+
font-size: 12px;
|
|
360
|
+
color: var(--muted);
|
|
347
361
|
}
|
|
348
362
|
|
|
349
363
|
.purge-result {
|
|
@@ -532,22 +546,80 @@ body {
|
|
|
532
546
|
|
|
533
547
|
/* --- Console -------------------------------------------------------------- */
|
|
534
548
|
|
|
549
|
+
/*
|
|
550
|
+
Largeurs des panneaux. Ce sont des variables parce qu'elles se déplacent : les
|
|
551
|
+
séparateurs les réécrivent au glissé, et le navigateur les retient d'une visite à
|
|
552
|
+
l'autre. La colonne du lecteur prend ce qui reste, elle n'a donc pas de variable.
|
|
553
|
+
*/
|
|
535
554
|
.console {
|
|
555
|
+
--w-agents: 240px;
|
|
556
|
+
--w-threads: 400px;
|
|
557
|
+
--w-sheet: 360px;
|
|
558
|
+
--w-gutter: 5px;
|
|
536
559
|
display: grid;
|
|
537
|
-
grid-template-columns:
|
|
560
|
+
grid-template-columns: var(--w-agents) var(--w-gutter) var(--w-threads) var(--w-gutter) minmax(0, 1fr);
|
|
538
561
|
height: calc(100vh - var(--topbar-h));
|
|
539
562
|
}
|
|
540
563
|
|
|
541
564
|
.console.has-sheet {
|
|
542
|
-
grid-template-columns:
|
|
565
|
+
grid-template-columns:
|
|
566
|
+
var(--w-agents) var(--w-gutter) var(--w-threads) var(--w-gutter)
|
|
567
|
+
minmax(0, 1fr) var(--w-gutter) var(--w-sheet);
|
|
543
568
|
}
|
|
544
569
|
|
|
545
570
|
.console.is-collapsed {
|
|
546
|
-
grid-template-columns: 57px
|
|
571
|
+
grid-template-columns: 57px var(--w-gutter) var(--w-threads) var(--w-gutter) minmax(0, 1fr);
|
|
547
572
|
}
|
|
548
573
|
|
|
549
574
|
.console.is-collapsed.has-sheet {
|
|
550
|
-
grid-template-columns:
|
|
575
|
+
grid-template-columns:
|
|
576
|
+
57px var(--w-gutter) var(--w-threads) var(--w-gutter)
|
|
577
|
+
minmax(0, 1fr) var(--w-gutter) var(--w-sheet);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* --- Séparateurs déplaçables ---------------------------------------------- */
|
|
581
|
+
|
|
582
|
+
.resizer {
|
|
583
|
+
cursor: col-resize;
|
|
584
|
+
background: none;
|
|
585
|
+
/* La zone saisissable déborde du trait : viser 5 pixels à la souris est pénible. */
|
|
586
|
+
border-left: 4px solid transparent;
|
|
587
|
+
border-right: 4px solid transparent;
|
|
588
|
+
background-clip: padding-box;
|
|
589
|
+
margin: 0 -4px;
|
|
590
|
+
z-index: 1;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.resizer:hover,
|
|
594
|
+
.resizer:focus-visible,
|
|
595
|
+
.resizer.is-active {
|
|
596
|
+
background-color: var(--accent);
|
|
597
|
+
background-clip: padding-box;
|
|
598
|
+
outline: none;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/* Le volet de détail n'est pas toujours là ; son séparateur non plus. */
|
|
602
|
+
.console:not(.has-sheet) .resizer--sheet {
|
|
603
|
+
display: none;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* Colonne repliée : il n'y a plus de largeur à régler, seulement un rail d'avatars. */
|
|
607
|
+
.console.is-collapsed #resize-agents {
|
|
608
|
+
cursor: default;
|
|
609
|
+
pointer-events: none;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/* Pendant le glissé, rien d'autre ne doit réagir : ni sélection de texte, ni survol. */
|
|
613
|
+
.console.is-resizing {
|
|
614
|
+
cursor: col-resize;
|
|
615
|
+
user-select: none;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.console.is-resizing .agents,
|
|
619
|
+
.console.is-resizing .threads,
|
|
620
|
+
.console.is-resizing .reader,
|
|
621
|
+
.console.is-resizing .sheet {
|
|
622
|
+
pointer-events: none;
|
|
551
623
|
}
|
|
552
624
|
|
|
553
625
|
/* --- Colonne des agents --------------------------------------------------- */
|
|
@@ -697,6 +769,54 @@ body {
|
|
|
697
769
|
padding: 7px 10px;
|
|
698
770
|
}
|
|
699
771
|
|
|
772
|
+
/* La ligne d'une boîte et son bouton de suppression, côte à côte. */
|
|
773
|
+
.box-line {
|
|
774
|
+
display: flex;
|
|
775
|
+
align-items: center;
|
|
776
|
+
gap: 2px;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.box-line .box {
|
|
780
|
+
flex: 1;
|
|
781
|
+
min-width: 0;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/*
|
|
785
|
+
Le bouton ne se montre qu'au survol ou au clavier : une corbeille par ligne, affichée en
|
|
786
|
+
permanence, transformerait la colonne en champ de mines. Il reste dans le flux — révélé
|
|
787
|
+
par l'opacité et non par `display` — pour que la ligne ne change pas de largeur.
|
|
788
|
+
*/
|
|
789
|
+
.box-delete {
|
|
790
|
+
display: flex;
|
|
791
|
+
padding: 5px;
|
|
792
|
+
border: 0;
|
|
793
|
+
border-radius: var(--radius);
|
|
794
|
+
background: none;
|
|
795
|
+
color: var(--muted);
|
|
796
|
+
cursor: pointer;
|
|
797
|
+
opacity: 0;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.box-line:hover .box-delete,
|
|
801
|
+
.box-delete:focus-visible {
|
|
802
|
+
opacity: 1;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.box-delete:hover {
|
|
806
|
+
background: var(--danger-soft);
|
|
807
|
+
color: var(--danger);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
.box-delete:focus-visible {
|
|
811
|
+
outline: 2px solid var(--accent);
|
|
812
|
+
outline-offset: -2px;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/* Colonne repliée : il n'y a plus de boîtes affichées, donc rien à supprimer. */
|
|
816
|
+
.is-collapsed .box-delete {
|
|
817
|
+
display: none;
|
|
818
|
+
}
|
|
819
|
+
|
|
700
820
|
.box .agent-name {
|
|
701
821
|
font-weight: 500;
|
|
702
822
|
font-size: 13px;
|
|
@@ -738,6 +858,19 @@ body {
|
|
|
738
858
|
outline-offset: -2px;
|
|
739
859
|
}
|
|
740
860
|
|
|
861
|
+
/* Le même geste un cran plus haut : il se détache donc de la liste des agents. */
|
|
862
|
+
.agents-empty-toggle {
|
|
863
|
+
margin-top: 6px;
|
|
864
|
+
padding-top: 10px;
|
|
865
|
+
border-top: 1px solid var(--border-soft);
|
|
866
|
+
border-radius: 0;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/* Colonne repliée : plus de place pour une phrase, et rien à replier de toute façon. */
|
|
870
|
+
.is-collapsed .agents-empty-toggle {
|
|
871
|
+
display: none;
|
|
872
|
+
}
|
|
873
|
+
|
|
741
874
|
/* Une boîte vide reste lisible mais s'efface : elle est là pour être retrouvée, pas lue. */
|
|
742
875
|
.box.is-empty .agent-name {
|
|
743
876
|
color: var(--muted);
|
|
@@ -1015,15 +1148,48 @@ body {
|
|
|
1015
1148
|
color: var(--accent);
|
|
1016
1149
|
}
|
|
1017
1150
|
|
|
1151
|
+
/* Les pastilles des deux correspondants, puis leurs noms : on voit qui parle avant de lire. */
|
|
1018
1152
|
.thread-who {
|
|
1153
|
+
display: flex;
|
|
1154
|
+
align-items: center;
|
|
1155
|
+
gap: 8px;
|
|
1156
|
+
margin-top: 4px;
|
|
1157
|
+
min-width: 0;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.thread-names {
|
|
1019
1161
|
font-size: 12px;
|
|
1020
1162
|
color: var(--muted);
|
|
1021
|
-
margin-top: 2px;
|
|
1022
1163
|
white-space: nowrap;
|
|
1023
1164
|
overflow: hidden;
|
|
1024
1165
|
text-overflow: ellipsis;
|
|
1025
1166
|
}
|
|
1026
1167
|
|
|
1168
|
+
/* Dans une liste, la pastille sert de repère, pas de portrait : elle est plus petite. */
|
|
1169
|
+
.thread-who .avatar--sm {
|
|
1170
|
+
width: 22px;
|
|
1171
|
+
height: 22px;
|
|
1172
|
+
font-size: 10px;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
/*
|
|
1176
|
+
Ici les pastilles ne se chevauchent pas. Le chevauchement du lecteur dit « ces gens vont
|
|
1177
|
+
ensemble » quand la place manque ; dans une liste qui se survole, il mange les initiales,
|
|
1178
|
+
et ce sont justement elles qui identifient la boîte. L'anneau qui détachait les pastilles
|
|
1179
|
+
superposées n'a alors plus rien à détacher.
|
|
1180
|
+
*/
|
|
1181
|
+
.thread-who .avatar-stack {
|
|
1182
|
+
gap: 4px;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
.thread-who .avatar-stack .avatar + .avatar {
|
|
1186
|
+
margin-left: 0;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
.thread-who .avatar--stack {
|
|
1190
|
+
box-shadow: none;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1027
1193
|
.thread-bottom {
|
|
1028
1194
|
display: flex;
|
|
1029
1195
|
align-items: center;
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const APP_VERSION = "1.0.
|
|
1
|
+
export declare const APP_VERSION = "1.0.20";
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Généré par scripts/generate-version.js — ne pas modifier à la main.
|
|
2
|
-
export const APP_VERSION = "1.0.
|
|
2
|
+
export const APP_VERSION = "1.0.20";
|