Metadata-Version: 2.4
Name: mud-slop
Version: 0.1.3
Summary: A terminal-based MUD client with GMCP support, ANSI colors, and protocol inspection
Project-URL: Homepage, https://github.com/mrosata/mud-slop
Project-URL: Repository, https://github.com/mrosata/mud-slop
Project-URL: Issues, https://github.com/mrosata/mud-slop/issues
Author: mrosata
License-Expression: MIT
License-File: LICENSE
Keywords: client,curses,gmcp,mud,telnet,terminal
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console :: Curses
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)
Classifier: Topic :: Terminals
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# mud-slop

![image](./assets/logo.png)

A terminal-based MUD (Multi-User Dungeon) client with GMCP support, ANSI color rendering, and protocol inspection. Built entirely with the Python standard library.

## Features

- **ANSI color rendering** — full support for 8 foreground/background colors, bright variants, bold, underline, and reverse
- **GMCP support** — negotiates with Aardwolf-style servers and displays HP/Mana/Moves bars and character attributes in a stats pane
- **Conversation overlay** — speech lines (says, tells, whispers, yells, asks) are captured and shown in a navigable overlay panel
- **Info ticker** — `INFO:` channel messages display in a ticker bar above the input line
- **Map pane** — ASCII maps are extracted using `<MAPSTART>`/`<MAPEND>` tags, room descriptions via `{rdesc}`/`{/rdesc}` tags, and rendered in a fixed panel on the right side of the screen showing room name, coords, map, exits, and word-wrapped description
- **Help pager** — help content wrapped in `{help}`/`{/help}` tags is displayed in a scrollable overlay with paging controls (PgUp/PgDn/Home/End/ESC), allowing users to read help while still typing commands
- **Debug logging** — writes output, protocol, and GMCP streams to log files
- **Scrollback** — Page Up/Down to scroll through history; configurable content visibility when scrolled up (conversations shown by default, help/maps/info hidden; toggle with `/history`)
- **Command history** — Up/Down arrows with prefix filtering
- **Line editing** — Left/Right arrows, Ctrl+A/E (home/end), Ctrl+Left/Right (word jump), Ctrl+W/U/K (kill word/to-start/to-end), Delete key
- **Password masking** — input is hidden when the server signals password mode (via telnet WILL ECHO)
- **Auto-login profiles** — store credentials in gitignored YAML profiles (`profiles/<name>.yml`) and use `-p <name>` to log in automatically

## Requirements

- Python 3.9+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip

## Installation

### From PyPI (recommended)

```bash
pip install mud-slop
```

