bots-garden/mini-mepublic Fork
⑂ feature/unload-model
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 726802e · on feature/unload-model · k33g · 4d ago
slash-commands.md · 185 lines · 17.7 KBmarkdown
Blame HistoryOpen raw

Référence : commandes slash et raccourcis clavier

Description neutre des commandes reconnues à l'invite du terminal de mm. Elles sont comparées à la ligne entière, débarrassée de ses espaces ; tout autre texte est envoyé au modèle.

Commandes

Commande À l'invite Pendant une génération
/quit Quitte le programme. Annule la génération, affiche Goodbye., quitte.
/abort Affiche ⚠️ No generation in progress. Annule la génération, affiche 🛑 Aborting... ; les commandes déjà exécutées restent dans l'historique.
/compact Compresse l'historique immédiatement, sans tenir compte du seuil ; affiche le rapport 🗜️, ou 🗜️ nothing to compact quand aucun tour n'est plus ancien que context.keepLastTurns. Envoyée au modèle comme nouveau message (voir ci-dessous).
/new Ramène l'historique au seul prompt système, réinitialise le détecteur de boucles et oublie le dernier compte de tokens du serveur ; affiche 🆕 new session: N message(s) forgotten (N compte tous les messages sauf le prompt système). Traitée comme n'importe quel texte : annule la génération, conserve son historique partiel, puis s'exécute comme /new sur cet historique.
/sessions Liste les sessions enregistrées du projet, la plus récente d'abord : identifiant, dernière mise à jour, nombre de questions, première question, puis · ⚠️ N error(s) quand la session a enregistré des erreurs ; * marque la session courante. Avec sessions.enabled: false : ⚠️ sessions are off (set sessions.enabled: true in the YAML). Envoyée au modèle comme nouveau message.
/resume [id] Reprend une session enregistrée : la plus récemment mise à jour autre que la courante, en ignorant les vides, ou l'identifiant donné. Affiche ↩️ resumed <id> — N message(s), started with "<première question>" (suivi de · ⚠️ N error(s) quand la session a enregistré des erreurs) ; réinitialise le détecteur de boucles et le compte de tokens du serveur ; les tours suivants sont enregistrés dans cette session. Refusée avec une raison ⚠️ quand les sessions sont désactivées, qu'il n'y a pas de session antérieure, que l'identifiant est inconnu ou désigne la session courante. Envoyée au modèle comme nouveau message.
/help Affiche les commandes de cette façade, une par ligne avec leur description, alignées. Envoyée au modèle comme nouveau message.
/save <fichier> [n] Écrit la dernière réponse (n : la n-ième depuis la fin) telle quelle dans un nouveau fichier, en créant les répertoires manquants, et affiche 💾 saved the last answer to <fichier> (N bytes). N'écrase jamais : un fichier existant donne ⚠️ <fichier> already exists — nothing was written; choose another name. Un nom de fichier avec des espaces n'est pas pris en charge. Le modèle n'est pas appelé. Envoyée au modèle comme nouveau message.
/unload [modèle] Avec unloadModels (activé par défaut) : décharge un modèle de la mémoire du serveur — celui de l'agent, ou celui nommé — et affiche une ligne : 🧹 unloaded <modèle>, 🧹 <modèle> was not loaded: nothing to unload, ou 🧹 cannot unload <modèle>: <raison> (un fournisseur ou un serveur qui n'a aucun moyen de le faire). L'historique n'est pas touché ; la question suivante recharge le modèle de l'agent. Envoyée au modèle comme nouveau message.
/copy [n|all] Copie la dernière réponse (n : la n-ième depuis la fin) dans le presse-papiers via pbcopy/wl-copy/xclip/xsel ou, à défaut, OSC 52 quand stdout est un terminal, et affiche 📋 copied N chars (<chemin>) ou ⚠️ …. /copy all est réservé au mode fenêtre : ici la commande le dit. Envoyée au modèle comme nouveau message.

Avec sessions.enabled, /new laisse le fichier de la session courante tel quel ; la question suivante ouvre un nouveau fichier. Une ligne vide à l'invite est ignorée.

Interroger un autre agent

Présentes seulement quand mmConfigs déclare au moins un agent ; /help et le sélecteur / les listent. <nom> est une clé de mmConfigs.

Commande Façades Effet
/ask-<nom> <prompt> terminal, fenêtre, éditeur Envoie <prompt> seul à <nom>.
/ask-with-context-<nom> <prompt> terminal, fenêtre, éditeur Envoie une transcription de la conversation courante, puis <prompt>.
/ask <nom> <prompt> terminal, fenêtre Comme /ask-<nom> <prompt>.
/ask-with-context <nom> <prompt> terminal, fenêtre Comme /ask-with-context-<nom> <prompt>.

