bots-garden/mini-mepublic Fork
⑂ main
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. 4478b61 · on main · k33g · 11h ago
use-the-window-mode.md · 100 lines · 9.8 KBmarkdown
Blame HistoryOpen raw

How to use the window mode (mm -tui)

This guide shows how to run mini-me as a single full-screen window — the conversation above, a box to type in below — instead of the line-by-line REPL. It assumes you already run mm from a project directory.

Steps

  1. Start the window from the project directory:

    mm -tui agent.dmr.yaml
    

    Or set tui: true in the YAML and start mm as usual. The banner that the line mode prints is shown as the first line of the conversation.

  2. Type your question in the box at the bottom and press Enter. A long line wraps at word boundaries inside the box (a word longer than a row is cut at the edge); the box keeps its three rows and scrolls them so the cursor's row stays visible, and ↑/↓ move the cursor from row to row. For a second paragraph, press Ctrl-J (or Alt-Enter where your terminal reports it) instead of Enter. A pasted block is inserted whole, never sent; a long one is collapsed into a [Pasted #1 · …] token (see below).

  3. Watch the answer stream into the conversation. Each tool call is one framed line — ‣ bash ls -1 ✓ done 0.03s — followed by its output, folded to previewLines lines; the +/- lines of a file edit are coloured.

  4. Press Esc to stop a running turn. Typing a new question and pressing Enter while a turn runs also stops it; the new question runs once the old one has settled.

  5. Type / at the start of the box to open the command picker: ↑/↓ choose, Tab completes, Enter sends a complete command. /help (or F1) lists the commands and keys in the conversation.

  6. Leave with /quit, at any moment — during a turn too. Ctrl-C cancels a running turn and quits when nothing is running.

  7. If a turn will not stop — the engine stopped answering, a tool is blocked — press Esc once more: the window says ⚠️ The turn is not answering the cancellation — press Ctrl-C (or /quit) to leave mm. Then /quit, or a second Ctrl-C, closes the window without waiting for it. The session file keeps everything up to the last completed turn.

Variants

  • Ask before every bash and file tool. Set yolo: false in the YAML. The box is replaced by the question ? bash: rm -rf build and four keys answer it: a allow once, s allow this tool for the session, r (or Esc) reject, n never allow this tool in this session. A rejected tool tells the model [command rejected by the user]. The default, yolo: true, runs tools without asking. See How to confirm tool calls.
  • Point the model at a file. @path works exactly as in the line mode: existing paths are attached and echoed as 📎 lines. See Point the model at a file with @path.
  • See which agent answers. The header and the label above each answer name the agent: mm, or mm [<acp.title>] when the config gives a title. While another agent works — /ask-<name>, or the ask_agent tool — the header names it with its model and asked by your agent, and its answer is labelled with its title (or its mmConfigs name); then both come back to your agent. See How to let your agent call other agents.
  • Keep and resume sessions. With sessions.enabled: true, the header shows the session id being saved; /sessions and /resume work as in the line mode. See Keep sessions and resume them.
  • Scroll the conversation. PgUp/PgDn page; Tab moves the focus to the conversation so ↑/↓, Home and End scroll it; End resumes following the end. Ctrl-L clears the displayed conversation without touching the history. The mouse wheel scrolls only after F2 (see below).
  • Not a terminal. mm -tui | tee log.txt, or any run where stdin or stdout is not a terminal, prints [tui: stdin or stdout is not a terminal — running the line mode] and runs the line mode. Nothing else changes.

Copy text out of the window

The window leaves the mouse to the terminal: click and drag selects text exactly as in any terminal, and your terminal's copy shortcut copies it. The status bar says F2 mouse: off. Press F2 to hand the mouse to the window instead — the wheel then scrolls the conversation and the status bar says mouse: on (Shift+drag selects); in most terminals, holding Shift while dragging still selects. F2 again gives the mouse back.

To copy an answer without selecting it:

Input Copies
/copy or Ctrl-Y The last answer, as raw text: no 🤖 prefix, no wrapping, no tool frames.
/copy 2 The answer before the last one (3 the one before that, and so on).
/copy all The whole conversation as plain text: questions prefixed with > , answers raw, tool calls as one heading line plus their output.

