Agent skill

Cloud Sync Module

by LedgerHQ in LedgerHQ/ledger-live

Write, review or debug a cloudSyncModule.ts — a CloudSyncDataManager that syncs one slice of user data through Ledger Sync (Cloud Sync).

MITAuto-check passedTesting & QA

Install Cloud Sync Module

skills CLI
$ npx skills add LedgerHQ/ledger-live --skill cloud-sync-module -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install LedgerHQ/ledger-live cloud-sync-module --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/LedgerHQ/ledger-live.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/cloud-sync-module .claude/skills/cloud-sync-module && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
cloud-sync-module
GitHub stars
621
Token cost
~2.4k tokens
SKILL.md length
929 words
Files
1
Skills in repo
50
Repo updated
First seen
Licence
MIT

At a glance

Write, review or debug a cloudSyncModule.ts — a CloudSyncDataManager that syncs one slice of user data through Ledger Sync (Cloud Sync).

  • Works in 6 steps: **resolveIncrementalUpdate… → diffLocalToDistant(emptyLocal, null) →… → Stability: re-diffing against your own… → …
  • Any work on /cloudSyncModule.ts
  • SKILL.md covers The three hooks, Invariants — break one and the…, Risks to evaluate before… and Tests, plus 1 more section
  • Calls pnpm

What it does

Cloud Sync Module is an agent skill from LedgerHQ/ledger-live. Write, review or debug a cloudSyncModule.ts — a CloudSyncDataManager that syncs one slice of user data through Ledger Sync (Cloud Sync). Covers the contract, its invariants, the mandatory contract test, the wiring checklist and the data-loss traps. Use for any work on /cloudSyncModule.ts, createAggregator, or @shared/cloud-sync-module.

Its SKILL.md is about 2.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Integration testing. The repository describes itself as: Mono-repository for Ledger Wallet apps and related packages. The licence is MIT.

When your agent uses it

  • Any work on /cloudSyncModule.ts
  • CreateAggregator
  • @shared/cloud-sync-module

Example prompts

  • “/cloud-sync-module”

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. **resolveIncrementalUpdate short-circuits on incoming == null, on incoming === latest, and on
  2. diffLocalToDistant(emptyLocal, null) → hasChanges: false, or every user who never touched
  3. Stability: re-diffing against your own nextState yields hasChanges: false. No Date.now(),
  4. Round-trip: the comparator must ignore any field applyUpdate cannot reproduce exactly
  5. Convergence: after applyUpdate from an incoming state, diffing against that state reports no
  6. Purity: LocalState comes from Redux and is Immer-frozen. Never mutate — return new objects.

What it can do on your machine

Read from SKILL.md and the folder at commit a3861a2. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Cloud Sync Module loads about 2.4k tokens when it runs. Until then it costs about 92 tokens; SKILL.md has 929 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~92
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from LedgerHQ/ledger-live at commit a3861a2, republished under its MIT licence (© LedgerHQ). 929 words, ~2,373 tokens.

