colabbd/CLAUDE.md
2026-01-27 21:55:53 -05:00

2.8 KiB

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 for crdt
  • websocket transport
  • vim9script adapter (with bun bridge since vim cant do websocket)

running

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)

: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