A synchronization tool that implements CRDTs for consistent distributed state management.
Install
mkdir -p .claude/skills/agent-crdt-synchronizer && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7059" && unzip -o skill.zip -d .claude/skills/agent-crdt-synchronizer && rm skill.zipInstalls to .claude/skills/agent-crdt-synchronizer
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Agent skill for crdt-synchronizer - invoke with $agent-crdt-synchronizerKey capabilities
- →Synchronizes delta states between nodes
- →Manages composite distributed data structures
- →Ensures causal ordering of operations
- →Calculates deterministic conflict-free merges
- →Tracks vector clock state
How it works
Maintains a vector clock and delta buffer to reconcile incoming updates against local state via deterministic merge operations.
Inputs & outputs
When to use agent-crdt-synchronizer
- →Synchronizing distributed state
- →Implementing conflict resolution
- →Managing replicated data structures
- →Ensuring eventual consistency
About this skill
name: crdt-synchronizer type: synchronizer color: "#4CAF50" description: Implements Conflict-free Replicated Data Types for eventually consistent state synchronization capabilities:
- state_based_crdts
- operation_based_crdts
- delta_synchronization
- conflict_resolution
- causal_consistency
priority: high
hooks:
pre: |
echo "🔄 CRDT Synchronizer syncing: $TASK"
Initialize CRDT state tracking
if [[ "$TASK" == "synchronization" ]]; then echo "📊 Preparing delta state computation" fi post: | echo "🎯 CRDT synchronization complete"Verify eventual consistency
echo "✅ Validating conflict-free state convergence"
CRDT Synchronizer
Implements Conflict-free Replicated Data Types for eventually consistent distributed state synchronization.
Core Responsibilities
- CRDT Implementation: Deploy state-based and operation-based conflict-free data types
- Data Structure Management: Handle counters, sets, registers, and composite structures
- Delta Synchronization: Implement efficient incremental state updates
- Conflict Resolution: Ensure deterministic conflict-free merge operations
- Causal Consistency: Maintain proper ordering of causally related operations
Technical Implementation
Base CRDT Framework
class CRDTSynchronizer {
constructor(nodeId, replicationGroup) {
this.nodeId = nodeId;
this.replicationGroup = replicationGroup;
this.crdtInstances = new Map();
this.vectorClock = new VectorClock(nodeId);
this.deltaBuffer = new Map();
this.syncScheduler = new SyncScheduler();
this.causalTracker = new CausalTracker();
}
// Register CRDT instance
registerCRDT(name, crdtType, initialState = null) {
const crdt = this.createCRDTInstance(crdtType, initialState);
this.crdtInstances.set(name, crdt);
// Subscribe to CRDT changes for delta tracking
crdt.onUpdate((delta) => {
this.trackDelta(name, delta);
});
return crdt;
}
// Create specific CRDT instance
createCRDTInstance(type, initialState) {
switch (type) {
case 'G_COUNTER':
return new GCounter(this.nodeId, this.replicationGroup, initialState);
case 'PN_COUNTER':
return new PNCounter(this.nodeId, this.replicationGroup, initialState);
case 'OR_SET':
return new ORSet(this.nodeId, initialState);
case 'LWW_REGISTER':
return new LWWRegister(this.nodeId, initialState);
case 'OR_MAP':
return new ORMap(this.nodeId, this.replicationGroup, initialState);
case 'RGA':
return new RGA(this.nodeId, initialState);
default:
throw new Error(`Unknown CRDT type: ${type}`);
}
}
// Synchronize with peer nodes
async synchronize(peerNodes = null) {
const targets = peerNodes || Array.from(this.replicationGroup);
for (const peer of targets) {
if (peer !== this.nodeId) {
await this.synchronizeWithPeer(peer);
}
}
}
async synchronizeWithPeer(peerNode) {
// Get current state and deltas
const localState = this.getCurrentState();
const deltas = this.getDeltasSince(peerNode);
// Send sync request
const syncRequest = {
type: 'CRDT_SYNC_REQUEST',
sender: this.nodeId,
vectorClock: this.vectorClock.clone(),
state: localState,
deltas: deltas
};
try {
const response = await this.sendSyncRequest(peerNode, syncRequest);
await this.processSyncResponse(response);
} catch (error) {
console.error(`Sync failed with ${peerNode}:`, error);
}
}
}
G-Counter Implementation
class GCounter {
constructor(nodeId, replicationGroup, initialState = null) {
this.nodeId = nodeId;
this.replicationGroup = replicationGroup;
this.payload = new Map();
// Initialize counters for all nodes
for (const node of replicationGroup) {
this.payload.set(node, 0);
}
if (initialState) {
this.merge(initialState);
}
this.updateCallbacks = [];
}
// Increment operation (can only be performed by owner node)
increment(amount = 1) {
if (amount < 0) {
throw new Error('G-Counter only supports positive increments');
}
const oldValue = this.payload.get(this.nodeId) || 0;
const newValue = oldValue + amount;
this.payload.set(this.nodeId, newValue);
// Notify observers
this.notifyUpdate({
type: 'INCREMENT',
node: this.nodeId,
oldValue: oldValue,
newValue: newValue,
delta: amount
});
return newValue;
}
// Get current value (sum of all node counters)
value() {
return Array.from(this.payload.values()).reduce((sum, val) => sum + val, 0);
}
// Merge with another G-Counter state
merge(otherState) {
let changed = false;
for (const [node, otherValue] of otherState.payload) {
const currentValue = this.payload.get(node) || 0;
if (otherValue > currentValue) {
this.payload.set(node, otherValue);
changed = true;
}
}
if (changed) {
this.notifyUpdate({
type: 'MERGE',
mergedFrom: otherState
});
}
}
// Compare with another state
compare(otherState) {
for (const [node, otherValue] of otherState.payload) {
const currentValue = this.payload.get(node) || 0;
if (currentValue < otherValue) {
return 'LESS_THAN';
} else if (currentValue > otherValue) {
return 'GREATER_THAN';
}
}
return 'EQUAL';
}
// Clone current state
clone() {
const newCounter = new GCounter(this.nodeId, this.replicationGroup);
newCounter.payload = new Map(this.payload);
return newCounter;
}
onUpdate(callback) {
this.updateCallbacks.push(callback);
}
notifyUpdate(delta) {
this.updateCallbacks.forEach(callback => callback(delta));
}
}
OR-Set Implementation
class ORSet {
constructor(nodeId, initialState = null) {
this.nodeId = nodeId;
this.elements = new Map(); // element -> Set of unique tags
this.tombstones = new Set(); // removed element tags
this.tagCounter = 0;
if (initialState) {
this.merge(initialState);
}
this.updateCallbacks = [];
}
// Add element to set
add(element) {
const tag = this.generateUniqueTag();
if (!this.elements.has(element)) {
this.elements.set(element, new Set());
}
this.elements.get(element).add(tag);
this.notifyUpdate({
type: 'ADD',
element: element,
tag: tag
});
return tag;
}
// Remove element from set
remove(element) {
if (!this.elements.has(element)) {
return false; // Element not present
}
const tags = this.elements.get(element);
const removedTags = [];
// Add all tags to tombstones
for (const tag of tags) {
this.tombstones.add(tag);
removedTags.push(tag);
}
this.notifyUpdate({
type: 'REMOVE',
element: element,
removedTags: removedTags
});
return true;
}
// Check if element is in set
has(element) {
if (!this.elements.has(element)) {
return false;
}
const tags = this.elements.get(element);
// Element is present if it has at least one non-tombstoned tag
for (const tag of tags) {
if (!this.tombstones.has(tag)) {
return true;
}
}
return false;
}
// Get all elements in set
values() {
const result = new Set();
for (const [element, tags] of this.elements) {
// Include element if it has at least one non-tombstoned tag
for (const tag of tags) {
if (!this.tombstones.has(tag)) {
result.add(element);
break;
}
}
}
return result;
}
// Merge with another OR-Set
merge(otherState) {
let changed = false;
// Merge elements and their tags
for (const [element, otherTags] of otherState.elements) {
if (!this.elements.has(element)) {
this.elements.set(element, new Set());
}
const currentTags = this.elements.get(element);
for (const tag of otherTags) {
if (!currentTags.has(tag)) {
currentTags.add(tag);
changed = true;
}
}
}
// Merge tombstones
for (const tombstone of otherState.tombstones) {
if (!this.tombstones.has(tombstone)) {
this.tombstones.add(tombstone);
changed = true;
}
}
if (changed) {
this.notifyUpdate({
type: 'MERGE',
mergedFrom: otherState
});
}
}
generateUniqueTag() {
return `${this.nodeId}-${Date.now()}-${++this.tagCounter}`;
}
onUpdate(callback) {
this.updateCallbacks.push(callback);
}
notifyUpdate(delta) {
this.updateCallbacks.forEach(callback => callback(delta));
}
}
LWW-Register Implementation
class LWWRegister {
constructor(nodeId, initialValue = null) {
this.nodeId = nodeId;
this.value = initialValue;
this.timestamp = initialValue ? Date.now() : 0;
this.vectorClock = new VectorClock(nodeId);
this.updateCallbacks = [];
}
// Set new value with timestamp
set(newValue, timestamp = null) {
const ts = timestamp || Date.now();
if (ts > this.timestamp ||
(ts === this.timestamp && this.nodeId > this.getLastWriter())) {
const oldValue = this.value;
this.value = newValue;
this.timestamp = ts;
this.vectorClock.increment();
this.notifyUpdate({
type: 'SET',
oldValue: oldValue,
newValue: newValue,
timestamp: ts
});
}
}
// Get current value
get() {
return this.value;
}
// Merge with another LWW-Register
merge(otherRegister) {
if (otherRegister.timestamp > this.timestamp ||
(otherR
---
*Content truncated.*
When not to use it
- →For simple, single-instance non-distributed applications
- →When real-time low-latency synchronization isn't a requirement
Prerequisites
Limitations
- →Requires consistent node-to-node connectivity
- →Dependent on correct vector clock implementation
- →Overhead increases with the complexity of composite structures
How it compares
It programmatically automates the mathematical convergence of distributed data rather than relying on manual state reconciliation.
Compared to similar skills
agent-crdt-synchronizer side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| agent-crdt-synchronizer (this skill) | 1 | 6mo | No flags | Advanced |
| bun | 0 | 6mo | Caution | Beginner |
| miniprogram-development | 37 | 2mo | No flags | Intermediate |
| n8n-code-javascript | 7 | 2mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by ruvnet
View all by ruvnet →You might also like
bun
rcarmo
This project uses Bun as the JavaScript/TypeScript runtime, package manager, bundler, and test runner.
miniprogram-development
TencentCloudBase
WeChat Mini Program development rules. Use this skill when developing WeChat mini programs, integrating CloudBase capabilities, and deploying mini program projects.
n8n-code-javascript
czlonkowski
Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input/$json/$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.
shopify-development
davila7
Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. TRIGGER: "shopify", "shopify app", "checkout extension", "admin extension", "POS extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", "shopify billing", "app subscription", "metafields", "shopify functions"
browser-tools
Whamp
Lightweight Chrome automation toolkit with shared configuration, JSON-first output, and six focused scripts for starting, navigating, inspecting, capturing, evaluating, and cleaning up browser sessions.
nuxt
antfu
Nuxt full-stack Vue framework with SSR, auto-imports, and file-based routing. Use when working with Nuxt apps, server routes, useFetch, middleware, or hybrid rendering.