.agents/skills/real-time-collab/SKILL.md
Multi-user collaborative editing with Yjs CRDT and live cursors. Use when adding real-time collaborative editing to a template, debugging sync issues, or understanding how the agent and humans edit documents simultaneously.
npx skillsauth add BuilderIO/agent-native real-time-collabInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are equal participants — both edit the same Y.Doc and changes merge cleanly without conflicts.
Y.Doc stores the document as a Y.XmlFragment (ProseMirror node tree)ySyncPlugin_collab_docs table persists Yjs state as base64-encoded binary (works across SQLite/Postgres)POST /_agent-native/collab/:docId/updateedit-document action → server search-replace → Y.XmlFragment mutation → poll update → all clientsBoth produce minimal Yjs operations that merge cleanly. Agent edits appear without destroying cursor position, selection, or undo history.
The edit-document action uses surgical search-and-replace on Y.XmlText nodes — more efficient than regenerating the entire document.
pnpm add @tiptap/extension-collaboration @tiptap/extension-collaboration-caret @tiptap/y-tiptap
// server/plugins/collab.ts
import { createCollabPlugin } from "@agent-native/core/collab";
export default createCollabPlugin({
table: "documents",
contentColumn: "content",
idColumn: "id",
});
import { useCollaborativeDoc } from "@agent-native/core/client";
const { ydoc, provider } = useCollaborativeDoc(documentId);
import { Collaboration } from "@tiptap/extension-collaboration";
import { CollaborationCaret } from "@tiptap/extension-collaboration-caret";
const editor = useEditor({
extensions: [
Collaboration.configure({ document: ydoc }),
CollaborationCaret.configure({
provider,
user: { name: session.email, color: "#6366f1" },
}),
],
});
optimizeDeps: {
include: [
"@tiptap/extension-collaboration",
"@tiptap/extension-collaboration-caret",
"@tiptap/y-tiptap",
],
}
| Route | Purpose |
| ----- | ------- |
| GET /_agent-native/collab/:docId/state | Fetch full Y.Doc state |
| POST /_agent-native/collab/:docId/update | Apply client Yjs update |
| POST /_agent-native/collab/:docId/text | Apply full text (diff-based) |
| POST /_agent-native/collab/:docId/search-replace | Surgical find/replace in Y.XmlFragment |
| POST /_agent-native/collab/:docId/awareness | Sync cursor/presence state |
| GET /_agent-native/collab/:docId/users | List active users |
content as a TipTap prop when Collaboration is enabled — Yjs owns the content. Set initial content via the Y.Doc instead.editor.setContent() for agent edits — it bypasses Yjs and causes conflicts. Use the search-replace route or edit-document action.optimizeDeps — Vite won't pre-bundle Yjs packages correctly otherwise, causing runtime errors in dev.Y.Doc per document — Don't create multiple Y.Doc instances for the same document ID. Use the useCollaborativeDoc hook which caches by ID.real-time-sync — Polling infrastructure that delivers Y.Doc updatesstoring-data — The _collab_docs table where Yjs state is persistedself-modifying-code — Agent edits to collaborative documents go through edit-document, not raw SQLtools
Public booking flow — the state machine, animations, and URL/app-state sync.
tools
Trigger-based automations — reminders, follow-ups, webhooks — across the booking lifecycle.
tools
Team event types, round-robin assignment, collective bookings, host weights, and no-show calibration.
development
The pure `computeAvailableSlots` function — inputs, outputs, invariants, and debugging guide.