# Uso della CLI — riferimento completo Il comando dopo `pip install -e .` è **`mudclient`** (entry point definito in `pyproject.toml`). È equivalente a `python -m viandante`. --- ## Flag | Flag | Tipo | Default | Note | | --- | --- | --- | --- | | `--host HOST` | str | `localhost` | host MUD (default punta al docker locale di Dead Souls) | | `--port PORT` | int | `6666` | porta TCP | | `--user NAME` | str | `""` (vuoto = no auto‑login del nome) | auto‑login quando il server chiede "What name do you wish?" | | `--password PWD` | str | `os.environ.get("MUDCLIENT_PASSWORD", "")` | password per auto‑login dopo `Password:` | | `--cols COLS` | int | `120` | larghezza iniziale finestra (NAWS subneg) | | `--rows ROWS` | int | `40` | altezza iniziale finestra | | `--log LVL` | choice | `WARNING` | livello Python logging. Valori validi (rifiutati se diversi): `DEBUG` / `INFO` / `WARNING` / `ERROR` / `CRITICAL`. | | `--log-json PATH` | str | `""` (no log JSON) | path JSONL append‑only (vedi `docs/events.md`) | | `--log-md PATH` | str | `""` (no log MD) | path Markdown streamed | > **Sicurezza `--password`**: il valore è in chiaro in `ps`/`history`. > Usare l'env `MUDCLIENT_PASSWORD` o `/password PWD` (redatto). Il > client redige automaticamente il valore nei log JSON/MD. --- ## Esempi rapidi ```bash # Connessione minimale al docker di sviluppo mudclient # Server remoto esplicito mudclient --host mud.example.com --port 4000 # Auto‑login completo (account + password) mudclient --user zork --password hunter2 # password via env (preferibile in CI / shell history): MUDCLIENT_PASSWORD=hunter2 mudclient --user zork # Auto‑login solo nome; password manuale quando il server chiede mudclient --user zork # Finestra ridotta (es. 80x24) per terminali piccoli mudclient --cols 80 --rows 24 # Debug del parser / IAC mudclient --log DEBUG --log-json ./debug.jsonl --log-md ./debug.md # Log persistente di una sessione intera (rotation esterna) mudclient --log-json ~/mud-$(date +%Y%m%d-%H%M).jsonl \ --log-md ~/mud-$(date +%Y%m%d-%H%M).md ``` --- ## Comandi slash (locali) | Slash | Implementazione | Loggato come | | --- | --- | --- | | `/help` o `/?` | stampa aiuto | `local_cmd` | | `/map` | render ASCII del mapper | `local_cmd` | | `/where` | "Sei in: {Room}. Uscite: {list}" | `local_cmd` | | `/look` | `conn.send_line("look")` | `local_cmd` | | `/stats` | locali scoperti, GMCP, vitali | `local_cmd` | | `/vitals` | `state.vitals` raw | `local_cmd` | | `/clear` | `prompt_toolkit.clear()` | `local_cmd` | | `/quit` `/exit` `/q` | chiude + SystemExit(0) | non loggato | | `/password PWD` | redacted + `conn.send_line(pwd)` | `local_cmd` (redatto) + `login` | | `/...` (altro) | passa al MUD con `/` rimosso | `line_sent` | `Ctrl-D` chiude in modo equivalente a `/quit`. --- ## Prompt e status bar **Prompt** (ricostruito a ogni line): ``` [NomeStanza]> _ ``` `[NomeStanza]` cyan brillante, `>` verde brillante. **Status bar** (ricostruito a ogni refresh): ``` [stanza: Outer Courtyard] [GMCP: on] HP 100/100 SP 50/50 MV 80/80 ``` Refresh forzato ogni **0.5 s** via `PromptSession(refresh_interval=0.5)`. Costo: ~2 redraw/sec anche in idle. Documentato come scelta di trade‑off tra reattività e CPU nel file `docs/architecture.md`. --- ## Flusso auto‑login ``` server: "What name do you wish? " (o "Enter your name:", "Login:") client: send_line(args.user) ← solo se --user e one-shot client: state.auto_user_sent = True server: "Password: " client: state.auto_password_prompted = True ├── args.password → send_line(args.password); state.auto_password_sent = True └── args.password "" → stampa: "[login] server chiede password; digita /password " ``` `auto_*_sent` è **one‑shot**: una seconda occorrenza di "What name…?" non re‑invio il nome. Previene spam in caso di messaggi di echo o re‑auth lato server. **Varianti regex coperte** (`_LOGIN_RE`): ``` What name do you wish Enter your name Login: / Login name Name to use ``` più prefissi opzionali `>` o `*`. **Varianti password** (`_PASSWORD_RE`): ``` Password: * Password ? > Password: ``` Tolleranti a prefissi `> *`, spaziature e `: ?` finale. Se il tuo MUD usa prompt diversi, modifica le regex in `src/viandante/cli.py` (sono 3 righe ciascuna). --- ## Output delle stanze Dead Souls con GMCP attivo invia `Room.Info {num, name, desc, exits}`. Il client usa `num` come id stabile della stanza. Senza GMCP, le stanze sono rilevate euristicamente vedendo: ``` Inn Hall A warm fire crackles. [ Exits: n e ] ``` `RollingRoomParser` chiude il blocco su `Exits:` line. Il mapper visita la stanza immediatamente. Puoi digitare `n` o `e` e la prossima volta che il server conferma la stanza, **l'edge viene creato**. --- ## Rotazione dei log I path `--log-json` e `--log-md` vengono **truncati** all'apertura. Per conservare le sessioni precedenti: ```bash mv ~/mud.jsonl{,.prev} && mudclient --log-json ~/mud.jsonl ``` Per archivi automatici prima di ogni sessione: ```bash LOGBASE=~/mud-$(date +%Y%m%d-%H%M) mudclient --log-json "$LOGBASE.jsonl" --log-md "$LOGBASE.md" ``` Per tail in tempo reale: ```bash # in un secondo terminale durante una sessione attiva tail -f ~/mud.jsonl | jq -c '.kind + ": " + (.data|tostring)' ``` --- ## Diagnosi minimali | Sintomo | Probabile causa | Cosa provare | | --- | --- | --- | | Il client si blocca dopo Connect | Server MUD non risponde `DO ECHO` / GMCP | `--log DEBUG` + `--log-json ./x.jsonl` | | Prompt non ridisegnato | `refresh_interval` non rinfresca in idle | è normale, aspettare il prossimo input | | `/map` mostra [mappa vuota] | nessuna stanza ancora riconosciuta | cammina un po', oppure controlla se `Room.Info` GMCP arriva | | Login password non parte | regex `_PASSWORD_RE` non match | `--log DEBUG` e ispezione `data` di `text` events | | Sessione termina subito | `conn.close()` per EOF inatteso | `--log INFO` per vedere l'eccezione in `read_loop` |