Pendant l'exécution :

Élément Comportement
Première ligne 🗣 asking <nom> (<fournisseur>/<modèle>)…, ou …, with the conversation… pour les formes avec contexte.
Réponse de <nom> Affichée au fil de l'eau là où s'affichent les réponses. Son raisonnement est affiché comme un raisonnement quand showThinking est actif.
Appels d'outils de <nom> Affichés comme des appels d'outils intitulés <nom> · <outil>: <arguments>. Les demandes de permission passent par cette façade : aucune en mode ligne (autorisé), permissions en mode fenêtre (a/s/r, « pour cette session » indexé sur <nom>/<outil>), la boîte de dialogue de l'éditeur en ACP.
/abort, Esc, Ctrl+C, session/cancel Annulent la demande ; 🛑 Ask aborted — nothing kept.
/quit Annule la demande et quitte.
Toute autre ligne (mode ligne) ⚠️ <nom> is still answering — /abort to stop it. ; la ligne est ignorée.

À la fin :

Issue Historique Message
Réponse obtenue Deux messages ajoutés : utilisateur [asked <nom> (<fournisseur>/<modèle>)[, with this conversation as context]: <prompt>], assistant [<nom>'s answer] + la réponse (plafonnée à maxOutput caractères, début et fin conservés). Enregistrés avec la session. 🗣 <nom>'s answer is in the history for your next question
Annulée Inchangé. 🛑 Ask aborted — nothing kept.
Échec Inchangé ; enregistré dans le fichier de session avec where: "ask". [error: …] (terminal, fenêtre) ou une erreur JSON-RPC (éditeur).

La transcription envoyée par les formes avec contexte contient les questions de l'utilisateur, les réponses de l'assistant, une ligne par appel d'outil (Assistant ran <outil>: <arguments>, arguments coupés à 160 caractères) et le résumé de compaction s'il existe ; jamais le prompt système, les sorties d'outils ni le raisonnement. Plafonnée à maxOutput caractères, en gardant les lignes les plus récentes, [… earlier conversation omitted …] marquant la coupure.

Erreur Cause
usage: /ask <agent> <prompt> — agents: … /ask sans nom.
unknown agent "x" — agents: … /ask x … avec un nom absent de mmConfigs.
nothing to ask: type the question after the command Pas de prompt.
<nom>: config file <chemin>: no such file or directory Le fichier de mmConfigs.<nom> n'existe pas.
<nom> did not start: … — <dernière ligne de stderr> Le processus de l'agent s'est arrêté ou n'a pas répondu à initialize en 60 s.
<nom> failed: … Le tour de l'agent s'est terminé sur une erreur (sa propre explication en une ligne).
<nom> gave no answer L'agent a terminé son tour sans aucun texte.
this agent was itself asked through 2 level(s) of /ask; it cannot ask further (max 2) MM_ASK_DEPTH vaut 2.

@chemin dans une question

Saisie Effet
@<chemin> en début de ligne ou après un espace, une parenthèse ou un guillemet Si le chemin existe (relatif au répertoire de lancement, absolu, ou ~/…), une ligne atténuée 📎 <chemin absolu> est affichée et [attached file: <chemin absolu>] (ou [attached directory: …]) est ajouté au message que reçoit le modèle. La ponctuation finale est ignorée ; chaque chemin est attaché une fois.
Un @<chemin> qui ne désigne rien sur le disque, ou @ collé à un mot Laissé tel quel.

Détails et exemples : Désigner un fichier au modèle avec @chemin.

Tout autre texte pendant une génération

Saisie Comportement
Une ligne qui n'est pas une commande Affiche 🔄 New command received. Cancelling current task..., annule la génération en cours, conserve son historique partiel, puis soumet la nouvelle ligne comme question suivante.

Raccourcis clavier

Touche À l'invite Pendant une génération
Ctrl+C Affiche Goodbye. et quitte. Affiche 🛑 Interrupted (Ctrl+C). et annule la génération ; l'invite revient.
Ctrl+D (fin d'entrée) Quitte. —

Touches du mode fenêtre

Dans mm -tui les mêmes commandes existent ; /abort au repos affiche ⚠️ No generation in progress. comme notice, et le sélecteur ouvert par / les liste.

/quit et /abort prennent effet immédiatement, même pendant un tour. Toutes les autres commandes et toutes les questions attendent la fin du tour, parce qu'elles ont besoin de l'historique que le tour est encore en train d'écrire. Voir Sortir d'un tour qui ne s'arrête pas.

Les touches :

Touche Action
Entrée Envoie la zone (rien sur une zone vide). Avec le sélecteur ouvert sur un nom incomplet, le complète à la place.
Ctrl-J, Alt-Entrée Insère un saut de ligne dans la zone.
Échap Annule le tour en cours (comme /abort) ; ferme le sélecteur ; refuse une permission en attente.
Ctrl-C Annule le tour en cours ; quitte au repos — et quitte aussi lorsque le tour a déjà reçu l'ordre de s'arrêter et ne l'a pas fait.
Tab Déplace le focus entre la zone et la conversation ; complète le choix du sélecteur quand il est ouvert (/, @ ou $).
↑ ↓ Dans la zone : passent d'une rangée à l'autre — une ligne longue est repliée aux espaces sur plusieurs rangées — et font défiler la conversation depuis sa première/dernière rangée. Sur la conversation : défilent d'une ligne. Dans le sélecteur : déplacent le choix.
PgUp PgDn Défilent d'une page.
Début Fin Dans la zone : début/fin de ligne. Sur la conversation : haut / bas (le bas reprend le suivi).
Ctrl-L Efface la conversation affichée ; l'historique est conservé.
F1 Comme /help.
F2 Bascule la capture de la souris. Désactivée (défaut) : le cliquer-glisser du terminal sélectionne du texte ; la barre d'état indique F2 mouse: off. Activée : la molette fait défiler, Maj+glisser sélectionne, la barre d'état indique mouse: on (Shift+drag selects).
Ctrl-Y Comme /copy : la dernière réponse dans le presse-papiers.
a s r n Répondent à une permission en attente (yolo: false, ou un outil MCP marqué ask) : autoriser une fois, autoriser cet outil pour la session, refuser cet appel (Échap aussi), ne jamais autoriser cet outil dans cette session.
Molette Fait défiler la conversation — seulement quand la souris est capturée (F2).
Collage encadré Inséré en un bloc ; ses sauts de ligne deviennent des sauts de ligne, jamais un envoi. Au-delà de 3 lignes ou de 200 caractères : replié en un jeton [Pasted #n · L lines · C chars] qui s'édite comme un seul caractère ; Entrée envoie le texte complet, la conversation garde le jeton. Un @chemin dans un collage n'est pas résolu.

Sortir d'un tour qui ne s'arrête pas

Un tour se termine normalement quand on l'annule. Un tour qui ignore l'annulation — un moteur qui ne répond plus, un outil bloqué sur quelque chose qui ne revient jamais — piégeait la fenêtre : /quit et /abort attendaient la fin du tour, donc ne s'exécutaient jamais, et Ctrl-C comprenait « il y a un tour à annuler » comme « donc ne pas quitter ». La seule issue était de tuer mm depuis un autre terminal.

La sortie, dans l'ordre :

Vous faites La fenêtre fait
Échap ou /abort Annule le tour, et affiche 🛑 Aborting….
Échap ou /abort à nouveau Le tour est toujours là : ⚠️ The turn is not answering the cancellation — press Ctrl-C (or /quit) to leave mm.
Ctrl-C Annule, comme ci-dessus.
Ctrl-C à nouveau Quitte mm, tour en cours ou non.
/quit Quitte mm tout de suite, à n'importe quel moment.

Sortir ainsi n'attend pas le travail bloqué : le fichier de session contient tout ce qui a été enregistré jusqu'au dernier tour terminé.

Les trois sélecteurs

Une fenêtre surgissante s'ouvre au-dessus de la conversation dès que vous tapez l'un des trois déclencheurs, et se resserre à mesure que vous tapez. Tab complète la ligne surlignée, ↑/↓ déplacent, Échap la referme jusqu'à ce que le texte change.

Déclencheur Propose Où ça marche Ce que Tab écrit
/ les commandes de la fenêtre seulement comme premier mot entier de la zone — une commande est le message la commande, en remplaçant la zone, avec une espace si elle prend un argument
@ fichiers et dossiers sous le répertoire de travail n'importe où dans une phrase le chemin avec son @ conservé. Un dossier reçoit un / final et pas d'espace, donc Tab à nouveau descend dans l'arbre ; un fichier reçoit une espace, donc la phrase continue
$ les skills du catalogue n'importe où dans une phrase $nom — le $ conservé — plus une espace, curseur après, prêt pour les paramètres du skill

Trois règles gardent la fenêtre à sa place :

  • Un déclencheur collé à la fin d'un mot n'en est pas un : bob@example.com n'ouvre rien, ni 5$.
  • @ masque les fichiers cachés jusqu'à ce que vous tapiez le . vous-même.
  • $ ne propose rien quand aucun skill ne correspond, donc echo $HOME et $PATH sont laissés tranquilles.

Entrée sur un token @ ou $ le complète au lieu d'envoyer : le message n'est pas fini. Entrée sur une commande dont le nom est déjà complet l'envoie.

Ce que fait $nom à l'envoi

$greetings Bob Morane ajoute une ligne à ce que lit le modèle, comme @chemin ajoute une ligne de pièce jointe :

use $greetings Bob Morane
[skill: greetings — load it with read_skill and carry out its steps now; parameters: Bob Morane]

Les paramètres sont le reste de la ligne. C'est toujours le modèle qui fait l'appel read_skill, donc le détecteur de boucle, la demande de permission et le recap 📖 N skill(s) le voient tous — mm ne charge pas le skill dans le dos du modèle.

La notation marche aussi en mode ligne et en ACP, tapée à la main : un $skill veut dire la même chose partout où il est écrit, comme @chemin. Un $nom qui ne correspond à aucun skill est laissé tel quel, et un $ dans un collage replié n'est pas résolu.

Messages affichés en fin de tour

Message Signification
🛑 Generation aborted. Le tour a été annulé (/abort, Ctrl+C). La question et les tours d'outils terminés restent dans l'historique.
[error: …] Le fournisseur a expliqué un échec en une ligne ; une question restée sans réponse est retirée de l'historique.
⚙ N command(s) Nombre de commandes bash réellement exécutées dans le tour.
· 📝 N file op(s) Ajouté quand des outils de fichiers ont tourné.
· 📖 N skill(s) Ajouté quand des skills ont été chargés.
Liste numérotée en vert Les commandes et opérations sur fichiers du tour, une par ligne, quand displayCommands: true.

Mode ACP

Deux commandes existent en mode ACP, trois avec unloadModels (le défaut) : /new, /compact et /unload. Elles sont annoncées à l'éditeur par une notification available_commands_update et interceptées par session/prompt quand le texte du prompt, débarrassé de ses espaces, est exactement la commande (/unload peut être suivie d'un nom de modèle). Chacune répond par un agent_message_chunk portant la ligne que le terminal afficherait, puis stopReason: end_turn ; le modèle n'est pas consulté.

Commande En ACP
/new Comme dans le terminal : historique ramené au prompt système, compte de tokens oublié ; l'identifiant de session, le cwd et les autorisations « toujours autoriser » sont conservés.
/compact Comme dans le terminal, toujours forcée : 🗜️ compressed …, 🗜️ nothing to compact: … ou [compact: failed, history kept: …]. Attend d'abord la fin d'un tour en cours.
/unload [modèle] Avec unloadModels (activé par défaut), annoncée avec l'indication de saisie [model] : comme dans le terminal, la ligne 🧹 comme texte de l'agent ; l'historique n'est pas touché.

Chaque skill y est proposé comme une commande à part entière : ACP n'a pas de sélecteur pour les skills, donc /greetings Bob dans le menu de l'éditeur est l'équivalent de $greetings Bob dans la fenêtre, et il est réécrit en exactement ça — voir la référence ACP.

Avec mmConfigs, /ask-<nom> et /ask-with-context-<nom> sont annoncées aussi, chacune avec l'indication de saisie <prompt> ; le /ask <nom> générique ne l'est pas, car le menu d'un éditeur complète un nom de commande mais pas son argument. Voir Interroger un autre agent.

/quit et /abort n'existent pas en mode ACP : l'éditeur possède le processus et le termine en fermant stdin, et il annule un tour avec sa propre touche d'arrêt via session/cancel. Voir la référence ACP.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Référence : commandes slash et raccourcis clavier

> Description neutre des commandes reconnues à l'invite du terminal de `mm`. Elles sont comparées à la ligne entière, débarrassée de ses espaces ; tout autre texte est envoyé au modèle.

## Commandes

| Commande | À l'invite | Pendant une génération |
|----------|------------|------------------------|
| `/quit` | Quitte le programme. | Annule la génération, affiche `Goodbye.`, quitte. |
| `/abort` | Affiche `⚠️ No generation in progress.` | Annule la génération, affiche `🛑 Aborting...` ; les commandes déjà exécutées restent dans l'historique. |
| `/compact` | Compresse l'historique immédiatement, sans tenir compte du seuil ; affiche le rapport `🗜️`, ou `🗜️ nothing to compact` quand aucun tour n'est plus ancien que `context.keepLastTurns`. | Envoyée au modèle comme nouveau message (voir ci-dessous). |
| `/new` | Ramène l'historique au seul prompt système, réinitialise le détecteur de boucles et oublie le dernier compte de tokens du serveur ; affiche `🆕 new session: N message(s) forgotten` (N compte tous les messages sauf le prompt système). | Traitée comme n'importe quel texte : annule la génération, conserve son historique partiel, puis s'exécute comme `/new` sur cet historique. |
| `/sessions` | Liste les sessions enregistrées du projet, la plus récente d'abord : identifiant, dernière mise à jour, nombre de questions, première question, puis ` · ⚠️ N error(s)` quand la session a enregistré des erreurs ; `*` marque la session courante. Avec `sessions.enabled: false` : `⚠️ sessions are off (set sessions.enabled: true in the YAML)`. | Envoyée au modèle comme nouveau message. |
| `/resume [id]` | Reprend une session enregistrée : la plus récemment mise à jour autre que la courante, en ignorant les vides, ou l'identifiant donné. Affiche `↩️ resumed <id> — N message(s), started with "<première question>"` (suivi de ` · ⚠️ N error(s)` quand la session a enregistré des erreurs) ; réinitialise le détecteur de boucles et le compte de tokens du serveur ; les tours suivants sont enregistrés dans cette session. Refusée avec une raison `⚠️` quand les sessions sont désactivées, qu'il n'y a pas de session antérieure, que l'identifiant est inconnu ou désigne la session courante. | Envoyée au modèle comme nouveau message. |
| `/help` | Affiche les commandes de cette façade, une par ligne avec leur description, alignées. | Envoyée au modèle comme nouveau message. |
| `/save <fichier> [n]` | Écrit la dernière réponse (`n` : la n-ième depuis la fin) telle quelle dans un nouveau fichier, en créant les répertoires manquants, et affiche `💾 saved the last answer to <fichier> (N bytes)`. N'écrase jamais : un fichier existant donne `⚠️ <fichier> already exists — nothing was written; choose another name`. Un nom de fichier avec des espaces n'est pas pris en charge. Le modèle n'est pas appelé. | Envoyée au modèle comme nouveau message. |
| `/unload [modèle]` | Avec `unloadModels` (activé par défaut) : décharge un modèle de la mémoire du serveur — celui de l'agent, ou celui nommé — et affiche une ligne : `🧹 unloaded <modèle>`, `🧹 <modèle> was not loaded: nothing to unload`, ou `🧹 cannot unload <modèle>: <raison>` (un fournisseur ou un serveur qui n'a aucun moyen de le faire). L'historique n'est pas touché ; la question suivante recharge le modèle de l'agent. | Envoyée au modèle comme nouveau message. |
| `/copy [n\|all]` | Copie la dernière réponse (`n` : la n-ième depuis la fin) dans le presse-papiers via `pbcopy`/`wl-copy`/`xclip`/`xsel` ou, à défaut, OSC 52 quand stdout est un terminal, et affiche `📋 copied N chars (<chemin>)` ou `⚠️ …`. `/copy all` est réservé au mode fenêtre : ici la commande le dit. | Envoyée au modèle comme nouveau message. |

Avec `sessions.enabled`, `/new` laisse le fichier de la session courante tel quel ; la question suivante ouvre un nouveau fichier. Une ligne vide à l'invite est ignorée.

## Interroger un autre agent

Présentes seulement quand `mmConfigs` déclare au moins un agent ; `/help` et le sélecteur `/` les listent. `<nom>` est une clé de `mmConfigs`.

| Commande | Façades | Effet |
|----------|---------|-------|
| `/ask-<nom> <prompt>` | terminal, fenêtre, éditeur | Envoie `<prompt>` seul à `<nom>`. |
| `/ask-with-context-<nom> <prompt>` | terminal, fenêtre, éditeur | Envoie une transcription de la conversation courante, puis `<prompt>`. |
| `/ask <nom> <prompt>` | terminal, fenêtre | Comme `/ask-<nom> <prompt>`. |
| `/ask-with-context <nom> <prompt>` | terminal, fenêtre | Comme `/ask-with-context-<nom> <prompt>`. |

Pendant l'exécution :

| Élément | Comportement |
|---------|--------------|
| Première ligne | `🗣 asking <nom> (<fournisseur>/<modèle>)…`, ou `…, with the conversation…` pour les formes avec contexte. |
| Réponse de `<nom>` | Affichée au fil de l'eau là où s'affichent les réponses. Son raisonnement est affiché comme un raisonnement quand `showThinking` est actif. |
| Appels d'outils de `<nom>` | Affichés comme des appels d'outils intitulés `<nom> · <outil>: <arguments>`. Les demandes de permission passent par cette façade : aucune en mode ligne (autorisé), `permissions` en mode fenêtre (`a`/`s`/`r`, « pour cette session » indexé sur `<nom>/<outil>`), la boîte de dialogue de l'éditeur en ACP. |
| `/abort`, `Esc`, `Ctrl+C`, `session/cancel` | Annulent la demande ; `🛑 Ask aborted — nothing kept.` |
| `/quit` | Annule la demande et quitte. |
| Toute autre ligne (mode ligne) | `⚠️ <nom> is still answering — /abort to stop it.` ; la ligne est ignorée. |

À la fin :

| Issue | Historique | Message |
|-------|------------|---------|
| Réponse obtenue | Deux messages ajoutés : utilisateur `[asked <nom> (<fournisseur>/<modèle>)[, with this conversation as context]: <prompt>]`, assistant `[<nom>'s answer]` + la réponse (plafonnée à `maxOutput` caractères, début et fin conservés). Enregistrés avec la session. | `🗣 <nom>'s answer is in the history for your next question` |
| Annulée | Inchangé. | `🛑 Ask aborted — nothing kept.` |
| Échec | Inchangé ; enregistré dans le fichier de session avec `where: "ask"`. | `[error: …]` (terminal, fenêtre) ou une erreur JSON-RPC (éditeur). |

La transcription envoyée par les formes avec contexte contient les questions de l'utilisateur, les réponses de l'assistant, une ligne par appel d'outil (`Assistant ran <outil>: <arguments>`, arguments coupés à 160 caractères) et le résumé de compaction s'il existe ; jamais le prompt système, les sorties d'outils ni le raisonnement. Plafonnée à `maxOutput` caractères, en gardant les lignes les plus récentes, `[… earlier conversation omitted …]` marquant la coupure.

| Erreur | Cause |
|--------|-------|
| `usage: /ask <agent> <prompt> — agents: …` | `/ask` sans nom. |
| `unknown agent "x" — agents: …` | `/ask x …` avec un nom absent de `mmConfigs`. |
| `nothing to ask: type the question after the command` | Pas de prompt. |
| `<nom>: config file <chemin>: no such file or directory` | Le fichier de `mmConfigs.<nom>` n'existe pas. |
| `<nom> did not start: … — <dernière ligne de stderr>` | Le processus de l'agent s'est arrêté ou n'a pas répondu à `initialize` en 60 s. |
| `<nom> failed: …` | Le tour de l'agent s'est terminé sur une erreur (sa propre explication en une ligne). |
| `<nom> gave no answer` | L'agent a terminé son tour sans aucun texte. |
| `this agent was itself asked through 2 level(s) of /ask; it cannot ask further (max 2)` | `MM_ASK_DEPTH` vaut 2. |

## `@chemin` dans une question

| Saisie | Effet |
|--------|-------|
| `@<chemin>` en début de ligne ou après un espace, une parenthèse ou un guillemet | Si le chemin existe (relatif au répertoire de lancement, absolu, ou `~/…`), une ligne atténuée `📎 <chemin absolu>` est affichée et `[attached file: <chemin absolu>]` (ou `[attached directory: …]`) est ajouté au message que reçoit le modèle. La ponctuation finale est ignorée ; chaque chemin est attaché une fois. |
| Un `@<chemin>` qui ne désigne rien sur le disque, ou `@` collé à un mot | Laissé tel quel. |

Détails et exemples : [Désigner un fichier au modèle avec `@chemin`](../how-to/attach-a-file.md).

## Tout autre texte pendant une génération

| Saisie | Comportement |
|--------|--------------|
| Une ligne qui n'est pas une commande | Affiche `🔄 New command received. Cancelling current task...`, annule la génération en cours, conserve son historique partiel, puis soumet la nouvelle ligne comme question suivante. |

## Raccourcis clavier

| Touche | À l'invite | Pendant une génération |
|--------|------------|------------------------|
| `Ctrl+C` | Affiche `Goodbye.` et quitte. | Affiche `🛑 Interrupted (Ctrl+C).` et annule la génération ; l'invite revient. |
| `Ctrl+D` (fin d'entrée) | Quitte. | — |

## Touches du mode fenêtre

Dans `mm -tui` les mêmes commandes existent ; `/abort` au repos affiche `⚠️ No generation in progress.` comme notice, et le sélecteur ouvert par `/` les liste.

`/quit` et `/abort` prennent effet **immédiatement**, même pendant un tour. Toutes les autres commandes et toutes les questions attendent la fin du tour, parce qu'elles ont besoin de l'historique que le tour est encore en train d'écrire. Voir [Sortir d'un tour qui ne s'arrête pas](#sortir-dun-tour-qui-ne-sarrête-pas).

Les touches :

| Touche | Action |
|--------|--------|
| `Entrée` | Envoie la zone (rien sur une zone vide). Avec le sélecteur ouvert sur un nom incomplet, le complète à la place. |
| `Ctrl-J`, `Alt-Entrée` | Insère un saut de ligne dans la zone. |
| `Échap` | Annule le tour en cours (comme `/abort`) ; ferme le sélecteur ; refuse une permission en attente. |
| `Ctrl-C` | Annule le tour en cours ; quitte au repos — et quitte aussi lorsque le tour a déjà reçu l'ordre de s'arrêter et ne l'a pas fait. |
| `Tab` | Déplace le focus entre la zone et la conversation ; complète le choix du sélecteur quand il est ouvert (`/`, `@` ou `$`). |
| `↑` `↓` | Dans la zone : passent d'une rangée à l'autre — une ligne longue est repliée aux espaces sur plusieurs rangées — et font défiler la conversation depuis sa première/dernière rangée. Sur la conversation : défilent d'une ligne. Dans le sélecteur : déplacent le choix. |
| `PgUp` `PgDn` | Défilent d'une page. |
| `Début` `Fin` | Dans la zone : début/fin de ligne. Sur la conversation : haut / bas (le bas reprend le suivi). |
| `Ctrl-L` | Efface la conversation affichée ; l'historique est conservé. |
| `F1` | Comme `/help`. |
| `F2` | Bascule la capture de la souris. Désactivée (défaut) : le cliquer-glisser du terminal sélectionne du texte ; la barre d'état indique `F2 mouse: off`. Activée : la molette fait défiler, `Maj`+glisser sélectionne, la barre d'état indique `mouse: on (Shift+drag selects)`. |
| `Ctrl-Y` | Comme `/copy` : la dernière réponse dans le presse-papiers. |
| `a` `s` `r` `n` | Répondent à une permission en attente (`yolo: false`, ou un outil MCP marqué `ask`) : autoriser une fois, autoriser cet outil pour la session, refuser cet appel (`Échap` aussi), ne jamais autoriser cet outil dans cette session. |
| Molette | Fait défiler la conversation — seulement quand la souris est capturée (F2). |
| Collage encadré | Inséré en un bloc ; ses sauts de ligne deviennent des sauts de ligne, jamais un envoi. Au-delà de 3 lignes ou de 200 caractères : replié en un jeton `[Pasted #n · L lines · C chars]` qui s'édite comme un seul caractère ; Entrée envoie le texte complet, la conversation garde le jeton. Un `@chemin` dans un collage n'est pas résolu. |

## Sortir d'un tour qui ne s'arrête pas

Un tour se termine normalement quand on l'annule. Un tour qui ignore l'annulation — un moteur qui ne répond plus, un outil bloqué sur quelque chose qui ne revient jamais — piégeait la fenêtre : `/quit` et `/abort` attendaient la fin du tour, donc ne s'exécutaient jamais, et `Ctrl-C` comprenait « il y a un tour à annuler » comme « donc ne pas quitter ». La seule issue était de tuer `mm` depuis un autre terminal.

La sortie, dans l'ordre :

| Vous faites | La fenêtre fait |
|-------------|-----------------|
| `Échap` ou `/abort` | Annule le tour, et affiche `🛑 Aborting…`. |
| `Échap` ou `/abort` à nouveau | Le tour est toujours là : `⚠️ The turn is not answering the cancellation — press Ctrl-C (or /quit) to leave mm.` |
| `Ctrl-C` | Annule, comme ci-dessus. |
| `Ctrl-C` à nouveau | Quitte `mm`, tour en cours ou non. |
| `/quit` | Quitte `mm` tout de suite, à n'importe quel moment. |

Sortir ainsi n'attend pas le travail bloqué : le fichier de session contient tout ce qui a été enregistré jusqu'au dernier tour terminé.

## Les trois sélecteurs

Une fenêtre surgissante s'ouvre au-dessus de la conversation dès que vous tapez l'un des trois déclencheurs, et se resserre à mesure que vous tapez. **Tab** complète la ligne surlignée, **↑/↓** déplacent, **Échap** la referme jusqu'à ce que le texte change.

| Déclencheur | Propose | Où ça marche | Ce que Tab écrit |
|---|---|---|---|
| `/` | les commandes de la fenêtre | seulement comme premier mot entier de la zone — une commande *est* le message | la commande, en remplaçant la zone, avec une espace si elle prend un argument |
| `@` | fichiers et dossiers sous le répertoire de travail | n'importe où dans une phrase | le chemin avec son `@` conservé. Un **dossier** reçoit un `/` final et pas d'espace, donc Tab à nouveau descend dans l'arbre ; un **fichier** reçoit une espace, donc la phrase continue |
| `$` | les skills du catalogue | n'importe où dans une phrase | `$nom` — le `$` **conservé** — plus une espace, curseur après, prêt pour les paramètres du skill |

Trois règles gardent la fenêtre à sa place :

- Un déclencheur collé à la fin d'un mot n'en est pas un : `bob@example.com` n'ouvre rien, ni `5$`.
- `@` masque les fichiers cachés jusqu'à ce que vous tapiez le `.` vous-même.
- `$` ne propose rien quand aucun skill ne correspond, donc `echo $HOME` et `$PATH` sont laissés tranquilles.

`Entrée` sur un token `@` ou `$` le complète au lieu d'envoyer : le message n'est pas fini. `Entrée` sur une commande dont le nom est déjà complet l'envoie.

### Ce que fait `$nom` à l'envoi

`$greetings Bob Morane` ajoute une ligne à ce que lit le modèle, comme `@chemin` ajoute une ligne de pièce jointe :

```
use $greetings Bob Morane
[skill: greetings — load it with read_skill and carry out its steps now; parameters: Bob Morane]
```

Les paramètres sont le reste de la ligne. C'est toujours le modèle qui fait l'appel `read_skill`, donc le détecteur de boucle, la demande de permission et le recap `📖 N skill(s)` le voient tous — `mm` ne charge pas le skill dans le dos du modèle.

La notation marche aussi en mode ligne et en ACP, tapée à la main : un `$skill` veut dire la même chose partout où il est écrit, comme `@chemin`. Un `$nom` qui ne correspond à aucun skill est laissé tel quel, et un `$` dans un collage replié n'est pas résolu.

## Messages affichés en fin de tour

| Message | Signification |
|---------|---------------|
| `🛑 Generation aborted.` | Le tour a été annulé (`/abort`, `Ctrl+C`). La question et les tours d'outils terminés restent dans l'historique. |
| `[error: …]` | Le fournisseur a expliqué un échec en une ligne ; une question restée sans réponse est retirée de l'historique. |
| `⚙ N command(s)` | Nombre de commandes `bash` réellement exécutées dans le tour. |
| `· 📝 N file op(s)` | Ajouté quand des outils de fichiers ont tourné. |
| `· 📖 N skill(s)` | Ajouté quand des skills ont été chargés. |
| Liste numérotée en vert | Les commandes et opérations sur fichiers du tour, une par ligne, quand `displayCommands: true`. |

## Mode ACP

Deux commandes existent en mode ACP, trois avec `unloadModels` (le défaut) : `/new`, `/compact` et `/unload`. Elles sont annoncées à l'éditeur par une notification `available_commands_update` et interceptées par `session/prompt` quand le texte du prompt, débarrassé de ses espaces, est exactement la commande (`/unload` peut être suivie d'un nom de modèle). Chacune répond par un `agent_message_chunk` portant la ligne que le terminal afficherait, puis `stopReason: end_turn` ; le modèle n'est pas consulté.

| Commande | En ACP |
|----------|--------|
| `/new` | Comme dans le terminal : historique ramené au prompt système, compte de tokens oublié ; l'identifiant de session, le `cwd` et les autorisations « toujours autoriser » sont conservés. |
| `/compact` | Comme dans le terminal, toujours forcée : `🗜️ compressed …`, `🗜️ nothing to compact: …` ou `[compact: failed, history kept: …]`. Attend d'abord la fin d'un tour en cours. |
| `/unload [modèle]` | Avec `unloadModels` (activé par défaut), annoncée avec l'indication de saisie `[model]` : comme dans le terminal, la ligne `🧹` comme texte de l'agent ; l'historique n'est pas touché. |

Chaque **skill** y est proposé comme une commande à part entière : ACP n'a pas de sélecteur pour les skills, donc `/greetings Bob` dans le menu de l'éditeur est l'équivalent de `$greetings Bob` dans la fenêtre, et il est réécrit en exactement ça — voir la [référence ACP](acp.md#les-skills-comme-commandes).

Avec `mmConfigs`, `/ask-<nom>` et `/ask-with-context-<nom>` sont annoncées aussi, chacune avec l'indication de saisie `<prompt>` ; le `/ask <nom>` générique ne l'est pas, car le menu d'un éditeur complète un nom de commande mais pas son argument. Voir [Interroger un autre agent](#interroger-un-autre-agent).

`/quit` et `/abort` n'existent pas en mode ACP : l'éditeur possède le processus et le termine en fermant stdin, et il annule un tour avec sa propre touche d'arrêt via `session/cancel`. Voir la [référence ACP](acp.md).