Metadata-Version: 2.4
Name: elesync
Version: 1.3.2
Summary: Local-first, MCP-native unified memory vault — your AI memory as files you own, shared across every model.
Author: Alphanymous
License: MIT
Project-URL: Homepage, https://github.com/darknodebros/EleSync
Project-URL: Repository, https://github.com/darknodebros/EleSync
Project-URL: Issues, https://github.com/darknodebros/EleSync/issues
Keywords: mcp,ai-memory,local-first,claude,chatgpt,gemini,grok,deepseek,memory,elesync
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: mcp
Requires-Dist: mcp[cli]>=1.2.0; extra == "mcp"
Provides-Extra: semantic
Requires-Dist: fastembed>=0.3.0; extra == "semantic"
Provides-Extra: encryption
Requires-Dist: pynacl>=1.5; extra == "encryption"
Provides-Extra: watch
Requires-Dist: watchdog>=4.0; extra == "watch"
Provides-Extra: dev
Requires-Dist: mcp[cli]>=1.2.0; extra == "dev"
Requires-Dist: fastembed>=0.3.0; extra == "dev"
Requires-Dist: pynacl>=1.5; extra == "dev"
Requires-Dist: watchdog>=4.0; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/darknodebros/EleSync/master/assets/logo-small.png" alt="EleSync — a neon circuit elephant" width="220">
</p>

# 🐘 EleSync

### Tired of re-explaining yourself to every AI? I bet you are, that's why we created EleSync, a One command setup memory vault, nicely encrypted, accessible to continue your conversations without repeating yourself to every model.

🔰 **You're not a developer?** Perfect — EleSync is designed for regular people first. Read the **[plain-English setup guide](SETUP.md)** — covers everything from first install to USB vault, step by step. ~10 minutes, no coding knowledge needed.

<p align="center">
  <img src="Elesyncdemo.gif" alt="EleSync demo" width="640">
</p>