The confirmation names the road taken, 📋 copied 1 240 chars (pbcopy), because two exist and they are not equally reliable:

  1. A native tool found on PATH: pbcopy on macOS, wl-copy on Wayland, xclip or xsel on X11. This is the reliable path on a Mac.
  2. Otherwise OSC 52, the escape sequence some terminals honour to set the clipboard. It works over SSH and in iTerm2 (allow it under Preferences → General → Selection), Ghostty, kitty and WezTerm; macOS Terminal.app ignores it silently. With no tool and no terminal, /copy says ⚠️ no clipboard: ….

The line mode has /copy and /copy 2 too, through the same roads; /copy all is window-only, since the terminal's scrollback is already selectable there.

Paste long text

A pasted block is never sent by itself: its line breaks become new lines in the box. When the block is longer than the box — more than 3 lines, or more than 200 characters — the box shows a single token instead of the text:

> explain this stack trace [Pasted #1 · 42 lines · 1.2k chars] and the fix in [Pasted #2 · 5 lines · 310 chars]

The token behaves as one character: ←/→ step over it, Backspace or Delete removes it whole together with the pasted text, and you keep typing around it. Several pastes in one message are numbered in the order you pasted them.

On Enter, the model receives your sentence with each token replaced by the full pasted text, byte for byte, line breaks included. Nothing is shortened or summarised. The conversation, on the other hand, keeps showing the token, so a long paste does not push the exchange off the screen; the persisted session and /copy all carry the full question.

Two details follow from "a paste is data you brought, not something you typed":

  • @path mentions inside a pasted block are not looked up; only the ones you typed yourself attach a file (see @path).
  • A /command inside a paste is text for the model, not a command.

Pastes shorter than the threshold are inserted as text, exactly as before. Bracketed paste must be supported by the terminal for any of this to work: Terminal.app, iTerm2, Ghostty and kitty support it; inside tmux, a paste is passed through as bracketed only when the outer terminal and tmux both support it (tmux does since 1.8; set -g needs no option for pass-through, but a paste-buffer without -p sends the text as plain keys, which then arrive as typed characters and are inserted one by one).

Recall an earlier question

With sessions.enabled: true, the box remembers what you asked.

  1. With the focus on the box, press ↑ on its first row: the last question you asked comes back in the box. Press ↑ again for the one before, and so on through this session, then through the project's earlier sessions, newest first.
  2. Press ↓ on the box's last row to go forward again. Past the newest question, ↓ gives back what you were typing before you started looking back.
  3. Edit the question if you want, and press Enter to send it. Or press Esc to clear the box and type something else — when no turn is running, Esc empties the box instead of cancelling.

A recalled question is the text mm stored: an @path question comes back with its [attached file: …] lines, a collapsed paste comes back as its full text, and an /ask as [asked <agent> (…): …]. Slash commands are not stored and are not recalled. A question whose turn failed or was cancelled is recalled until you ask the next one, even though it is not kept in the session file. With sessions off, or before anything was asked, ↑ on the first row scrolls the conversation as it always did.

Run commands in your shell without leaving mm

  1. Type /shell and press Enter. The window disappears and your shell ($SHELL) starts in the window's working directory, under the line mm: /bin/zsh in /path/to/project — type exit to come back to the conversation.
  2. Run what you need: git diff, your tests, an editor. Ctrl-C stops the command you started, not mm.
  3. Type exit. The conversation comes back as you left it, with 🐚 Back from the shell. under it.

Your prompt starts with (mm) while you are in that shell, so you do not type exit in it thinking you are closing a terminal tab. If your prompt theme hides the prefix (powerlevel10k redraws the whole prompt), test the MM_SHELL variable, set to 1 in that shell, in your theme's configuration to show your own marker.

A turn that was running goes on while you are in the shell, and its answer is there when you come back. If it needs a permission, it waits for you.

See also

  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
# How to use the window mode (`mm -tui`)

This guide shows how to run mini-me as a single full-screen window — the conversation above, a box to type in below — instead of the line-by-line REPL. It assumes you already run `mm` from a project directory.

## Steps

1. Start the window from the project directory:

   ```bash
   mm -tui agent.dmr.yaml
   ```

   Or set `tui: true` in the YAML and start `mm` as usual. The banner that the line mode prints is shown as the first line of the conversation.

2. Type your question in the box at the bottom and press **Enter**. A long line wraps at word boundaries inside the box (a word longer than a row is cut at the edge); the box keeps its three rows and scrolls them so the cursor's row stays visible, and ↑/↓ move the cursor from row to row. For a second paragraph, press **Ctrl-J** (or Alt-Enter where your terminal reports it) instead of Enter. A pasted block is inserted whole, never sent; a long one is collapsed into a `[Pasted #1 · …]` token (see below).

3. Watch the answer stream into the conversation. Each tool call is one framed line — `‣ bash  ls -1  ✓ done  0.03s` — followed by its output, folded to `previewLines` lines; the `+`/`-` lines of a file edit are coloured.

4. Press **Esc** to stop a running turn. Typing a new question and pressing Enter while a turn runs also stops it; the new question runs once the old one has settled.

5. Type `/` at the start of the box to open the command picker: ↑/↓ choose, **Tab** completes, **Enter** sends a complete command. `/help` (or **F1**) lists the commands and keys in the conversation.

6. Leave with `/quit`, at any moment — during a turn too. **Ctrl-C** cancels a running turn and quits when nothing is running.

7. If a turn will not stop — the engine stopped answering, a tool is blocked — press **Esc** once more: the window says `⚠️ The turn is not answering the cancellation — press Ctrl-C (or /quit) to leave mm.` Then `/quit`, or a second **Ctrl-C**, closes the window without waiting for it. The session file keeps everything up to the last completed turn.

## Variants

- **Ask before every `bash` and file tool.** Set `yolo: false` in the YAML. The box is replaced by the question `? bash: rm -rf build` and four keys answer it: `a` allow once, `s` allow this tool for the session, `r` (or Esc) reject, `n` never allow this tool in this session. A rejected tool tells the model `[command rejected by the user]`. The default, `yolo: true`, runs tools without asking. See [How to confirm tool calls](confirm-tool-calls.md).
- **Point the model at a file.** `@path` works exactly as in the line mode: existing paths are attached and echoed as `📎` lines. See [Point the model at a file with `@path`](attach-a-file.md).
- **See which agent answers.** The header and the label above each answer name the agent: `mm`, or `mm [<acp.title>]` when the config gives a title. While another agent works — `/ask-<name>`, or the `ask_agent` tool — the header names it with its model and `asked by` your agent, and its answer is labelled with its title (or its `mmConfigs` name); then both come back to your agent. See [How to let your agent call other agents](let-the-agent-call-other-agents.md).
- **Keep and resume sessions.** With `sessions.enabled: true`, the header shows the session id being saved; `/sessions` and `/resume` work as in the line mode. See [Keep sessions and resume them](keep-sessions.md).
- **Scroll the conversation.** PgUp/PgDn page; **Tab** moves the focus to the conversation so ↑/↓, Home and End scroll it; End resumes following the end. **Ctrl-L** clears the displayed conversation without touching the history. The mouse wheel scrolls only after **F2** (see below).
- **Not a terminal.** `mm -tui | tee log.txt`, or any run where stdin or stdout is not a terminal, prints `[tui: stdin or stdout is not a terminal — running the line mode]` and runs the line mode. Nothing else changes.

## Copy text out of the window

The window leaves the mouse to the terminal: click and drag selects text exactly as in any terminal, and your terminal's copy shortcut copies it. The status bar says `F2 mouse: off`. Press **F2** to hand the mouse to the window instead — the wheel then scrolls the conversation and the status bar says `mouse: on (Shift+drag selects)`; in most terminals, holding Shift while dragging still selects. F2 again gives the mouse back.

To copy an answer without selecting it:

| Input | Copies |
|-------|--------|
| `/copy` or **Ctrl-Y** | The last answer, as raw text: no `🤖` prefix, no wrapping, no tool frames. |
| `/copy 2` | The answer before the last one (`3` the one before that, and so on). |
| `/copy all` | The whole conversation as plain text: questions prefixed with `> `, answers raw, tool calls as one heading line plus their output. |

The confirmation names the road taken, `📋 copied 1 240 chars (pbcopy)`, because two exist and they are not equally reliable:

1. A native tool found on `PATH`: `pbcopy` on macOS, `wl-copy` on Wayland, `xclip` or `xsel` on X11. This is the reliable path on a Mac.
2. Otherwise **OSC 52**, the escape sequence some terminals honour to set the clipboard. It works over SSH and in iTerm2 (allow it under *Preferences → General → Selection*), Ghostty, kitty and WezTerm; **macOS Terminal.app ignores it silently**. With no tool and no terminal, `/copy` says `⚠️ no clipboard: …`.

The line mode has `/copy` and `/copy 2` too, through the same roads; `/copy all` is window-only, since the terminal's scrollback is already selectable there.

## Paste long text

A pasted block is never sent by itself: its line breaks become new lines in the box. When the block is longer than the box — **more than 3 lines, or more than 200 characters** — the box shows a single token instead of the text:

```
> explain this stack trace [Pasted #1 · 42 lines · 1.2k chars] and the fix in [Pasted #2 · 5 lines · 310 chars]
```

The token behaves as one character: ←/→ step over it, **Backspace** or **Delete** removes it whole together with the pasted text, and you keep typing around it. Several pastes in one message are numbered in the order you pasted them.

On **Enter**, the model receives your sentence with each token replaced by the full pasted text, byte for byte, line breaks included. Nothing is shortened or summarised. The conversation, on the other hand, keeps showing the token, so a long paste does not push the exchange off the screen; the persisted session and `/copy all` carry the full question.

Two details follow from "a paste is data you brought, not something you typed":

- `@path` mentions **inside** a pasted block are not looked up; only the ones you typed yourself attach a file (see [`@path`](attach-a-file.md)).
- A `/command` inside a paste is text for the model, not a command.

Pastes shorter than the threshold are inserted as text, exactly as before. Bracketed paste must be supported by the terminal for any of this to work: Terminal.app, iTerm2, Ghostty and kitty support it; inside **tmux**, a paste is passed through as bracketed only when the outer terminal and tmux both support it (tmux does since 1.8; `set -g` needs no option for pass-through, but a `paste-buffer` without `-p` sends the text as plain keys, which then arrive as typed characters and are inserted one by one).

## Recall an earlier question

With `sessions.enabled: true`, the box remembers what you asked.

1. With the focus on the box, press **↑** on its first row: the last question you asked comes back in the box. Press ↑ again for the one before, and so on through this session, then through the project's earlier sessions, newest first.
2. Press **↓** on the box's last row to go forward again. Past the newest question, ↓ gives back what you were typing before you started looking back.
3. Edit the question if you want, and press **Enter** to send it. Or press **Esc** to clear the box and type something else — when no turn is running, Esc empties the box instead of cancelling.

A recalled question is the text mm stored: an `@path` question comes back with its `[attached file: …]` lines, a collapsed paste comes back as its full text, and an `/ask` as `[asked <agent> (…): …]`. Slash commands are not stored and are not recalled. A question whose turn failed or was cancelled is recalled until you ask the next one, even though it is not kept in the session file. With sessions off, or before anything was asked, ↑ on the first row scrolls the conversation as it always did.

## Run commands in your shell without leaving mm

1. Type `/shell` and press **Enter**. The window disappears and your shell (`$SHELL`) starts in the window's working directory, under the line `mm: /bin/zsh in /path/to/project — type exit to come back to the conversation.`
2. Run what you need: `git diff`, your tests, an editor. `Ctrl-C` stops the command you started, not mm.
3. Type `exit`. The conversation comes back as you left it, with `🐚 Back from the shell.` under it.

Your prompt starts with `(mm) ` while you are in that shell, so you do not type `exit` in it thinking you are closing a terminal tab. If your prompt theme hides the prefix (powerlevel10k redraws the whole prompt), test the `MM_SHELL` variable, set to `1` in that shell, in your theme's configuration to show your own marker.

A turn that was running goes on while you are in the shell, and its answer is there when you come back. If it needs a permission, it waits for you.

## See also

- [Command line](../reference/cli.md) — the `-tui` flag and the window-mode specifics
- [Slash commands](../reference/slash-commands.md) — the keys of the window
- [Keyboard shortcuts of the window](../../../guides/tui-keyboard-shortcuts.md) — every key, grouped by what you are doing
- [Configuration file](../reference/configuration.md) — `tui` and `permissions`
- [Architecture: one loop, three front ends](../explanation/architecture.md) — why the window is a third front end on the same sink