@imenam/mcp-messenger 1.0.13 → 1.0.14

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 CHANGED
@@ -345,7 +345,13 @@ correspondants et l'état de lecture :
345
345
  chevron sur ses boîtes ; une boîte que son agent n'a pas nommée s'affiche à son adresse,
346
346
  la seule chose qui la distingue alors de ses sœurs. Cliquer l'agent filtre les fils sur
347
347
  **toutes ses sessions**, cliquer une boîte sur **cette seule session**. La colonne se
348
- replie sur les seuls avatars d'agents quand la place manque ;
348
+ replie sur les seuls avatars d'agents quand la place manque.
349
+
350
+ **Le classement se fait sur la dernière activité, la plus récente en tête** — les
351
+ sessions au sein d'un agent comme les agents entre eux, un agent héritant de l'activité
352
+ de sa session la plus vivante. Chaque boîte affiche donc la date qui la classe ; celles
353
+ qui n'ont jamais rien fait ferment la marche, et deux dates identiques sont départagées
354
+ par l'adresse pour que l'ordre ne bouge pas d'un rafraîchissement à l'autre ;
349
355
  - **la liste des fils**, du plus récemment actif au plus ancien, chacun résumé par son
350
356
  nom, ses correspondants, son dernier message et sa priorité la plus haute. Trois puces
351
357
  la filtrent : tous, non lus, priorité haute ;
@@ -287,13 +287,42 @@ function groupByAgent(boxes) {
287
287
  for (const box of boxes) {
288
288
  const key = box.agent_name || box.id;
289
289
  if (!groups.has(key)) {
290
- groups.set(key, { key, name: box.agent_name || boxLabel(box), boxes: [], unread: 0 });
290
+ groups.set(key, { key, name: box.agent_name || boxLabel(box), boxes: [], unread: 0, activity: "" });
291
291
  }
292
292
  const group = groups.get(key);
293
293
  group.boxes.push(box);
294
294
  group.unread += box.unread;
295
+ // L'agent hérite de l'activité de sa session la plus vivante.
296
+ if (activityOf(box) > group.activity) group.activity = activityOf(box);
295
297
  }
296
- return [...groups.values()];
298
+ const list = [...groups.values()];
299
+ for (const group of list) group.boxes.sort(byActivity);
300
+ // Le classement est refait ici plutôt que laissé à l'ordre d'arrivée de l'annuaire :
301
+ // ce que la colonne promet — le plus récent en tête — ne doit pas dépendre du hasard
302
+ // d'un tri fait ailleurs.
303
+ list.sort((a, b) => compareActivity(a.activity, b.activity) || (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
304
+ return list;
305
+ }
306
+
307
+ /** Dernière activité d'une boîte, ou chaîne vide quand elle n'a jamais rien fait. */
308
+ function activityOf(box) {
309
+ return box.last_activity_at || "";
310
+ }
311
+
312
+ /**
313
+ * Compare deux dates ISO, la plus récente d'abord.
314
+ *
315
+ * Les dates ISO se comparent comme du texte, et la chaîne vide — une boîte qui n'a jamais
316
+ * vécu — est plus petite que toute date : elle finit donc en queue, sans cas particulier.
317
+ */
318
+ function compareActivity(left, right) {
319
+ if (left === right) return 0;
320
+ return left < right ? 1 : -1;
321
+ }
322
+
323
+ /** À activité égale, l'adresse départage : deux rendus donnent le même ordre. */
324
+ function byActivity(a, b) {
325
+ return compareActivity(activityOf(a), activityOf(b)) || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
297
326
  }
298
327
 
299
328
  function isSelected(kind, key) {
@@ -425,17 +454,20 @@ function boxRow(box) {
425
454
  const name = node("div", "agent-name", label);
426
455
  if (!box.display_name) name.classList.add("mono", "is-absent");
427
456
  text.appendChild(name);
428
- text.appendChild(
429
- node(
430
- "div",
431
- "agent-box",
432
- box.registered ? `${plural(box.sent, "envoyé")} · ${plural(box.received, "reçu")}` : "jamais connectée"
433
- )
434
- );
457
+ // Les sessions d'un agent sont classées sur cette date : sans elle, leur ordre
458
+ // paraîtrait arbitraire. Les compteurs passent dans l'info-bulle, faute de place.
459
+ const activity = box.last_activity_at
460
+ ? `activité ${formatShort(box.last_activity_at)}`
461
+ : box.registered
462
+ ? "aucune activité"
463
+ : "jamais connectée";
464
+ const meta = node("div", "agent-box", activity);
465
+ if (!box.last_activity_at) meta.classList.add("is-absent");
466
+ text.appendChild(meta);
435
467
  row.appendChild(text);
436
468
 
437
469
  if (box.unread > 0) row.appendChild(node("span", "count count--accent", String(box.unread)));
438
- row.title = box.id;
470
+ row.title = `${box.id}\n${plural(box.sent, "envoyé")} · ${plural(box.received, "reçu")}`;
439
471
  row.addEventListener("click", () => select("box", box.id));
440
472
  item.appendChild(row);
441
473
  return item;
@@ -1 +1 @@
1
- export declare const APP_VERSION = "1.0.13";
1
+ export declare const APP_VERSION = "1.0.14";
@@ -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.13";
2
+ export const APP_VERSION = "1.0.14";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/mcp-messenger",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "main": "dist/src/index.js",
5
5
  "scripts": {
6
6
  "test": "npm run build && vitest run",