[![PyPI](https://img.shields.io/pypi/v/elesync.svg)](https://pypi.org/project/elesync/)
[![CI](https://github.com/darknodebros/EleSync/actions/workflows/ci.yml/badge.svg)](https://github.com/darknodebros/EleSync/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-native-8A2BE2.svg)](https://modelcontextprotocol.io)
[![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=flat&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/Darknodebros)

<!-- mcp-name: io.github.darknodebros/elesync -->

You use Claude, ChatGPT, and Gemini. Each one knows a different slice of you, and none
of them share. **EleSync** is one private vault on your own computer that every AI
plugs into — so anything one AI learns about you is instantly available in all of them.

> No accounts. No cloud. No subscriptions. Your memories are plain text files on your
> own disk — readable in any text editor, synced however you already sync files.

```
Tell ChatGPT something  →  it lands in your vault  →  Claude already knows it.
```

**Two commands and you're done:**

```bash
pip install "elesync[mcp]"   # install
ele onboard                  # connect to Claude Desktop — that's it
```

**Want it fully automatic?** Install the watch extra once — after that, just export from any AI and Claude already knows:

```bash
pip install "elesync[watch]"
ele watch --autostart        # runs in the background from now on
```

**Stable at v1.3** — a 179-test suite, CI across Python 3.10–3.14 (including a dev-extras job
covering encryption and real-model semantic recall) plus ruff lint/format and mypy type-checking,
and a public surface (CLI commands, MCP tools, vault layout, export format) you can build on
without breakage inside 1.x. See the [CHANGELOG](CHANGELOG.md) for the full history.

---

## The one-sentence idea

**EleSync *is* an MCP server sitting on top of a local-first file store.**

Because MCP is now supported natively by OpenAI, Google and Anthropic, a single server
makes one vault you own readable and writable by all of them — live and bidirectionally.

## Who it's for

EleSync is for **people who _use_ AI — not engineers building agents.**

"AI memory" is having a moment, but most of it is **developer infrastructure**: memory layers
and SDKs you wire into agents you're coding (mem0, Letta, Zep), or autonomous-agent products
that manage their own memory (Manus). Powerful — *for builders.*

EleSync is the everyday-user end of that spectrum:

- **No code, no agent to build, no cloud account.** Install it, run `ele onboard`, done.
- **It plugs into the apps you already talk to** — Claude, ChatGPT, Gemini — instead of asking you to adopt a new one.
- **The memory is yours:** plain markdown files on your disk, not rows in someone else's database.

If you've ever had to re-explain yourself to a fresh chat, EleSync is for you. If you're wiring
a memory store into a fleet of autonomous agents, one of the developer tools above is the better fit.

## Why this, when Anuma / Memory Forge exist?

The "unified memory layer" concept is validated (Anuma crossed ~60k users). The gap they
leave open is the wedge here:

| | Anuma | Memory Forge | **EleSync (this)** |
|---|---|---|---|
| Open / inspectable | ✗ closed app | partial | ✓ your files, your code |
| MCP server | ✗ none | ✗ | ✓ core feature |
| Keep using Claude/ChatGPT/Gemini apps | ✗ must switch in | n/a | ✓ they connect to you |
| Live read **+ write back** | within app | ✗ static file | ✓ |
| Infrastructure | crypto/wallet | browser only | ✓ zero — files + SQLite |

"Eco-friendly and easy" = no server, no database to run, no blockchain/wallet. Markdown + SQLite.

## Architecture

```
  ChatGPT export ─┐
  Claude export  ─┤   adapters/normalize.py      ┌─ notes/*.md   (source of truth, Obsidian-compatible)
  Gemini export  ─┼─►  → MemoryItem (schema) ──►  │
  manual notes   ─┘                               └─ index.db    (SQLite + FTS5 full-text search)
                                                         │
                                                         ▼
                                              mcp_server.py  (the connector)
                                                         │
                       ┌─────────────────────────────────┼─────────────────────────────────┐
                   Claude Desktop                     ChatGPT                            Gemini / any MCP client
                   recall / remember / forget / memory_status / list_scopes
```

- **`elesync/models.py`** — the normalized `MemoryItem` schema every source maps into.
- **`elesync/store.py`** — local-first store: markdown files + SQLite FTS index, with
  content-hash dedup (re-importing is idempotent).
- **`elesync/normalize.py`** — tolerant ingest adapters that sniff each provider's export shape.
- **`elesync/mcp_server.py`** — exposes the vault over MCP (`recall`, `remember`, `forget`, `memory_status`, `find_conflicts`, `list_scopes`).
- **`elesync/cli.py`** — `import`, `search`, `add`, `stats`, `reindex`, `sync`, `conflicts`, `scope`, `scopes`, `embed`, `export`, `encrypt`, `decrypt`, `serve`.
- **`elesync/embeddings.py`** — optional semantic recall: vectors stored alongside the
  SQLite index, brute-force cosine, hybrid keyword+vector ranking. Degrades to keyword-only.
- **`elesync/crypto.py`** — optional encryption at rest: argon2id key + libsodium per-file
  AEAD; the index is a rebuildable cache. Plaintext stays the default.

## Install

Works on **macOS, Windows, and Linux**. Needs **Python 3.10+** and **[Claude Desktop](https://claude.ai/download)**.

> **Not a developer?** The [plain-English setup guide](SETUP.md) walks through every step, including where to get your memory export files from ChatGPT, Claude, and Gemini.

**1 · Install**

```bash
pip install "elesync[mcp]"
```

> No Python yet? Download from **[python.org/downloads](https://www.python.org/downloads/)** — on Windows tick **"Add Python to PATH"** during install. If `pip` isn't found: use `py -m pip …` (Windows) or `python3 -m pip …` (Mac/Linux).

```bash
ele --version          # → EleSync 1.3.0
```

**2 · Import your memories from ChatGPT / Claude / Gemini**

```bash
ele import ~/Downloads/chatgpt_memory.json   --source chatgpt
ele import ~/Downloads/claude_export.json    --source claude
ele import ~/Downloads/gemini_memory.json    --source gemini
```

Re-importing is always safe — duplicates are skipped automatically.

**3 · Connect to Claude Desktop — one command**

```bash
ele onboard
```

Finds the Claude config file automatically on macOS/Windows/Linux, backs it up, and wires EleSync in. Then **fully quit and reopen Claude Desktop** (not just close the window — quit the whole app).

**4 · Verify**

```bash
ele doctor
```

Then ask Claude: *"What do you remember about me?"* — that's your live confirmation. 🎉

<details>
<summary>Install from source instead (for contributors / latest <code>master</code>)</summary>

```bash
git clone https://github.com/darknodebros/EleSync.git
cd EleSync
pip install -e ".[mcp]"
```
No git? Use the green **Code → Download ZIP** button on the repo page, unzip, and run the `pip install` from inside the folder.
</details>

<details>
<summary>Prefer to wire Claude by hand?</summary>

`ele onboard --print-only` prints the exact block to paste into your Claude Desktop config file:

```json
{
  "mcpServers": {
    "elesync": {
      "command": "python",
      "args": ["-m", "elesync.mcp_server"],
      "env": { "ELESYNC_DIR": "/path/to/your/EleSyncVault" }
    }
  }
}
```
</details>

## Use it with other AI apps (any MCP client)

EleSync is a standard **MCP server**, so the *same vault* works with any app that can act as an MCP client — not just Claude Desktop. Tools like **[Manus](https://manus.im)**, Cursor, and other MCP-capable apps can connect and `recall` / `remember` against your vault live — **no adapter, no export/import**.

The how-to is the same everywhere: point the client at EleSync's MCP server. Print the config block with

```bash
ele onboard --print-only
```

then add that `mcpServers` entry wherever the app keeps its MCP config (in Manus: **Settings → Connectors**; in Cursor: its MCP settings), with `ELESYNC_DIR` pointing at your vault. Done — that app now reads and writes the one vault every other AI shares.

> Note: the `ele import` adapters are for chat assistants that expose a **memory export**. Three platforms offer verified exports today (ChatGPT, Claude, Gemini); four more have adapters ready for when exports become available (Grok, DeepSeek, Perplexity, Copilot). Agent tools like Manus don't offer one — and don't need it: they connect as a live MCP client instead.

## Everyday use

Import what your AIs already exported, then search across all of them at once:

```bash
ele import ~/Downloads/chatgpt_memory.json --source chatgpt
ele import ~/Downloads/claude_export.json   --source claude

ele search "project notes"
ele add "Prefers direct, no-fluff answers" --type preference
ele stats

ele summary                    # see everything your vault knows about you
ele summary --short            # quick overview — counts + top facts
ele export vault-backup.json   # back up / move your whole vault
ele reindex                    # rebuild the search index from notes/*.md
ele forget <id>                # delete a memory by full id or 8-char prefix

# Auto-import: watches ~/Downloads and imports exports as they arrive
pip install "elesync[watch]"
ele watch                      # Ctrl+C to stop
ele watch --autostart          # register as a login item (runs from boot)
```

> The file paths above are just examples — point them at wherever your export files are. EleSync keeps its vault at `~/EleSyncVault`; to use a different folder set `ELESYNC_DIR` (**macOS/Linux:** `export ELESYNC_DIR=~/my-vault` · **Windows PowerShell:** `$env:ELESYNC_DIR="C:\path\to\my-vault"`).

Now Claude can `recall` your full cross-AI context at the start of any chat and `remember`
new durable facts back into the same vault that ChatGPT and Gemini read from.

### Semantic recall (optional)

By default, search is keyword-based (SQLite FTS) — no dependencies, no model. Install the
optional extra to also match on *meaning*, so `recall` finds the right memory even when the
wording differs:

```bash
pip install "elesync[semantic]"     # adds a small local ONNX model (no PyTorch, no cloud)
ele embed                            # embed existing memories (first run downloads the model)
ele --semantic search "where do they live"   # → surfaces "Based in Westbrook"
```

Vectors are stored as float32 blobs in the same SQLite index — no new datastore — and ranking
fuses keyword + vector hits (Reciprocal Rank Fusion), so exact matches stay strong while
semantically-close memories surface too. Set `ELESYNC_SEMANTIC=1` to make it the default (the
MCP server picks this up too). Without the extra, everything works exactly as before.

### Encryption at rest (optional)

Plaintext markdown is the default (so the vault stays Obsidian-readable). If you'd rather your
notes be unreadable on disk — a stolen laptop, a leaked backup, a synced folder — encrypt the
vault with a passphrase:

```bash
pip install "elesync[encryption]"
ele encrypt          # encrypts notes/*.md → *.md.enc, drops the plaintext index
```

Each note is encrypted with XSalsa20-Poly1305 (libsodium); your passphrase is stretched to a key
with **argon2id** (the key is never written to disk — only the salt + params live in `vault.json`).

**Use it while it stays encrypted.** You don't have to decrypt the whole vault to use it — just
supply the passphrase and EleSync unlocks it *live*, building the search index **only in memory**
(nothing plaintext ever touches the disk):

```bash
ELESYNC_PASSPHRASE=… ele search "project notes"   # or it'll prompt you
ele add "Prefers concise answers" --type preference   # writes a new *.md.enc, still encrypted at rest
ele decrypt                                        # permanently revert to plaintext when you want
```

The **MCP server** does the same: set `ELESYNC_PASSPHRASE` in its config and it serves the
encrypted vault live (key held in memory for the session). `ele decrypt` is only for permanently
turning encryption back off.

> **Threat model — be clear-eyed.** This protects data **at rest** (stolen disk, leaked backup,
> synced folder). It does **not** protect a running process, or a host where your passphrase is in
> memory or in an env var. Lose the passphrase and the data is unrecoverable.

### Scoped sharing (optional)

One vault, but not every AI needs to see every memory. Your **writing style** is fine for any
assistant; your **legal** or **health** notes are not. Scopes let a single vault present a
different slice of itself to each client — the everyday-user version of what Anuma gates by
category, with zero new infrastructure.

The model is one rule: a memory with **no scope is `general`** — visible to everyone, exactly as
today — and a memory **with** a scope is visible only to a client *granted* that scope. Scoping is
opt-in restriction, so every memory you already have is unaffected.

```
# tag memories into compartments (or scope an existing one in place)
ele add "Lawsuit vs Acme; settle at 10k" --type fact --scopes legal
ele scope 1dc24751 writing,coding        # re-scope by id/prefix (never forks identity)
ele scopes                               # list compartments with counts

# audit exactly what a given client would see, before you trust it
ele --as general,writing scopes           # which compartments are visible — legal/health absent
ele --as general,writing search Acme      # the legal "Acme" memory above won't surface
```

Each client carries a **grant** as an env var — the same local-first pattern as `ELESYNC_DIR`:
`ELESYNC_SCOPES=general,writing` lets that client see general + writing and nothing else, and
`ELESYNC_WRITE_SCOPE=writing` files everything it remembers into the writing compartment. **Unset
means unrestricted** (the full vault), so existing setups are unchanged. `ele onboard` wires it for
you:

```
# Claude Desktop: writing + general only
ele onboard --scopes general,writing --write-scope writing

# a second, legal-scoped connection in the SAME client (distinct --name)
ele onboard --scopes general,legal --write-scope legal --name elesync-legal
```

Every read path is grant-aware — `recall`, `find_conflicts`, `memory_status` and even `forget`
filter by the client's scope, so a scoped client can't read *or infer the existence of* anything
outside its compartment (counts and conflict output never leak hidden memories). An AI can discover
its own compartments with the `list_scopes` MCP tool.

> **Be clear-eyed about the boundary.** Scopes are *organisational hygiene*, not a cryptographic
> wall: the boundary is the per-client config **you** control, and a client you point at the vault
> with no `ELESYNC_SCOPES` set sees everything, by design. For data that must be unreadable even to
> a process that opens the vault, use **encryption at rest** — the two compose (an encrypted vault
> still scopes).

### Spotting contradictions (provenance)

When two AIs record facts that disagree — *"Based in Westbrook"* (from Claude) vs *"Based in
Portland"* (from ChatGPT) — EleSync **surfaces the conflict with provenance** instead of silently
treating both as true:

```bash
ele conflicts
# Found 1 possible conflict(s) — review and `forget` the wrong one:
# 1. Same topic, different values:
#    - [claude, 2026-03-12] Based in Westbrook  (id=ff85b854)
#    - [chatgpt, 2026-05-01] Based in Portland   (id=efbecb07)
```

`recall` flags it inline too (so a connected AI notices and can ask you), and there's a
`find_conflicts` MCP tool. Detection is a deliberately simple, **local** heuristic — it flags
`fact`s that look like they're about the same thing but differ — so treat results as *candidates to
review*, not verdicts. EleSync only ever **surfaces**; you resolve with `ele forget <id>`.

## Portable USB vault (carry your memory anywhere)

Plug in a USB drive, run one command, and your encrypted AI memory goes with you everywhere.
On any machine with Python, `python RUN_ME.py` installs EleSync and connects it to Claude — no
prior knowledge needed.

```bash
pip install "elesync[mcp,encryption]"

# One-time setup on your USB drive
ele usb install /Volumes/MyUSB          # macOS
ele usb install E:\\                    # Windows
ele usb install /media/myusb            # Linux
# Enter a passphrase when prompted — this encrypts everything on the drive

# Later: import your AI memories onto the drive
ele --vault /Volumes/MyUSB/EleSyncVault import chatgpt_memory.json --source chatgpt
ele --vault /Volumes/MyUSB/EleSyncVault import claude_export.json  --source claude
ele --vault /Volumes/MyUSB/EleSyncVault import gemini_memory.json  --source gemini

# Connect to Claude Desktop (on any machine)
ele usb attach /Volumes/MyUSB           # prompts for passphrase, wires Claude Desktop
# → Fully quit and reopen Claude Desktop

# Before unplugging
ele usb detach /Volumes/MyUSB           # removes Claude Desktop entry
ele usb eject  /Volumes/MyUSB           # safe-eject

# Other commands
ele usb list                            # see all removable drives
ele usb status /Volumes/MyUSB          # check vault health & memory count
```

**On a new machine** — plug in the drive and run:

```bash
python /Volumes/MyUSB/RUN_ME.py
```

That's it. `RUN_ME.py` is a self-contained script the drive carries with it: it installs
EleSync via pip (if needed) and wires the USB vault into Claude Desktop — no prior knowledge
of pip or MCP required.

**Security model** — USB vaults are *always* encrypted (unlike the main vault where encryption
is opt-in). Your passphrase is the only thing that unlocks the vault; a lost or stolen drive
exposed nothing without it. The same XSalsa20-Poly1305 + argon2id encryption used by
`ele encrypt` is applied automatically at install time.

> The USB vault is a standard EleSync vault at `<drive>/EleSyncVault`. You can run any normal
> `ele` command against it by passing `--vault <drive>/EleSyncVault`. Nothing is synced
> automatically between the USB vault and your main vault — use `ele export` + `ele import` to
> move memories between them.

## Local web UI

No terminal needed once EleSync is installed — `ele web` opens a clean browser-based
vault explorer:

```bash
ele web                 # opens http://127.0.0.1:7477 in your browser
ele web --port 8080     # custom port
ele web --no-browser    # start server without auto-opening browser
```

**What you get:**

| Tab | What it does |
|---|---|
| **Dashboard** | Total memories, AI source breakdown, FTS / embedding status |
| **Browse** | Paginated list with live filter, source & type dropdowns |
| **Search** | Instant full-text search across all memories |
| **Add Memory** | Manually add a memory (content, source, type, tags) |
| **Import** | Drag-and-drop a ChatGPT / Claude / Gemini / Grok export JSON |

Click any memory to open a slide-in editor — update content, type, tags, or delete it.

**Zero extra dependencies** — pure Python stdlib `http.server`. Works with encrypted
vaults (prompts for passphrase at startup). Binds to `127.0.0.1` only.

---

## Sync across devices

Your vault is **just a folder** (`notes/*.md` + a small `vault.json`), so sync it however you
already sync files — **git, iCloud, Syncthing, Dropbox, Drive**. No server, no account.

Two things to know:

- **Don't sync `index.db`** — it's a local, rebuildable cache. `ele sync` drops a `.gitignore` in
  your vault so git skips it automatically; for other tools, just exclude `index.db`.
- **After pulling changes on another device, run `ele sync`.** It rebuilds the index from the notes
  and tells you what changed (e.g. *"2 added, 1 changed, 0 removed"*). Plain `ele reindex` does the
  rebuild silently if you don't care about the diff.

```bash
# device B, after a git pull / iCloud sync
ele sync        # → "1 added, 0 changed, 0 removed. Vault holds 42."
```

**Encrypted vaults sync safely** through even an untrusted service — the notes are `*.md.enc`
ciphertext at rest, so the sync provider only ever sees encrypted blobs.

## Troubleshooting

**Run this first** — it checks everything and tells you in plain words what needs fixing:
```bash
ele doctor
```

<details>
<summary>🔴 Claude says it doesn't know anything</summary>

You almost certainly closed the **window** instead of quitting the **app**. MCP connections are only loaded when Claude starts.

- **Mac:** press **Cmd + Q** to quit, then reopen
- **Windows:** right-click the Claude icon near the clock → **Quit**, then reopen

If that doesn't fix it: run `ele doctor` and check that "Claude Desktop config wired" says PASS. If it says WARN, run `ele onboard` again.
</details>

<details>
<summary>🔴 <code>ele: command not found</code> (or <code>'ele' is not recognized</code>)</summary>

The `ele` shortcut wasn't added to your PATH. Use the full form instead — it works for every command:

```bash
python -m elesync.cli --version
python -m elesync.cli onboard
python -m elesync.cli import ~/Downloads/chatgpt_memory.json --source chatgpt
```

Or add the scripts folder pip printed to your PATH, then restart the command box.
</details>

<details>
<summary>🔴 <code>pip: command not found</code></summary>

- **Windows:** use `py -m pip install "elesync[mcp]"`
- **Mac / Linux:** use `python3 -m pip install "elesync[mcp]"`
</details>

<details>
<summary>🔴 Python too old or not found</summary>

EleSync needs Python **3.10 or newer**. Check: `python --version` (or `python3 --version`).
Download the latest from **[python.org/downloads](https://www.python.org/downloads/)**.
On Windows, tick **"Add Python to PATH"** during install.
</details>

<details>
<summary>🔴 <code>ModuleNotFoundError: No module named 'mcp'</code></summary>

Run: `pip install "mcp[cli]"` then restart Claude.
</details>

<details>
<summary>🔴 Semantic search not matching on meaning</summary>

Semantic recall is optional. Enable it once:
```bash
pip install "elesync[semantic]"
ele embed
```
Then search with `ele --semantic search "your query"`.
</details>

Still stuck? Open an issue at **[github.com/darknodebros/EleSync/issues](https://github.com/darknodebros/EleSync/issues)** and paste the output of `ele doctor`. We'll help.

## Tests

```bash
python -m unittest discover -s tests -v   # 179 tests, stdlib only — no MCP SDK required
```

## Where the export files come from (2026 reality)

EleSync ships **3 verified sources** (real, user-accessible memory exports today) and
**4 experimental adapters** (code is ready, but the platforms don't yet offer a native
memory export — bring-your-own-format only).

**Verified — real exports you can get right now:**

- **ChatGPT** — Settings → Data controls → Export memory (JSON of stored facts/preferences)
- **Claude** — claude.ai → Settings → Export data → memory export (structured JSON)
- **Gemini** — Google Takeout → select "Gemini" → download ZIP, extract the memory JSON

**Experimental — adapters built, export not yet publicly available:**

- **Grok** — adapter expects `{"grok_memories": [...]}`; xAI has not shipped a user-accessible memory export
- **DeepSeek** — adapter expects `{"deepseek_memories": [...]}`; no native export available
- **Perplexity** — adapter expects `{"perplexity_memories": [...]}`; no native export available
- **Copilot** — adapter expects `{"copilot_memories": [...]}`; Microsoft has not shipped a memory export

> These four platforms do not currently provide user-accessible memory exports. The adapters
> are ready for when they do. Contributions welcome once formats are confirmed.

EU/EEA availability of the in-app import tools may be restricted; importing your own export
file into your own vault sidesteps that entirely.

## Roadmap (the honest next 20%)

<!-- NOTE: USB portable vault landed in v1.2.0 — removed from roadmap -->

1. **Semantic recall** — ✅ landed (optional `[semantic]` extra: local ONNX embeddings,
   hybrid keyword+vector ranking — see above). Next: semantic *dedup* (near-duplicate
   detection), and pgvector/sqlite-vec if a vault ever outgrows brute-force cosine.
2. **Encryption at rest** — ✅ landed, both phases (see above): opt-in `ele encrypt`/`decrypt`
   (libsodium + argon2id), *and* live "locked mode" — supply the passphrase and the vault is
   queryable/writable with an in-memory index, so the CLI and MCP server use it without ever
   decrypting to disk.
3. **Sync** — it's just files: `git`, iCloud, Syncthing, or Drive. No server to build.
   After syncing the notes to another machine, `ele reindex` rebuilds the search
   index from the markdown so the vault and its index agree again.
4. **Scoped sharing** — ✅ landed (see above): per-client memory scopes via `ELESYNC_SCOPES`,
   so one vault shows Claude your writing style while keeping legal/health context in a
   compartment it can't see — `ele scope`/`ele scopes`/`ele --as`, a `list_scopes` MCP tool,
   and `ele onboard --scopes`. Next: an optional per-scope passphrase so a compartment is
   encrypted *and* access-gated, not just gated.
5. **Provenance & conflict resolution** — ✅ landed (`ele conflicts` + `find_conflicts` MCP tool,
   and `recall` flags clashes inline — see above). Next: smarter detection (embedding-based, or
   an optional LLM pass) beyond the current lexical heuristic.
6. **More adapters** — 3 verified (ChatGPT, Claude, Gemini) + 4 experimental (Grok, DeepSeek,
   Perplexity, Copilot) — adapters are ready, waiting on the platforms to ship user-accessible
   exports. (Manus was researched and ruled out — it's an autonomous *agent* with no memory
   export; it connects as a live MCP client instead.) Each new verified source is a ~40-line
   file in `normalize.py`.

## License

MIT — see [LICENSE](LICENSE) for details.
