<< All versions
Skill v1.0.0
currentLLM-judged scan90/100yanacuti1121/yana-ai/automerge-crdt
──Details
PublishedOctober 23, 2026 at 01:47 AM
Content Hashsha256:da64cbd31de211b7...
Git SHA5b39442837f1
──Files
Files (1 file, 3.5 KB)
SKILL.md3.5 KBactive
SKILL.md · 119 lines · 3.5 KB
name: automerge-crdt description: Automerge CRDT for Git-like branching, independent editing, and automatic merge of agent state without a central server. Document fork/merge, change history, and conflict-free concurrent writes. Sources: automerge/automerge (MIT). origin: yana-ai — synthesized from automerge/automerge (MIT) license: Apache-2.0 version: 1.0.0 compatibility: yana-ai >= 1.3.50
/automerge-crdt
When to Use
- Agents independently modify a shared document offline and merge later (Git-like workflow)
- Config or state that multiple agents can modify simultaneously with automatic conflict resolution
- History/audit: inspect every change ever made to a document, who made it, when
- Rollback: revert a document to any prior state via change log
Do NOT use for
- Real-time sync (Yjs [[yjs-crdt-sync]] is lower-latency for live collaborative editing)
- Large binary blobs (Automerge excels at structured data, not raw bytes)
Create and modify a document
javascript
import * as A from '@automerge/automerge'// Create initial documentlet doc = A.from({agentConfig: {tier: 'fast',maxTokens: 2000,rules: [],},})// Modify (always returns new doc — immutable)doc = A.change(doc, 'upgrade tier', d => {d.agentConfig.tier = 'power'd.agentConfig.maxTokens = 8000d.agentConfig.rules.push('token-budget-policy')})console.log(doc.agentConfig.tier) // 'power'
Fork and merge (concurrent changes)
javascript
// Two agents start from the same baselet agentA = A.clone(doc)let agentB = A.clone(doc)// Agent A modifies tieragentA = A.change(agentA, 'agent-A: set tier', d => {d.agentConfig.tier = 'power'})// Agent B concurrently adds a ruleagentB = A.change(agentB, 'agent-B: add rule', d => {d.agentConfig.rules.push('rate-limit-gate')})// Merge: both changes survive (CRDT — no data loss)const merged = A.merge(A.clone(agentA), agentB)console.log(merged.agentConfig.tier) // 'power' (from A)console.log(merged.agentConfig.rules) // ['token-budget-policy', 'rate-limit-gate'] (both)
Sync protocol (incremental updates)
javascript
// Encode changes to send to a peerconst [syncState, syncMessage] = A.generateSyncMessage(doc, A.initSyncState())// Peer applies the messagelet peerDoc = A.receiveSyncMessage(peerDoc, peerSyncState, syncMessage)// Compact save/loadconst saved = A.save(doc) // Uint8Array — full serialized documentconst loaded = A.load(saved) // restore from bytes
Inspect history
javascript
// All changes ever made to the documentconst history = A.getHistory(doc)history.forEach(({ change, snapshot }) => {console.log(`[automerge] ${change.message} at ${new Date(change.timestamp * 1000).toISOString()}`)})// Diff between two versionsconst changes = A.getChanges(docBefore, docAfter)console.log('[automerge] changes since fork:', changes.length)
Anti-Fake-Pass Checklist
❌ Mutating doc directly outside A.change() → mutation silently lost; Automerge docs are frozen❌ A.merge() on docs with no common history → no error but changes may not reconcile as expected❌ Comparing doc values with === after merge → same logical value, different object reference❌ Not saving doc after changes → in-memory only; process restart loses all history❌ Using A.change() for large binary payloads → each byte tracked as a CRDT op; very slow❌ timestamp in change relies on system clock → use logical clocks if clock skew is a concern