# meshdb-client
A terminal UI for Bolt-compatible graph databases. One binary, three tabs —
Cypher REPL, schema browser, and an ASCII graph view of the nodes and edges
in the last result.
Part of the [mesh](../../) workspace. Speaks Bolt 5.4 / 5.0 / 4.4, so it
works against Mesh, Neo4j, or anything else that implements the Bolt
protocol.
## Backends
| Mesh | Bolt 5.4 / 5.0 / 4.4 | Uses the in-workspace `meshdb-bolt` crate directly. |
| Neo4j | Bolt 5.4 / 5.0 / 4.4 | Same wire code path as Mesh. HELLO→LOGON split handled for 5.1+. |
### URI schemes
| `bolt://`, `neo4j://` | Plaintext TCP. |
| `bolt+s://`, `neo4j+s://` | TLS verified against the Mozilla root bundle (`webpki-roots`). |
| `bolt+ssc://`, `neo4j+ssc://` | TLS, accepts any server cert — **dev / self-signed only**. |
The `neo4j://` schemes are treated identically to `bolt://` — server-side
routing isn't implemented, so connections go straight to the host/port in
the URI. Default port is `7687` if omitted.
## Build
`meshdb-client` is a member of the top-level `mesh` workspace, so the usual
workspace commands work from the repo root:
```sh
cargo build -p meshdb-client --release
```
The binary lands at `target/release/meshdb-client`.
## Run
```sh
cargo run -p meshdb-client --release -- --profile mesh-local
```
On first launch with no `~/.config/meshdb-client/config.toml`, two sensible
defaults are seeded in-memory: `mesh-local` and `neo4j-local`. Write your
own config (see below) to override.
Flags:
| `-p, --profile NAME` | Which profile to connect to. Defaults to the first in the config. |
| `-c, --config PATH` | Alternate config path. Defaults to `~/.config/meshdb-client/config.toml`. |
## Keyboard shortcuts
All terminal-safe — no Ctrl combos that iTerm / tmux / terminal multiplexers
typically steal.
| `F1` / `F2` / `F3` | REPL / Schema / Graph tab |
| `F5` | Run query (REPL tab) |
| `F6` | Toggle focus between editor and results (REPL tab) |
| `F8` | Refresh schema |
| `F10` | Quit |
| `Alt+↑` / `Alt+↓` | Cycle query history (REPL editor only) |
| `Esc` | From editor, drop into results pane |
| `Enter` / `i` | From results, jump back into editor |
| `↑` `↓` `j` `k` | Scroll results / schema |
| `PgUp` / `PgDn` | Page-scroll results |
| `Home` | Results/schema: top · Graph: recenter (0, 0) |
| `h` `j` `k` `l` | Pan the graph view |
## Config
`~/.config/meshdb-client/config.toml`:
```toml
[[profiles]]
name = "mesh-local"
username = "neo4j"
password = "password"
[[profiles]]
name = "neo4j-local"
kind = "neo4j"
uri = "bolt://127.0.0.1:7687"
username = "neo4j"
password = "password"
database = "neo4j"
[[profiles]]
name = "neo4j-tls"
kind = "neo4j"
uri = "bolt+s://graph.example.com:7687"
username = "neo4j"
password = "s3cret"
```
`username` / `password` are optional — leaving both off sends `scheme: none`
on the Bolt HELLO/LOGON. `database` is forwarded on Neo4j connections.
Pick a profile at startup with `--profile <name>`, or point at a different
config with `--config <path>`.
## How the three tabs work together
- **REPL (F1)** — write Cypher in the editor, run with F5. Results drop into
a paged table below. Each successful query is pushed onto the session's
history (Alt+↑/↓ to recall). The status line shows row count, `t_last`
from Bolt, and query type when the server returns them.
- **Schema (F2)** — three columns: labels, relationship types, property keys.
Loaded on startup, refreshed on demand with F8. Populated by running
`MATCH (n) UNWIND labels(n) AS l RETURN DISTINCT l` etc., so it works
against any Cypher-speaking backend without server-side introspection
APIs.
- **Graph (F3)** — renders the nodes and edges of the last REPL result on
a ratatui canvas. Circular layout — deterministic so panning stays
stable; gets busy past ~30 nodes. Edges are drawn straight, labels
next to node circles.
## Layout
```
src/
├── main.rs # entry, terminal setup, event loop, key routing
├── app.rs # App state: tabs, focus, history, scroll offsets
├── config.rs # Serde-backed profile config, default-path lookup
├── backend/
│ ├── mod.rs # GraphBackend trait, Value/Node/Edge/QueryResult types
│ └── bolt.rs # Bolt 4.4/5.x client on meshdb-bolt, with TLS
└── ui/
├── mod.rs # top-level layout, tab bar, status line
├── repl.rs # query textarea + results table
├── schema.rs # three-column list view
└── graph.rs # canvas-based graph viewer with circular layout
```
## Dependencies worth knowing about
- **`meshdb-bolt`** (intra-workspace) — the Bolt 5 client used for every
backend. Picks the newest version each side supports via
`perform_client_handshake`.
- **`tokio-rustls`** + **`webpki-roots`** — TLS for `+s://` schemes. The
`+ssc://` variants swap in a no-op cert verifier for dev against
self-signed servers.
- **`ratatui`** + **`crossterm`** + **`tui-textarea`** — the TUI stack.
## Known limitations
- **Graph layout is circular, not force-directed.** Stable and fast, but
gets visually busy past ~30 nodes. Good upgrade path for later.
- **No server-side routing.** `neo4j://` URIs are treated as direct
connections — the client talks straight to the host/port in the URI
without consulting `ROUTE`. Fine for single-server setups.