Skip to content

Concepts & glossary

agentsync borrows its mental model from chezmoi: you keep one canonical source of truth, you apply it to produce the real files agents read, and when something edits those files out from under you, agentsync detects the drift and helps you reconcile it.

Read this page once and the rest of the docs — the architecture, the user guide, and agentsync --help — will click into place.


Everything agentsync does is a comparison between three states of the same logical thing (an MCP server, a memory file, a plugin’s slash command):

StateWhat it isWhere it lives
SourceWhat you committed — the intent.~/.agentsync/ (a git repo you own)
TargetWhat the source renders to for a given agent, computed fresh in memory at apply time.nowhere on disk — it’s transient
DestinationWhat is actually on disk in each agent’s native config right now.~/.claude.json, ~/.config/opencode/, …
Source Target Destination
~/.agentsync/ render (in-memory) write ~/.claude/…
hand-edited ───────▶ per-agent ───────▶ ~/.config/opencode/…
TOML + .md FileOps native config files
▲ │
│ capture │
└────────────────────────────────────────────────┘
(write native edits back into source)

The genius of the model is that drift is just a hash comparison:

  • Drift — the destination changed since agentsync last wrote it (hash(destination) ≠ hash(last-applied)). Something edited the native file.
  • Source change — you edited the canonical source (hash(target) ≠ hash(last-applied)). A normal pending change.
  • Conflictboth happened. agentsync stops and asks you to reconcile.

The single directory you own and (optionally) commit to git. It holds small, hand-editable TOML files (one MCP server per file, one plugin per file) plus markdown for memory and skills. Override its location with AGENTSYNC_HOME. There is no hidden internal representation — the Go structs that parse these TOML files are the canonical model.

A per-agent translator. Each adapter knows how to render the canonical model into one agent’s native config format and how to ingest that native config back into the canonical model. Claude and OpenCode are real adapters in v1.0; Codex and Cursor are registered but no-op (see the capability matrix). Adding an agent means adding an adapter — the canonical schema never changes.

agentsync apply runs the render pipeline: load the source → resolve secrets → ask each enabled adapter to project the model into a set of file operations → write them atomically → record hashes in state. Apply is local-only and offline — it never hits the network.

The reverse direction. Ingest reads an agent’s native config back into the canonical model; capture persists that back into ~/.agentsync/. This is how agentsync import (pull a native edit into the source) and the reconcile [w]rite-back action work. All write-back funnels through one place (internal/capture) so secrets get re-referenced and never leak as cleartext.

For every managed item, agentsync holds three hashes — source (H_src), last-applied (H_applied, from state), and destination (H_dest) — and classifies the item into exactly one of nine cases:

ClassMeaningWhat apply does
cleanall three agreenothing
pendingyou changed the sourcewrite the new source
driftthe destination was editedblock; suggest reconcile
convergedsource and dest changed to the same valuerefresh state silently
conflictsource and dest changed to different valuesblock; require reconcile
newbrand-new item, nothing on diskcreate
foreign-collisiona pre-existing file agentsync didn’t writeback it up, then write
orphanremoved from source, still on diskdelete
orphan-driftedremoved from source, but the dest was also editedwarn; ask for explicit action

Granularity is per-key for structured files (JSON/JSONC/TOML, tracked by JSON pointer) and per-file for everything else. Keys agentsync never wrote are foreign keys — surfaced for awareness but never touched.

The interactive merge UX for drift and conflicts. For each drifting item you choose [w]rite-back (adopt the dest edit into source), [o]verride (re-impose source), [s]kip, [i]gnore (add to ignore.toml), [d]iff, or [q]uit. Bulk hotkeys (W/O/S) and non-interactive flags (--auto-writeback, --auto-override, --auto-safe) exist for scripting.

Config applies at user scope (the whole machine) or project scope (one repo). A repo opts in by dropping a .agentsync.toml marker at its root; agentsync walks up from the current directory to find it. The marker can add project-only MCP servers, disable plugins, and merge extra memory.

The canonical source never stores cleartext credentials. You write ${secret:github.token} or ${env:HOME}; agentsync resolves these at apply time — ${secret:…} from an age-encrypted file, ${env:…} from the environment. The public recipient key is safe to commit; the private identity key is per-machine and never backed up for you.

A central invariant: a resolved cleartext secret must never be written back into the canonical source. The type system enforces this — see architecture and CLAUDE.md.

Gitignored bookkeeping: targets.json (the last-applied hashes that make drift detection possible), the apply lock, the two-phase write staging dir, first-apply backups, and the marketplace/plugin cache. Keys are stored ${HOME}-relative so state is portable across machines.

A marketplace is a registry of plugins (Claude’s marketplace format). A plugin is a bag of components — MCP servers, skills, subagents, commands, hooks, LSP servers. Projection translates each component independently into each target agent, which is where fan-out happens: install once, land on every enabled agent that supports the component.

Every apply, verify, and explain ends with a report showing, per plugin per agent, what landed:

  • ✓ native — full fidelity; the agent has the concept directly.
  • ◐ projected — lossy but defensible translation, explicitly reported.
  • ✗ skipped — no honest translation exists; logged so it’s never silent.

agentsync update is the only command that touches the network: it polls marketplaces, refreshes the cache, and recomputes version pins. apply then runs entirely from cache. This split keeps apply fast, reproducible, and offline-safe.


you edit ~/.agentsync/ an agent edits its own config
│ │
▼ ▼
agentsync apply ──writes──▶ native config ──drift──▶ agentsync status
(source ▶ dest) agentsync diff
agentsync reconcile / import
(dest ▶ source capture)
agentsync update ──network──▶ refresh marketplace cache & pins
(then apply renders from cache, offline)

Next: see the architecture for how these are implemented, or jump straight to the user guide to get hands-on.