Skip to content

Agate-DB/Carnelia-Collab

Repository files navigation

Carnelia Collab

Barebones Rust CLI client and server for collaborative plain-text peer to peer editing over TCP.

Uses Carnelia as the backend CRDT engine.

Installation

Pre-built binaries (recommended)

Linux / macOS:

curl -fsSL https://raw.githubusercontent.com/Agate-DB/Carnelia-Collab/master/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/Agate-DB/Carnelia-Collab/master/install.ps1 | iex

Or download the binary for your platform directly from GitHub Releases.

From source (requires Rust)

cargo install --git https://github.com/Agate-DB/Carnelia-Collab

After installation, the carnelia-collab command is available in your PATH.


What It Does

  • TCP server that maintains room/doc text state.
  • CLI clients connect, join a room/doc, and send insert/delete/cursor ops.
  • Server broadcasts updates to all clients in the same room/doc.
  • Plain-text snapshots are persisted to data/<room>/<doc>.
  • MDCS TextDoc is used internally for edits; /sync requests a snapshot.

Quick Start

Note

The TUI joins/leaves automatically and manages cursor movement and edits.

Remote cursors are shown as colored highlights, and a short cursor list is visible in the status line.

1) Start the server

cargo run -- server --addr 0.0.0.0:4000 --data-dir data

Health check (HTTP GET):

curl http://127.0.0.1:8080/health

2) Connect clients

cargo run -- tui --addr 127.0.0.1:4000 --user Alice --room demo --doc shared.txt
cargo run -- tui --addr 127.0.0.1:4000 --user Bob --room demo --doc shared.txt

Tip

For ngrok, use the public host:port as the --addr value.

Controls:

  • Arrow keys: move cursor
  • Home/End: line start/end
  • Enter: newline
  • Backspace/Delete: remove characters
  • Ctrl+R: request sync
  • Ctrl+Q or Esc: quit

Deployment (Real Users)

  1. Build a release binary locally:
cargo build --release
  1. Copy the binary to your server (VPS) and run it:
# example path after build
./target/release/testing_carnelia server --addr 127.0.0.1:4000 --data-dir data
  1. Open the port in your firewall (e.g. 4000/tcp) if you are not using a proxy.
  2. Clients connect using your public IP or domain:
./target/release/testing_carnelia client --addr <public-ip>:4000 --user Alice --room demo --doc shared.txt

TLS with Nginx Stream

Use Nginx stream to terminate TLS on port 443 and proxy to the TCP backend.

  1. Copy deploy/nginx-stream.conf to /etc/nginx/conf.d/collab-stream.conf.
  2. Replace the certificate paths with your domain cert (e.g. Let’s Encrypt).
  3. Reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
  1. Run the server on localhost and connect clients through 443:
./target/release/testing_carnelia server --addr 127.0.0.1:4000 --data-dir data
./target/release/testing_carnelia client --addr <your-domain>:443 --user Alice --room demo --doc shared.txt

Optional: Run under systemd (Linux)

  • Create a service that runs the binary with your preferred --addr and --data-dir.
  • Ensure the working directory is writable for data/ snapshots.

Share via ngrok (Quick Demo)

ngrok can forward raw TCP so others can connect without a VPS. This is best for short demos.

  1. Install and authenticate ngrok (see ngrok docs):
  2. Start the server locally:
cargo run -- server --addr 127.0.0.1:4000 --data-dir data
  1. Start ngrok TCP tunnel to port 4000:
ngrok tcp 4000
  1. ngrok will print a public address like tcp://0.tcp.ngrok.io:12345. Share the host and port with others:
cargo run -- client --addr 0.tcp.ngrok.io:12345 --user Alice --room demo --doc shared.txt

Notes:

  • ngrok TCP does not add TLS. For encrypted connections, use a VPS with Nginx stream + TLS.
  • If you want a stable address, use an ngrok reserved TCP address.

Docker Deployment

Build and run the server in a container and publish port 4000. Via docker-compose:

docker compose up --build

Set your ngrok token (required for TCP tunnels) and watch the ngrok output in the container logs:

$env:NGROK_AUTHTOKEN = "<your-token>"
docker compose up --build

You can still connect from clients using the host IP or from ngrok by forwarding port 4000 on the host:

ngrok tcp 4000

The container also serves a health endpoint on port 8080:

curl http://127.0.0.1:8080/health

Protocol

Line-delimited JSON over TCP.

  • Client → Server: Join, Insert, Delete, Cursor, SyncRequest, Ping
  • Server → Client: Welcome, Applied, Presence, SyncResponse, Error

See src/protocol.rs for full message schemas.

About

Barebones Rust CLI for collaborative plain-text editing over TCP

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors