smithery/benderfendor

local-first-sync

Implement a local-first + backend-sync data flow (create/update/delete) with tombstones, dedupe, and safe retry. Use when building offline-capable entities (highlights, annotations, queue items, notes) that must persist immediately in localStorage while syncing to a server.

Installation

$ npx skills add smithery/benderfendor --skill local-first-sync

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 3,641 B
  • docs SUMMARY.md 298 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Local-First Sync

Overview

This skill provides a reusable, minimal pattern for local-first persistence with background server sync, including dedupe/merge rules, tombstones for deletes, and a safe retry model that avoids infinite loops.

Use it when the user requires:

  • Instant local persistence (works offline)
  • Backend as eventual consistency store
  • Create/update/delete support
  • Explicit handling for failures and retries

Assumptions (state explicitly)

  • Whether backwards compatibility is required.
  • Whether the backend supports idempotency keys or client-provided ids.
  • What determines identity (server id, natural key, or fingerprint).

Data Model

Store local records with:

  • client_id (UUID)
  • server_id?
  • sync_status: synced | pending | failed
  • pending_op: create | update | delete
  • last_error? (string)
  • localupdatedat (ISO)
  • deleted? (tombstone)

Recommendation: keep local records as a superset of server records (so rendering code can stay simple).

Storage Keys

  • Prefer versioned keys: entity:v1:<entityscopeor_id>
  • Scope keys by natural grouping (e.g. highlights:v1:${article_url}) to avoid large global blobs.

Core Workflow

1) Read path (open modal / load view)

  1. Load local state immediately and render.
  2. Fetch server state.
  3. Merge + dedupe server into local.
  4. Persist merged local state.
  5. Kick off background sync for pending/failed ops.

2) Write path (create/update/delete)

Always do the local write first:

  1. Create/update/delete in local store; mark pendingop and syncstatus=pending (or keep tombstone for delete).
  2. Render from local store.
  3. Trigger background sync.

3) Sync loop (background)

For each record with pending_op:

  • create: POST to server, then store returned server_id and clear pending fields.
  • update: PATCH to server (requires server_id), clear pending fields.
  • delete: DELETE on server if server_id exists; then remove local record.

Failure behavior:

  • Mark local record syncstatus=failed and set lasterror.
  • Do not tight-loop retries; retry on explicit user action (button) and optionally on reconnect.

Merge + Dedupe Strategy

Identity approach (strong → weak):

  1. server_id
  2. Fingerprint of stable fields (example): ${start}:${end}:${normalized(text)}

Merge rules (common default):

  • Keep local tombstones: if local says deleted and pending_op=delete, do not resurrect from server.
  • Prefer newer note/edit: compare localupdatedat vs server updated_at if available.
  • Preserve local clientid and syncstatus.

UI Guidance

  • Show sync state near the entity list: Synced | Saving | Offline | Failed.
  • Add a Retry sync button when failed.
  • Don’t block user writes when offline; queue them.

Testing Checklist

  • Dedupe: server merge doesn’t create duplicates.
  • Tombstones: pending delete doesn’t resurrect.
  • Offline: create/update/delete marks pending and persists locally.
  • Failure: marks failed and records last_error.
  • Retry: transitions failed → pending → synced.

Debug Logging Guidance

  • Log one-line summary per sync run (counts: pending/failed/synced).
  • Log failing entity clientid, serverid, pending_op, and request URL.
  • Avoid logging full article text or other large/PII payloads.