Download SKILL.mdSave it as .claude/skills/cloud-sync-module/SKILL.md (or your agent's skills folder).
name
cloud-sync-module
description
Write, review or debug a `cloudSyncModule.ts` — a `CloudSyncDataManager` that syncs one slice of user data through Ledger Sync (Cloud Sync). Covers the contract, its invariants, the mandatory contract test, the wiring checklist and the data-loss traps. Use for any work on `**/cloudSyncModule.ts`, `createAggregator`, or `@shared/cloud-sync-module`.

Authoring a cloudSyncModule.ts

A module reconciles LocalState (what the app holds, from Redux) with DistantState (what is stored encrypted in Cloud Sync). createAggregator composes every module into one blob shared by all of the user's instances (LWD, LWM, web-tools).

Concepts: 05-wallet-sync-data-manager, then 06-watch-loop for when each hook fires. Steps and a video: cookbook. Testing layers: test-strategy. Contract: @shared/cloud-sync-module. Copy account-name (simplest); accounts for async + injected ctx; recent-addresses for the tolerant-list schema only — its .transform() use is a known bug (see below).

The three hooks

HookSync?RunsMust return
diffLocalToDistant(local, latest)syncevery loop tick (~10s) before push{ hasChanges, nextState } — what to push
resolveIncrementalUpdate(local, latest, incoming)asyncon pull and every tick with incoming === latest{ hasChanges: false } or { hasChanges: true, update }
applyUpdate(local, update)synconly when the above reported changesthe new LocalState (pure, no mutation)

Live under domain/entity/<name>/src/cloudSyncModule.ts beside schema.ts + slice.ts (see domain/entity/README.md). Type it CloudSyncDataManager<LocalState, Update, typeof schema>, with hasChanges: false as const so the union narrows. A 4th generic DistantState defaults to z.infer<Schema> — pass the raw wire type explicitly if your schema transforms, since that is what the hooks actually receive.

Invariants — break one and the loop misbehaves

  1. resolveIncrementalUpdate short-circuits on incoming == null, on incoming === latest, and on incoming being content-equal to local. The reference check alone only covers makeLocalIncrementalUpdate, which passes one object as both args every tick; every pull hands you a freshly decrypted one (incrementalUpdates.ts, makeSaveNewUpdate). Without the content check, an unchanged pull dispatches → re-renders → pushes, forever.
  2. diffLocalToDistant(emptyLocal, null) → hasChanges: false, or every user who never touched the feature creates Cloud Sync data on first launch.
  3. Stability: re-diffing against your own nextState yields hasChanges: false. No Date.now(), no random ids, no unstable key order.
  4. Round-trip: the comparator must ignore any field applyUpdate cannot reproduce exactly (recent-addresses stores lastUsed but never compares it — comparing it would loop forever).
  5. Convergence: after applyUpdate from an incoming state, diffing against that state reports no changes.
  6. Purity: LocalState comes from Redux and is Immer-frozen. Never mutate — return new objects.

Risks to evaluate before writing a line

  • Wiping every instance's data. Persist LocalState with the same lifetime as walletSyncState.version (exportWalletState / importWalletState, both apps). Otherwise a restart finds the version "up-to-date", never pulls, and diffLocalToDistant(empty, latest) pushes an empty state that deletes the data everywhere.
  • A too-strict schema kills sync, or overwrites data. CloudSyncSDK parses the whole aggregate on every pull and push, so one module rejecting another version's payload stops sync for accounts, names, everything. On the persisted path parseDistantState (walletSyncComposition.ts) safeParses and returns null instead — which the loop reads as "no distant state" and pushes over. Stay permissive: optional fields, z.unknown() + safeParse-and-filter for lists, never .strict().
  • A .transform()'s output is discarded in production. Both call sites above do parse — the transform executes — then pass the raw JSON on, to preserve unknown fields. Hooks therefore get un-normalised data typed as the transform's output, a lie TypeScript will not catch; normalise in the hooks instead. The contract suite won't catch it either: it only ever replays states your own diffLocalToDistant produced (the idempotence case runs one back through schema.parse()), never the legacy payload an older version actually wrote.
  • No migrations, ever. The wire format is permanent and shared across app versions: add optional fields only, never rename, repurpose or require a key. Rebuilding nextState from scratch (account-name, recent-addresses) is safe only while your subtree is a total function of LocalState — once it can carry a field you don't own, apply your diff on top of latest as accounts does, or you silently delete the other version's data. recent-addresses already violates this: it drops the ensName its own schema declares.
  • Payload and privacy. One blob holds every module: store the minimum needed to restore the state (descriptors, ids), nothing refetchable, no raw device/user ids (client-ids).
  • Async blocks the loop. resolveIncrementalUpdate runs inside the pull's atomic lock. Network work must be batched and recoverable — see accounts' nonImportedAccountInfos + backoff queue.
  • Injected dependencies? The interface has no ctx: export a bindCtx(ctx) factory, as accounts does.
Show full SKILL.md (263 more words)Show less

Tests

describeCloudSyncModuleContract is mandatory, but a floor rather than a proof. It covers invariants 1-3 and 5, JSON serialisability, a 1MB ceiling, and a 5ms average over 100 calls — for diffLocalToDistant and applyUpdate only. It skips invariant 4 and resolveIncrementalUpdate's cost, and wraps its convergence and applyUpdate cases in if (result.hasChanges), so a module that always answers hasChanges: false passes them silently.

ts
// src/__tests__/cloudSyncModule.test.ts
import { describeCloudSyncModuleContract } from "@shared/cloud-sync-module/moduleRequirements";

describeCloudSyncModuleContract("<name>SyncModule contract", <name>SyncModule, {
  emptyLocalState,
  nonEmptyLocalState,
  matchingDistantState, // optional — always provide it, it unlocks 2 extra checks
});

Then add module-specific cases:

TargetCover
schemavalid payload · garbage/unknown entries tolerated, not thrown · fields written by a future version survive
diffLocalToDistantnull latest · exact match · added · modified · removed · fields it must ignore (invariant 4)
resolveIncrementalUpdatenull incoming · same reference · same content, different reference · real change · the raw payload rather than schema.parse()'s output (the only way to catch the transform trap)
applyUpdateexpected state · does not mutate localData · is reached at all — assert hasChanges: true explicitly instead of trusting the contract suite

Run pnpm --filter @domain/entity-<name> test; copy a sibling entity package's jest config (testEnvironment: "node", roots: ["<rootDir>/src"]).

Wiring checklist

Registration is where the module becomes real — and where the persistence risk above lives.

  1. walletSyncComposition.ts — add the key to createAggregator({...}) and to the hand-maintained walletSyncSchema (they are duplicated; miss the second and your key silently vanishes from WalletSyncDistantState).
  2. Reducers — LWD wallet.core.ts, LWM wallet.ts: reducer, ExportedWalletState, exportWalletState, walletStateExportShouldDiffer, importWalletState.
  3. useWatchWalletSync.ts — LWD, LWM: add the key to localStateSelector and dispatch it in save.
  4. AppAccountsSync.tsx — a third full registration site (its own createAggregator, AggLocalState, localStateSelector). It is also the only place to verify by hand, with several web-tools tabs as separate instances.
  5. Changeset (create-changeset) and a line in scenarios.md.

© LedgerHQ, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/cloud-sync-module of LedgerHQ/ledger-live.

Open the folder on GitHubat commit a3861a2

Compare with similar skills

Cloud Sync Module next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Cloud Sync Module compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Cloud Sync Module this skillLedgerHQ/ledger-live621—~2.4kAutomated safety check: PassMIT
Plugin Testingpolyipseity/obsidian-terminal948—~828Automated safety check: PassAGPL-3.0
Create Modulecartography-cncf/cartography4.1k—~2.5kAutomated safety check: PassApache-2.0
Td Integration Testmarcus/td250—~1.2kAutomated safety check: PassMIT
Integration E2E Testingshinpr/claude-code-workflows690—~3.5kAutomated safety check: PassMIT
JS-in-HTML Testingliaohch3/claude-tap3.3k—~924Automated safety check: PassMIT

Similar skills

  • Plugin Testing

    polyipseity/obsidian-terminal

    Skill for testing Obsidian plugin features in this repository.

    948 GitHub stars~828 tokensUpdated 4 days ago
    Testing & QAAuto-check passed
  • Create Module

    cartography-cncf/cartography

    Author a new Cartography intel module end-to-end (entry point, sync GET/TRANSFORM/LOAD/CLEANUP, declarative data model, integration test, schema docs).

    4.1k GitHub stars~2.5k tokensUpdated today
    Testing & QAAuto-check passed
  • Write integration tests for the td-sync admin API using the TestHarness in internal/api/testharnesstest.go.

    250 GitHub stars~1.2k tokensUpdated 7 days ago
    Testing & QAAuto-check passed
  • Integration E2E Testing

    shinpr/claude-code-workflows

    Integration and E2E test design principles, ROI calculation, test skeleton specification, and review criteria.

    690 GitHub stars~3.5k tokensUpdated 6 days ago
    Testing & QAAuto-check passed
  • JS-in-HTML Testing

    liaohch3/claude-tap

    Tests JavaScript embedded in an HTML file in two layers: pytest checks of the logic ported to Python, and Playwright runs in a real browser for the DOM.

    3.3k GitHub stars~924 tokensUpdated 15 days ago
    Testing & QAAuto-check passed
  • Crosvm Testing

    google/crosvm

    Official

    Skill to assist with running tests and managing test VMs in the crosvm repository.

    1.3k GitHub stars~847 tokensUpdated today
    Testing & QAAuto-check passed

More from LedgerHQ/ledger-live

All 50 skills in this repo
  • Impacting PRs

    LedgerHQ/ledger-live

    Find which open PRs are impacted by a migration/sunset/refactor and notify their authors — blocking review when the old path is already gone from develop, heads-up comment when it is only deprecated…

    621 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Codeownership

    LedgerHQ/ledger-live

    Maintain CODEOWNERS file and team directories. An agent skill from LedgerHQ/ledger-live.

    621 GitHub stars~687 tokensUpdated today
    Auto-check passed
  • Coin Families Contract

    LedgerHQ/ledger-live

    Coin-specific families logic must live in families/. An agent skill from LedgerHQ/ledger-live.

    621 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • Data Layer Advanced

    LedgerHQ/ledger-live

    Structure a Ledger Wallet data layer where one API response serves several entities.

    621 GitHub stars~509 tokensUpdated today
    Auto-check passed
  • Debug Rn Native Crash

    LedgerHQ/ledger-live

    Investigate native React Native crashes (Fabric/Hermes/iOS) in ledger-live-mobile when JS error logs are missing or unhelpful.

    621 GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Detect Data Leaks

    LedgerHQ/ledger-live

    Detect new PII leaks introduced by the current branch. An agent skill from LedgerHQ/ledger-live.

    621 GitHub stars~1.3k tokensUpdated today
    Auto-check passed

Categories

Questions about Cloud Sync Module

What does Cloud Sync Module do?

Write, review or debug a cloudSyncModule.ts — a CloudSyncDataManager that syncs one slice of user data through Ledger Sync (Cloud Sync). Cloud Sync Module is an agent skill from LedgerHQ/ledger-live.ts — a CloudSyncDataManager that syncs one slice of user data through Ledger Sync (Cloud Sync).

When should I use Cloud Sync Module?

Cloud Sync Module fits situations like: any work on /cloudSyncModule.ts; createAggregator; @shared/cloud-sync-module.

How do I install Cloud Sync Module in Claude Code?

Run `npx skills add LedgerHQ/ledger-live --skill cloud-sync-module -a claude-code`. Or copy the skill folder (.agents/skills/cloud-sync-module in LedgerHQ/ledger-live) into .claude/skills/cloud-sync-module in your project. Claude Code loads it when a task matches its description.

How do I install Cloud Sync Module in Codex?

Run `npx skills add LedgerHQ/ledger-live --skill cloud-sync-module -a codex`. Or copy the skill folder (.agents/skills/cloud-sync-module in LedgerHQ/ledger-live) into .agents/skills/cloud-sync-module in your project. Codex loads it when a task matches its description.

Can I use Cloud Sync Module in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add LedgerHQ/ledger-live --skill cloud-sync-module -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cloud-sync-module, .gemini/skills/cloud-sync-module, .github/skills/cloud-sync-module and .opencode/skills/cloud-sync-module in your project.

What does Cloud Sync Module need to run?

Going by SKILL.md and its folder, Cloud Sync Module needs the command-line tools its instructions call (pnpm).

Does Cloud Sync Module access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Cloud Sync Module safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Cloud Sync Module use?

Cloud Sync Module is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Cloud Sync Module use?

About 2.4k tokens (SKILL.md is roughly 9.5k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Cloud Sync Module?

Skills that share tags, products or a category with Cloud Sync Module: Plugin Testing (polyipseity/obsidian-terminal, 948 stars), Create Module (cartography-cncf/cartography, 4.1k stars), Td Integration Test (marcus/td, 250 stars) and Integration E2E Testing (shinpr/claude-code-workflows, 690 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Cloud Sync Module?

LedgerHQ (a GitHub organization) maintains it in LedgerHQ/ledger-live, which has 621 GitHub stars. The repository holds 50 skills in this directory. The repository was last updated on October 7, 2026.

Source: LedgerHQ/ledger-live on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.