106 lines
2.8 KiB
Markdown
106 lines
2.8 KiB
Markdown
# collabd - editor-agnostic collaborative editing daemon
|
|
|
|
daemon + thin adapters architecture. daemon handles yjs crdt, adapters just
|
|
hook buffer events and apply remote changes.
|
|
|
|
## status
|
|
|
|
working:
|
|
- daemon with room-based sessions
|
|
- multi-peer sync (tested with 2+ clients)
|
|
- vim9 adapter with live buffer sync
|
|
- proper crdt diffing (not delete-all-insert-all)
|
|
- integration tests for concurrent edits
|
|
|
|
not yet:
|
|
- cursor/selection sync (awareness protocol stubbed but unused)
|
|
- other editor adapters (helix, kakoune, zed)
|
|
- reconnection handling
|
|
|
|
## stack
|
|
|
|
- bun runtime
|
|
- [yjs](https://github.com/yjs/yjs) for crdt
|
|
- websocket transport
|
|
- vim9script adapter (with bun bridge since vim cant do websocket)
|
|
|
|
## running
|
|
|
|
```bash
|
|
just dev # daemon on :4040
|
|
COLLABD_DB=path.db just dev # custom db path (default: collabd.db)
|
|
bun test # unit tests
|
|
just check # biome lint
|
|
```
|
|
|
|
## vim adapter usage
|
|
|
|
requires Vim 9.0+ (uses vim9script)
|
|
|
|
```vim
|
|
:source adapters/vim/collab.vim
|
|
:CollabJoin roomname
|
|
:CollabLeave
|
|
:CollabStatus
|
|
```
|
|
|
|
the vim plugin spawns adapters/vim/bridge.ts which handles yjs and speaks
|
|
json lines to vim via channels.
|
|
|
|
## protocol
|
|
|
|
daemon speaks json over websocket at /ws
|
|
|
|
client -> server:
|
|
{ type: "join", room: "name" }
|
|
{ type: "leave" }
|
|
{ type: "update", data: [...] } // yjs update bytes
|
|
|
|
server -> client:
|
|
{ type: "sync", data: [...] } // full yjs state on join
|
|
{ type: "update", data: [...] } // remote changes
|
|
{ type: "peers", count: N }
|
|
|
|
## key files
|
|
|
|
- src/index.ts - websocket server, room routing
|
|
- src/session.ts - yjs doc per room, peer management
|
|
- src/protocol.ts - message types
|
|
- src/db.ts - sqlite persistence, save/load crdt updates
|
|
- adapters/vim/bridge.ts - bun process vim spawns
|
|
- adapters/vim/collab.vim - vim9script plugin
|
|
|
|
## adding new editor adapters
|
|
|
|
each adapter needs:
|
|
1. hook buffer change events
|
|
2. send changes to daemon as yjs updates (or use a bridge like vim does)
|
|
3. receive remote updates and apply to buffer
|
|
4. optionally show peer cursors
|
|
|
|
see NOTES.txt for cell-grid vs text-crdt mode discussion.
|
|
see docs/ for full research and architecture breakdown.
|
|
|
|
## security
|
|
|
|
current state (research prototype):
|
|
- room name validation (alphanumeric, 1-64 chars)
|
|
- message type validation via protocol decoder
|
|
- websocket.send error handling
|
|
|
|
known gaps (not production ready):
|
|
- no authentication (anyone can join any room by name)
|
|
- no authorization (all peers see all edits)
|
|
- no rate limiting on messages or room creation
|
|
- no message size limits
|
|
- room names guessable via brute force
|
|
- no encryption (deploy behind wss, not ws)
|
|
- no audit logging
|
|
|
|
before production:
|
|
1. auth layer (jwt tokens or unix socket for local-only)
|
|
2. per-room authorization
|
|
3. rate limiting (msgs/sec, rooms/minute)
|
|
4. message size caps
|
|
5. tls via reverse proxy
|
|
6. access logging
|