libchat/bin/chat-cli/README.md
Ivan FB aa33e199f4
chore: build the native library from source (flake, CI, docs)
liblogosdelivery is no longer consumed as a prebuilt Nix package; waku-bindings
compiles it from the Nim sources in its vendor submodule. The devShell drops the
prebuilt package and LOGOS_DELIVERY_LIB_DIR and instead supplies that build's
toolchain. CI checks out submodules recursively and caches the (slow, cold) Nim
build on the submodule commit; the toolchain-only jobs exclude every crate that
reaches the native lib, and format is scoped to workspace members so it never
rewrites the vendored generated sources.

Docs corrected along the way: the default transport is `file`, not
logos-delivery, and chat-cli no longer carries its own build.rs or a
logos_delivery transport module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ai43sF2rymPFMG9iki9fwL
2026-07-18 17:31:28 +02:00

134 lines
4.8 KiB
Markdown

# chat-cli
A terminal chat application built on top of libchat. End-to-end encrypted messaging in your terminal.
## Building
The native [logos-delivery](https://github.com/logos-messaging/logos-delivery)
node is built from source by the `waku-bindings` submodule, so fetch it
recursively and build inside the dev shell (which supplies the Nim/C toolchain):
```bash
git submodule update --init --recursive
nix develop -c cargo build --release -p chat-cli
```
The binary lands at `target/release/chat-cli`. The first build compiles the whole
Nim tree and takes tens of minutes; later ones are incremental.
## Transports
Both transports are compiled into the binary and selected at runtime via `--transport`:
| Value (`--transport`) | Description |
|-----------------------|-------------|
| `file` (default) | Shared directory; no network needed — great for local testing |
| `logos-delivery` | Embedded Waku node on the logos.dev network, one reliable channel per conversation |
## Quick start
Run two instances in separate terminals:
```bash
# Terminal 1
cargo run -p chat-cli -- --name alice --port 60001
# Terminal 2
cargo run -p chat-cli -- --name bob --port 60002
```
For local-only testing without any network dependency, use the file transport:
```bash
# Terminal 1
cargo run -p chat-cli -- --name alice --transport file
# Terminal 2
cargo run -p chat-cli -- --name bob --transport file
```
### Establishing a connection
1. In Alice's terminal, type `/intro` — the bundle is copied to your clipboard automatically.
2. In Bob's terminal, type `/connect <paste bundle here>`.
3. Bob's "Hello!" message appears in Alice's terminal. Both can now chat.
### Optional: KeyPackage registry
When `--registry-url <url>` is set, the client publishes its MLS KeyPackage
to the [keypackage-registry](https://github.com/logos-messaging/chat-store)
service on startup so other clients can later fetch it by `account_id`. Without
the flag, an in-memory registry is used and is only visible inside the local
process.
```bash
# Terminal 1 — registry server (from a chat-store checkout)
cargo run -- --bind 127.0.0.1:18080
# Terminal 2 / 3 — chat clients pointing at it
cargo run -p chat-cli -- --name alice --transport file \
--registry-url http://127.0.0.1:18080
cargo run -p chat-cli -- --name bob --transport file \
--registry-url http://127.0.0.1:18080
```
The registry is a throwaway testnet helper; v0.3 replaces it with a
λLEZ-based discovery service.
## Options
| Flag | Default | Description |
|------|---------|-------------|
| `--transport <kind>` | `logos-delivery` | Transport to use (`logos-delivery` or `file`) |
| `--data <dir>` | `tmp/chat-cli-data` | Data directory (UI state and default SQLite path) |
| `--db <path>` | `<data>/<name>.db` | SQLite file for persistent identity |
| `--preset <name>` | `logos.dev` | logos-delivery network preset |
| `--port <n>` | `60000` | TCP port for the embedded logos-delivery node |
| `--registry-url <url>` | *(unset)* | Use the HTTP-backed [keypackage-registry](https://github.com/logos-messaging/chat-store) at this URL instead of the in-memory registry |
| `--log-file <path>` | *(stderr, off)* | Write logs to a file instead of stderr |
## Commands
| Command | Description |
|---------|-------------|
| `/help` | Show available commands |
| `/intro` | Generate your introduction bundle (copies to clipboard) |
| `/connect <bundle>` | Connect to a user using their introduction bundle |
| `/chats` | List all established chats |
| `/switch <user>` | Switch active chat |
| `/delete <user>` | Delete a chat session |
| `/status` | Show identity and connection info |
| `/clear` | Clear current chat's message history |
| `/quit` · `Esc` · `Ctrl+C` | Exit |
## Storage
All data lives under `tmp/chat-cli-data/` by default (override with `--data`):
| Path | Contents |
|------|----------|
| `<name>.db` | SQLite — identity keys, ratchet state, chat metadata (encrypted) |
| `<name>_state.json` | UI state — message history, active chat |
| `transport/<name>/` | Inbox directory watched for incoming messages (file transport only) |
The SQLite database can be inspected with *DB Browser for SQLite*: password `chat-cli`, cipher `SQLCipher 4 defaults`.
## Architecture
```
bin/chat-cli/
└── src/
├── main.rs entry point, CLI arg parsing, runtime transport dispatch
├── app.rs application state and command handling
├── ui.rs ratatui terminal UI
├── utils.rs shared helpers
├── transport.rs module declarations
└── transport/
└── file.rs file-based transport
```
The logos-delivery transport is not part of this crate: it lives in
[`extensions/embedded-logos-delivery`](../../extensions/embedded-logos-delivery),
which maps each conversation onto a reliable channel and links the native node
through `waku-bindings`.