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
|
# Reference: slash commands and keyboard shortcuts
> Neutral description of the commands recognised at the terminal prompt of `mm`. They are matched on the whole trimmed line; anything else is sent to the model.
## Commands
| Command | At the prompt | During a generation |
|---------|---------------|---------------------|
| `/quit` | Exits the program. | Cancels the generation, prints `Goodbye.`, exits. |
| `/abort` | Prints `⚠️ No generation in progress.` | Cancels the generation, prints `🛑 Aborting...`; the commands already run stay in the history. |
| `/compact` | Compresses the history now, regardless of the threshold; prints the `🗜️` report, or `🗜️ nothing to compact` when no turn is older than `context.keepLastTurns`. | Sent to the model as a new message (see below). |
| `/new` | Clears the history back to the system prompt, resets the loop detector and forgets the server's last token count; prints `🆕 new session: N message(s) forgotten` (N counts every message except the system prompt). | Treated like any other text: cancels the generation, keeps its partial history, then runs as `/new` on that history. |
| `/sessions` | Lists the project's stored sessions, newest first: id, last update, question count, first question, then ` · ⚠️ N error(s)` when the session recorded errors; `*` marks the current one. With `sessions.enabled: false`: `⚠️ sessions are off (set sessions.enabled: true in the YAML)`. | Sent to the model as a new message. |
| `/resume [id]` | Continues a stored session: the most recently updated one other than the current, skipping empty ones, or the named id. Prints `↩️ resumed <id> — N message(s), started with "<first question>"` (plus ` · ⚠️ N error(s)` when the session recorded errors); resets the loop detector and the server's token count; later turns are saved to that session. Refused with a `⚠️` reason when sessions are off, when there is no earlier session, when the id is unknown or is the current session. | Sent to the model as a new message. |
| `/help` | Prints the commands of this front end, one per line with their description, aligned. | Sent to the model as a new message. |
| `/copy [n\|all]` | Copies the last answer (`n`: the n-th from the end) to the clipboard through `pbcopy`/`wl-copy`/`xclip`/`xsel` or, failing that, OSC 52 when stdout is a terminal, and prints `📋 copied N chars (<road>)` or `⚠️ …`. `/copy all` is window-mode only: here it says so. | Sent to the model as a new message. |
With `sessions.enabled`, `/new` leaves the current session's file as it is; the next question opens a new file. An empty line at the prompt is ignored.
## `@path` in a question
| Input | Effect |
|-------|--------|
| `@<path>` at the start or after a space, bracket or quote | If the path exists (relative to the start directory, absolute, or `~/…`), a dim `📎 <absolute path>` line is printed and `[attached file: <absolute path>]` (or `[attached directory: …]`) is appended to the message the model receives. Trailing punctuation is ignored; each path is attached once. |
| A `@<path>` that names nothing on disk, or `@` glued to a word | Left as typed. |
Details and examples: [Point the model at a file with `@path`](../how-to/attach-a-file.md).
## Any other text during a generation
| Input | Behaviour |
|-------|-----------|
| A non-command line | Prints `🔄 New command received. Cancelling current task...`, cancels the current generation, keeps its partial history, then submits the new line as the next question. |
## Keyboard shortcuts
| Key | At the prompt | During a generation |
|-----|---------------|---------------------|
| `Ctrl+C` | Prints `Goodbye.` and exits. | Prints `🛑 Interrupted (Ctrl+C).` and cancels the generation; the prompt comes back. |
| `Ctrl+D` (end of input) | Exits. | — |
## Window mode keys
In `mm -tui` the same commands exist; `/abort` when idle prints `⚠️ No generation in progress.` as a notice, and the picker opened by `/` lists them. The keys:
| Key | Action |
|-----|--------|
| `Enter` | Sends the box (nothing on an empty box). With the picker open on an incomplete name, completes it instead. |
| `Ctrl-J`, `Alt-Enter` | Inserts a newline in the box. |
| `Esc` | Cancels the running turn; closes the picker; rejects a pending permission. |
| `Ctrl-C` | Cancels the running turn; quits when idle. |
| `Tab` | Moves the focus between the box and the conversation; completes the picker's choice when it is open. |
| `↑` `↓` | In the box: move between its rows — a long line wraps at spaces into several rows — and scroll the conversation from its first/last row. On the conversation: scroll one line. In the picker: move the choice. |
| `PgUp` `PgDn` | Scroll one page. |
| `Home` `End` | In the box: start/end of the line. On the conversation: top / bottom (bottom resumes following). |
| `Ctrl-L` | Clears the displayed conversation; the history is kept. |
| `F1` | Same as `/help`. |
| `F2` | Toggles mouse capture. Off (default): the terminal's own click-and-drag selection works; the status bar says `F2 mouse: off`. On: the wheel scrolls, `Shift`+drag selects, the status bar says `mouse: on (Shift+drag selects)`. |
| `Ctrl-Y` | Same as `/copy`: the last answer to the clipboard. |
| `a` `s` `r` | Answer a pending permission: allow once, allow this tool for the session, reject. |
| Mouse wheel | Scrolls the conversation — only while the mouse is captured (F2). |
| Bracketed paste | Inserted as one block; its line breaks become newlines, never a send. Longer than 3 lines or 200 characters: collapsed into one `[Pasted #n · L lines · C chars]` token that edits as a single character; Enter sends the full text, the conversation keeps the token. `@path` inside a paste is not looked up. |
## Messages printed at the end of a turn
| Message | Meaning |
|---------|---------|
| `🛑 Generation aborted.` | The turn was cancelled (`/abort`, `Ctrl+C`). The question and any completed tool turns stay in the history. |
| `[error: …]` | The provider explained a failure in one line; a question that got no answer is removed from the history. |
| `⚙ N command(s)` | Number of `bash` commands that actually ran in the turn. |
| `· 📝 N file op(s)` | Appended when file tools ran. |
| `· 📖 N skill(s)` | Appended when skills were loaded. |
| Numbered green list | The commands and file operations of the turn, one per line, when `displayCommands: true`. |
## ACP mode
Two commands exist in ACP mode: `/new` and `/compact`. They are advertised to the editor through an `available_commands_update` notification and intercepted by `session/prompt` when the prompt text, trimmed, is exactly the command. Each answers with one `agent_message_chunk` carrying the line the terminal would print, then `stopReason: end_turn`; the model is not consulted.
| Command | Over ACP |
|---------|----------|
| `/new` | Same as in the terminal: history back to the system prompt, token count forgotten; the session id, `cwd` and allow-always grants are kept. |
| `/compact` | Same as in the terminal, always forced: `🗜️ compressed …`, `🗜️ nothing to compact: …` or `[compact: failed, history kept: …]`. Waits for a running turn to finish first. |
`/quit` and `/abort` do not exist in ACP mode: the editor owns the process and ends it by closing stdin, and cancels a turn with its own stop key through `session/cancel`. See the [ACP reference](acp.md).
|