omp-sync0.1.4
Encrypted per-session sync for the omp coding agent (S3/R2 compatible).
Built for omp
The author tagged this package omp-package.
Reports 0
No reports yet.
Readme
omp-sync — Encrypted Per-Session Sync for omp
omp-sync syncs your omp coding-agent
sessions across machines through any S3-compatible storage (AWS S3,
Cloudflare R2, IDrive E2, MinIO, …).
Every session JSONL is stored as its own object, wrapped as
AES-256-GCM(gzip(plaintext)) and bound to its object key. Objects are
content-addressed and immutable: a failed push can never corrupt the
previously published generation, and pulls cryptographically verify every
byte before it touches disk.
Install
omp plugin install npm:omp-sync
Quick start
Create a bucket on any S3-compatible storage and grab the endpoint, region, and access keys.
Write the config to
<agentDir>/omp-sync.local.json(default agent dir:~/.omp/agent):{ "endpoint": "https://<bucket-host>", "bucket": "<bucket>", "region": "auto", "accessKeyId": "...", "secretAccessKey": "..." }Every field can also come from the environment (
OMP_SYNC_ENDPOINT,OMP_SYNC_BUCKET,OMP_SYNC_REGION,OMP_SYNC_ACCESS_KEY_ID,OMP_SYNC_SECRET_ACCESS_KEY).Generate the encryption key once per machine set — it is shared by all machines but never leaves them (it is not synced, ever):
echo "export OMP_SYNC_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\"" >> ~/.zshrcIn omp, run:
/omp-sync doctor…should report
config ok,encrypt key ok (32-byte),bucket reachable. Then on your first machine:/omp-sync pushOn the second machine:
/omp-sync pull
Commands
| Command | What it does |
|---|---|
/omp-sync status |
Local vs remote diff. Never writes sessions or remote objects (a one-time local base-state migration may run after upgrades). |
/omp-sync push |
Upload new/changed local sessions (last-writer-wins on first contact). |
/omp-sync pull |
Download remote sessions (never touches your open session file). |
/omp-sync blobs |
Full two-way reconcile of the attachment blob store. |
/omp-sync doctor |
Config + key + bucket + lock diagnostics. Works without a config. |
/omp-sync config |
Show resolved (secret-redacted) configuration. |
/omp-sync unlock |
Inspect/remove a stale lock. Works without a config. |
Automation (no commands needed day to day):
- After each turn, the current session file is pushed (debounced, one small upload — no shutdown race).
- On startup, an opt-in pull fetches other sessions (
autoPull, off by default, never overwrites the open file). - On shutdown, a best-effort final push of the current file runs inside omp's handler budget.
Conflict handling
When both sides edited the same session since the last sync, nothing is
silently overwritten: the remote version is preserved next to your file as
<session>.conflict-<timestamp>.jsonl, your bytes stay untouched, and the
next push adopts your side. The copy syncs up like any other session, so
both versions survive on every machine.
Configuration reference
omp-sync.local.json (or OMP_SYNC_* env vars):
| Key / env | Default | Meaning |
|---|---|---|
endpoint / OMP_SYNC_ENDPOINT |
— (required) | Storage endpoint incl. scheme. If the endpoint's first host label equals the bucket name (e.g. bucket s3 with https://s3.example.com), embed the bucket in the host instead to force virtual-hosted addressing |
region / OMP_SYNC_REGION |
auto |
SigV4 region |
accessKeyId/secretAccessKey |
— (required) | Storage credentials |
prefix / OMP_SYNC_PREFIX |
omp-sync/ |
Bucket namespace for all objects |
autoPush / OMP_SYNC_AUTO_PUSH |
true |
Debounced per-turn push of the current session |
autoPull / OMP_SYNC_AUTO_PULL |
false |
Pull other sessions on startup |
debounceMs |
5000 |
Turn-end push debounce |
includeBlobs / OMP_SYNC_BLOBS |
true |
Sync blob:sha256: attachments alongside sessions |
maxBlobBytes |
33554432 |
Oversized blobs are skipped with a warning on push; sessions referencing them fail to pull until the limit is raised |
pathMap / OMP_SYNC_PATHMAP |
[] |
[{from, to}] prefix rewrites for trees that differ beyond the home root (home shapes /Users/u, /home/u, /root reconcile automatically) |
OMP_SYNC_ENCRYPTION_KEY |
— (required) | Base64 of 32 random bytes, shared across machines |
OMP_SYNC_TIMEOUT_MS |
15000 |
Per-request network timeout |
How it works
- Keys derive from the session header's
cwd, never from the on-disk bucket directory (which is lossy). Two omp machines converge on the same keys for the same project, across macOS and Linux: any POSIX home shape (/Users/u/...,/home/u/...,/root/...) folds tohome/...regardless of which machine encoded it, username included or not. - Change tracking is sha256-of-plaintext plus a local agreed-base, with mtime tie-breaking only on first contact.
- Manifest (
<prefix>manifest.json, itself sealed) is a truthful index of remote objects, updated withIf-Matchoptimistic concurrency and bounded retries — concurrent pushes merge instead of clobbering. - Pulls land in omp's own sessions tree (
<agentDir>/sessions/<omp bucket>/, or$XDG_DATA_HOME/omp/sessions/...when omp is XDG-redirected). Project working directories are never written to. - Deletions never propagate: the store is additive; deleting locally and pushing does not delete remotely.
Security notes
- Payloads are
AES-256-GCM(gzip(plaintext))with a fresh 96-bit nonce per object; session, blob, and manifest envelopes are each bound (AAD) to their object key, so swapped or cross-prefix objects are rejected. - The storage operator sees only opaque blobs, content hashes, sizes, and modification times — never prompts, code, or file contents (note: object keys do reveal the sanitized project directory layout and per-object sizes, which are listable).
- Downloads are hash-verified and size-bounded before they reach disk; oversized or mismatched objects are refused, never partially applied.
- Credentials live in
omp-sync.local.json/ env on each machine. The encryption key lives only inOMP_SYNC_ENCRYPTION_KEY.
Requirements
- omp coding agent (developed and tested against omp
18.1.13). - Node 22+ or Bun (for the
fetch,AbortSignal.timeout, andPromise.withResolversruntimes used internally).
License
MIT — see LICENSE.