Or with [uv](https://docs.astral.sh/uv/):

```bash
uv tool install mud-slop
```

### From source

```bash
git clone <repo-url> && cd mud-slop
uv sync
```

## Usage

```bash
uv run mud-slop <host> <port>
```

### Options

| Flag | Description |
|---|---|
| `-c`, `--config` | Configuration name or path (see [Configuration](#configuration)) |
| `-p`, `--profile` | Login profile name or path (see [Profiles](#profiles)) |
| `--create-profile NAME` | Create a login profile interactively (saves to `~/.mud-slop/profiles/`) |
| `--no-color` | Disable ANSI color rendering |
| `-d`, `--debug` | Enable debug logging to `mud_*.log` files |
| `--conv-pos {top-left\|top-center\|...\|bottom-right}` | Conversation overlay position (default: `bottom-right`) |

### Examples

```bash
# Connect to Aardwolf using config file
uv run mud-slop -c aardwolf

# Connect with explicit host/port (overrides config)
uv run mud-slop aardmud.org 4000

# With debug logging enabled
uv run mud-slop -c aardwolf --debug

# Create a login profile (prompts for username/password)
uv run mud-slop --create-profile mychar

# Auto-login with a profile
uv run mud-slop -c aardwolf -p mychar

# Override host/port from config
uv run mud-slop -c aardwolf localhost 5000
```

### Configuration

Configuration files are YAML files loaded via `-c <name>` or `-c <path>`. CLI arguments override config values.

**Search order for config names:**
1. `~/.mud-slop/configs/<name>.yml` (user configs)
2. `./configs/<name>.yml` (current directory)
3. Package `configs/` directory (bundled configs)

You can also pass a full path: `-c ~/my-configs/custom.yml`

Example config structure (`configs/aardwolf.yml`):

```yaml
connection:
  host: aardmud.org
  port: 4000

gmcp:
  subscriptions:
    - "char 1"
    - "char.vitals 1"
    - "char.stats 1"

patterns:
  map:
    start_tag: '<MAPSTART>'
    end_tag: '<MAPEND>'
  info:
    prefix: '^INFO:\s+'

timers:
  conversation:
    auto_close: 8.0

ui:
  right_panel_max_width: 70
  max_output_lines: 5000
  history:
    conversations: true
    help: false

hooks:
  # Commands to run after login (when GMCP vitals first arrive)
  post_login:
    - map
    - look
  # Commands to run before disconnecting
  on_exit:
    - quit
```

See `configs/default.yml` for the complete schema with all options.

### Profiles

Login profiles store credentials for auto-login. Profile files are **gitignored** to prevent committing secrets.

**Search order for profile names:**
1. `~/.mud-slop/profiles/<name>.yml` (user profiles)
2. `./profiles/<name>.yml` (current directory)
3. Package `profiles/` directory

You can also pass a full path: `-p ~/my-profiles/mychar.yml`

Create a profile interactively (password input is hidden, saves to `~/.mud-slop/profiles/`):

```bash
mud-slop --create-profile mychar
```

Then use it to auto-login:

```bash
mud-slop -c aardwolf -p mychar
```

The client sends the username after the server's initial prompt and sends the password when the server enters password mode (telnet WILL ECHO). See `profiles/README.md` for details.

### In-app commands

| Command | Action |
|---|---|
| `/quit` | Exit the client |
| `/clear` | Clear output pane (and conversation, map, ticker) |
| `/debug` | Toggle debug logging on/off at runtime |
| `/info` | Show timestamped info message history |
| `/history` | Show history visibility settings |
| `/history <type> [on\|off]` | Toggle what shows when scrolled up (types: conversations, help, maps, info) |

Everything else typed at the prompt is sent to the server.

### Keyboard shortcuts

| Key | Action |
|---|---|
| Enter | Send input |
| Left / Right | Move cursor within input line |
| Ctrl+A | Jump to start of input |
| Ctrl+E | Jump to end of input |
| Ctrl+Left / Ctrl+Right | Jump word left/right |
| Backspace | Delete character before cursor |
| Delete | Delete character at cursor |
| Ctrl+W | Delete word backwards |
| Ctrl+U | Delete to start of line |
| Ctrl+K | Delete to end of line |
| Up / Down | Navigate command history |
| Page Up / Page Down | Scroll output (or help pager when open) |
| Home / End | Jump to top/bottom of scrollback (or help pager when open) |
| Shift+Right / Shift+Left | Navigate conversation entries |
| Escape | Dismiss conversation overlay or help pager |
| W / A / S / D | Move north/west/south/east (only when input is empty, after login) |
| F1 | Toggle help overlay |
| Ctrl+C | Quit |

### UI layout

The UI has up to five regions:

- **Output pane** — main MUD text (filtered: speech, info, and map lines removed at scroll position 0)
- **Stats pane** — GMCP vitals/status/attributes (appears automatically when GMCP data arrives, 24-char column on the right)
- **Map pane** — fixed panel on the right side (below stats if both present) showing room name, coordinates, ASCII map, exits, and word-wrapped description (appears after login when map data is received)
- **Help pager** — scrollable overlay on the right side showing help content (appears when server sends `{help}` tags, covers stats/map panes)
- **Info ticker** — single-row bar above the input line showing `INFO:` channel messages
- **Input line** — command entry with `> ` prompt

The conversation overlay draws on top of the output pane. The map pane is a fixed panel on the right side of the screen (below the stats pane if both are present), and is hidden while the conversation overlay is visible. Scrolling up reveals history with configurable content visibility — by default only conversation lines are included. Use `/history` to toggle what appears (conversations, help, maps, info).

Debug logging (`-d` or `/debug`) writes to `mud_output.log`, `mud_proto.log`, and `mud_gmcp.log` in the current directory.

## Development

```bash
# Install in dev mode
uv sync

# Run via entry point
uv run mud-slop <host> <port>

# Run via python -m
uv run python -m mud_slop <host> <port>
```

The project has zero runtime dependencies. See `CLAUDE.md` for detailed architecture notes and the module dependency graph.

```bash
# Run tests
uv run python -m pytest tests/ -v
```
