@imenam/mcp-messenger 1.0.31 → 1.0.32

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
@@ -567,16 +567,23 @@ n'ont rien à échanger : chacun reçoit la liaison, avec la boîte d'en face et
567
567
  - **Une colonne par agent**, celle dont la dernière boîte est la plus récente à gauche. Son
568
568
  en-tête dit depuis quand cette dernière boîte existe (« dernière : il y a 38 s »).
569
569
  - **En hauteur, l'heure exacte de création**, la plus récente en haut, sous la ligne
570
- « maintenant ». Les **cinq dernières minutes** sont agrandies, une graduation par minute ;
571
- le reste de la fenêtre détaillée est resserré. Chaque boîte porte son **rang de
570
+ « maintenant ». L'**échelle est régulière** sur toute la fenêtre détaillée, avec six
571
+ graduations au plus, chacune à son heure. Chaque boîte porte son **rang de
572
572
  création** (#1 = la plus récente), son heure à la seconde et son âge : deux boîtes ouvertes
573
573
  dans la même minute se distinguent sans hésitation.
574
574
  - **La fenêtre détaillée se règle** (« Détail sur », de 5 minutes à 4 heures, 30 minutes par
575
575
  défaut) ; le navigateur retient le choix. Au-delà, les boîtes sont **empilées en liste** sous
576
576
  leur agent, de la plus récente à la plus ancienne.
577
577
  - **Lier deux boîtes** : tirer la poignée d'une boîte jusqu'à une autre, ou choisir une boîte
578
- puis cliquer **Lier** sur un candidat du volet de droite. Le volet classe les candidats par
579
- rang, puis les boîtes plus anciennes ; un motif facultatif accompagne la liaison.
578
+ puis cliquer **Lier** sur un candidat du volet de droite. Les boîtes empilées ont aussi leur
579
+ poignée, au survol, et reçoivent le fil comme les autres ; pendant le glissé, la boîte
580
+ survolée est mise en avant et « + N autres » se déplie après un court survol. Le volet
581
+ classe les candidats par rang, puis les boîtes plus anciennes ; un motif facultatif
582
+ accompagne la liaison.
583
+ - **Renommer une boîte** : le crayon qui apparaît au survol, ou deux clics rapprochés sur la
584
+ boîte, changent son nom en champ de saisie — récente ou empilée. Entrée ou un clic ailleurs
585
+ enregistre, Échap annule, un champ vidé efface le nom. Ce nom remplace celui que l'agent a
586
+ pu poser avec `rename_mailbox`, et l'agent le lit à son prochain `whoami`.
580
587
  - **Le volet montre l'état de chaque liaison** : « reçue par … » dès que l'agent en a pris
581
588
  connaissance (`whoami`, `list_links`, `list_agents`), « en attente : … » sinon. Une liaison
582
589
  se supprime en deux clics.
@@ -659,6 +666,7 @@ la console (cookie), qui elle n'ouvre rien d'autre.
659
666
  | `GET` | `/admin/mailboxes/empty` | Boîtes par lesquelles rien n'est jamais passé, sans critère de date |
660
667
  | `POST` | `/admin/mailboxes/purge` | Supprime les boîtes nommées (`mailboxes`, plus exactement un critère : `before`, `created_before` **ou** `empty: true`) — refusé si l'une d'elles ne répond plus au critère |
661
668
  | `DELETE` | `/admin/mailboxes/:id` | Supprime une boîte désignée, quel que soit son état — 404 si l'adresse est inconnue |
669
+ | `PATCH` | `/admin/mailboxes/:id` | Renomme une boîte (`display_name` ; vide ou `null` efface le nom) — 404 si l'adresse est inconnue |
662
670
  | `GET` | `/admin/links` | Toutes les liaisons, la plus récente en tête, avec la date de réception par chaque boîte |
663
671
  | `POST` | `/admin/links` | Lie deux boîtes (`mailboxes: [a, b]`, `note?`) — 404 si l'une est inconnue, 409 si elles sont déjà liées |
664
672
  | `DELETE` | `/admin/links/:id` | Supprime une liaison |
@@ -51,6 +51,11 @@ export declare class MessageStore extends EventEmitter<StoreEvents> {
51
51
  * de l'agent sans toucher au nom de la boîte, et `rename_mailbox` fait l'inverse.
52
52
  */
53
53
  ensureAgent(id: string, opts?: EnsureAgentOptions): Agent;
54
+ /**
55
+ * Nomme une boîte depuis la console. Le nom remplace celui en place, quel qu'en soit
56
+ * l'auteur ; null l'efface. La boîte doit exister, et sa date de passage ne bouge pas.
57
+ */
58
+ setMailboxName(id: string, name: string | null): Agent;
54
59
  touchAgent(id: string): void;
55
60
  getAgent(id: string): Agent | null;
56
61
  /**
@@ -205,6 +205,16 @@ export class MessageStore extends EventEmitter {
205
205
  }
206
206
  return this.getAgent(id);
207
207
  }
208
+ /**
209
+ * Nomme une boîte depuis la console. Le nom remplace celui en place, quel qu'en soit
210
+ * l'auteur ; null l'efface. La boîte doit exister, et sa date de passage ne bouge pas.
211
+ */
212
+ setMailboxName(id, name) {
213
+ const result = this.db.prepare("UPDATE agents SET display_name = ? WHERE id = ?").run(name, id);
214
+ if (result.changes === 0)
215
+ throw new MessengerError(`mailbox not found: ${id}`, 404);
216
+ return this.getAgent(id);
217
+ }
208
218
  touchAgent(id) {
209
219
  this.db.prepare("UPDATE agents SET last_seen_at = ? WHERE id = ?").run(new Date().toISOString(), id);
210
220
  }
@@ -11,7 +11,7 @@ export type DeliveryRole = (typeof DELIVERY_ROLES)[number];
11
11
  * - l'agent (`agent_name`, `agent_description`) : d'où il vient, typiquement le projet.
12
12
  * Posé par la configuration à l'enregistrement, stable pour toute la vie de la boîte.
13
13
  * - la boîte (`display_name`, `description`) : de quoi cette session s'occupe. Vide au
14
- * départ, posé par l'agent lui-même (`rename_mailbox`), et libre de changer.
14
+ * départ, posé par l'agent (`rename_mailbox`) ou depuis la console, et libre de changer.
15
15
  * Le nom de l'agent seul ne distingue pas deux sessions du même projet ; le nom de la boîte
16
16
  * seul ne dit pas où l'agent travaille. La console et l'annuaire montrent les deux.
17
17
  */
@@ -133,6 +133,10 @@ const purgeSchema = z
133
133
  .refine((input) => [input.before, input.created_before, input.empty].filter((value) => value !== undefined).length === 1, {
134
134
  message: "provide exactly one of `before` (inactive since that date), `created_before` (created before that date) or `empty: true`",
135
135
  });
136
+ /** Nom donné à une boîte depuis la console : une chaîne vide l'efface. */
137
+ const mailboxNameSchema = z.object({
138
+ display_name: z.string().trim().max(200).nullable(),
139
+ });
136
140
  const linkSchema = z.object({
137
141
  mailboxes: z.tuple([agentIdSchema, agentIdSchema]),
138
142
  note: z.string().trim().max(500).nullish(),
@@ -335,6 +339,14 @@ export function createApp({ store, config }) {
335
339
  logger.warn(`admin delete: mailbox ${id} deleted (${removed.messages} message(s) erased)`);
336
340
  res.json({ mailbox: id, ...removed });
337
341
  });
342
+ /** Renomme une boîte. Le nom remplace celui que l'agent a pu poser avec `rename_mailbox`. */
343
+ admin.patch("/mailboxes/:id", (req, res) => {
344
+ const id = normalizeAgentId(String(req.params.id));
345
+ const input = mailboxNameSchema.parse(req.body ?? {});
346
+ const agent = store.setMailboxName(id, input.display_name || null);
347
+ logger.info(`admin rename: mailbox ${id} -> ${agent.display_name ?? "(no name)"}`);
348
+ res.json({ agent });
349
+ });
338
350
  admin.get("/links", (_req, res) => {
339
351
  res.json({ links: store.listLinks() });
340
352
  });