# REPL Command Reference

The qpq interactive REPL provides 40+ slash commands for messaging, group
management, file transfer, privacy controls, and mesh networking. Launch it
with:

```bash
cargo run --bin qpq -- repl --username alice --password mypass
```

Type any text without a leading `/` to send a message in the active
conversation.

---

## Account and identity

| Command | Alias | Description |
|---|---|---|
| `/whoami` | | Show your identity key, active conversation, and group status |
| `/verify <username>` | | Compare 60-digit safety numbers with a peer for out-of-band key verification |
| `/update-key` | `/rotate-key` | Rotate your MLS leaf node key material (proposes self-update, auto-commits, fans out to all members) |
| `/delete-account` | | Permanently delete your account with confirmation prompt. Purges all user data, keys, deliveries, and channel memberships from the server |

---

## Conversations

| Command | Alias | Description |
|---|---|---|
| `/dm <username>` | | Start or switch to a 1:1 DM with a peer. Creates the channel on first use |
| `/create-group <name>` | `/cg` | Create a new MLS group |
| `/invite <username>` | | Add a member to the current group (fetches their KeyPackage, sends Welcome) |
| `/remove <username>` | | Remove a member from the current group |
| `/join` | | Accept a pending group invitation (processes Welcome message) |
| `/leave` | | Leave the current group |
| `/switch @user` or `/switch #group` | | Switch the active conversation |
| `/list` | `/ls` | List all conversations |
| `/members` | | Show group members with resolved usernames |
| `/group-info` | `/gi` | Show group type, member list, and current MLS epoch |
| `/rename <name>` | | Rename the current conversation |
| `/history [count]` | `/hist` | Show message history (default: 20 messages) |

---

## Messaging

| Command | Alias | Description |
|---|---|---|
| *(plain text)* | | Send a message in the active conversation |
| `/react <emoji> [index]` | | React to a message with an emoji. Omit index to react to the latest message |
| `/typing` | | Send a typing indicator to the active conversation |
| `/typing-notify on\|off` | | Toggle display of other users' typing indicators |
| `/edit <index> <text>` | | Edit one of your own messages (by history index) |
| `/delete <index>` | | Delete one of your own messages (by history index) |

---

## File transfer

| Command | Alias | Description |
|---|---|---|
| `/send-file <path>` | `/sf` | Upload a file in 256 KB chunks (SHA-256 verified), send a FileRef to the conversation. Max 50 MB. MIME type auto-detected |
| `/download <index>` | `/dl` | Download a received file by message index. Verifies SHA-256 hash on completion. Saves to current directory with collision avoidance |

---

## Privacy and disappearing messages

| Command | Alias | Description |
|---|---|---|
| `/disappear <duration>` | | Set message TTL for the active conversation. Duration format: `30m`, `1h`, `1d`, `7d`. Messages are deleted by the server after expiry |
| `/disappear off` | | Disable disappearing messages for the conversation |

---

## Mesh networking

These commands require the client to be built with mesh support:

```bash
cargo build -p quicproquo-client --features mesh
```

| Command | Description |
|---|---|
| `/mesh peers` | Scan for nearby qpq nodes via mDNS (`_quicproquo._udp.local.`) |
| `/mesh server <host:port>` | Note a discovered server address for connection |
| `/mesh send <peer_id> <msg>` | Send a direct P2P message via iroh transport |
| `/mesh broadcast <topic> <msg>` | Publish a message to a broadcast channel |
| `/mesh subscribe <topic>` | Join a topic-based broadcast channel |
| `/mesh route` | Display the current routing table |
| `/mesh identity` | Show your mesh identity (Ed25519 public key, known peers) |
| `/mesh store` | Show store-and-forward queue statistics |

---

## System

| Command | Alias | Description |
|---|---|---|
| `/help` | `/h` | Show command reference |
| `/quit` | `/q`, `/exit` | Exit the REPL |

---

## Message types on the wire

Every application message uses a `[version: 1][type: 1][payload...]` binary
format inside the MLS ciphertext:

| Type | Code | Wire format |
|---|---|---|
| Chat | `0x01` | `[msg_id: 16][body_len: 2 BE][body]` |
| Reply | `0x02` | `[ref_msg_id: 16][body_len: 2 BE][body]` |
| Reaction | `0x03` | `[ref_msg_id: 16][emoji_len: 1][emoji]` |
| ReadReceipt | `0x04` | `[msg_id: 16]` |
| Typing | `0x05` | `[active: 1]` (0 = stopped, 1 = typing) |
| Edit | `0x06` | `[ref_msg_id: 16][body_len: 2 BE][body]` |
| Delete | `0x07` | `[ref_msg_id: 16]` |
| FileRef | `0x08` | `[blob_id: 32][filename_len: 2 BE][filename][file_size: 8 BE][mime_len: 2 BE][mime_type]` |

Read receipts are sent automatically when a Chat or Reply message is received.
Typing indicators time out after 10 seconds of inactivity.
