Claudian Session Sync

by powoct
5
4
3
2
1
Score: 51/100

Description

Sync agent-CLI session files between your computers, so a Claudian conversation started on one machine can be resumed on another. Obsidian plugin, desktop only.

Reviews

No reviews yet.

Stats

1
stars
219
downloads
0
forks
29
days
9
days
9
days
53
total PRs
0
open PRs
2
closed PRs
51
merged PRs
0
total issues
0
open issues
0
closed issues
90
commits

Latest Version

10 days ago

Changelog

Install or update via BRAT: powoct/claudian-session-sync. See the README for setup.

Upgrading from 0.3.4 needs nothing from you.

If you use Claudian 2.3.3 or later, read this if you turned on either optional records feature

Claudian 2.3.3 changed how it deletes a conversation: it now removes the conversation's record and leaves nothing behind, where it used to leave a small marker saying "deleted". Assign to this device changed the same way.

With the default settings, nothing changes for you. A deleted conversation's record is gone, so its session file simply stops syncing — exactly as before.

Two optional features, both off by default, relied on those markers, and are not yet compatible with Claudian 2.3.3:

  • Claudian conversation records — for vaults whose own sync cannot carry .claudian/, such as Obsidian Sync. A conversation you delete can come back after you restart Obsidian, because the next sync restores its record from the sync folder. Your other devices keep it either way.
  • Share this device's conversations — a conversation you delete can come back after a restart if you started it in that Obsidian session or used it shortly before closing Obsidian. A conversation another device deleted, or assigned to itself, can also be shared again from this machine.

No conversation is lost — no session file is ever deleted, and everything overwritten is backed up. A deleted conversation may simply reappear.

This release does not change how syncing works. It tells you, while either feature is on: directly under that setting, at the top of every sync report, and once each time Obsidian starts. It says nothing if your Claudian is older, if it cannot tell which version you have, or if neither feature is on.

Two things it cannot see:

  • It only knows this device's Claudian. The sharing problems start as soon as any of your devices runs Claudian 2.3.3, so upgrade them together, or turn sharing off on the ones you have not upgraded yet.
  • Obsidian Sync users: Obsidian Sync carries Claudian's small manifest.json but not Claudian itself, which is over its size limit. So a device can report one version while it runs another. Update Claudian on every device.

A proper fix is being worked on.

Also in this release

  • "Assign to this device" is not supported while sharing is on. With Claudian 2.3.3 or later on any of your devices, the next sync moves the conversation back to where all devices can see it. To keep a conversation on one device, turn sharing off and leave it off.
  • Corrected advice. The warning that sharing carries folder permissions as absolute paths now applies only if a device still runs Claudian 2.2.6 or earlier, because Claudian 2.2.7 removed that feature. The README now tells you to move a record rather than copy it, and to do it while Obsidian is closed on the device that created the conversation.
  • The one new thing this plugin reads is Claudian's manifest.json, to learn its version. The README's disclosure table now lists it.

For the record

gh attestation verify main.js --owner powoct

The main.js here was built by the release workflow from this commit, not uploaded by hand, and is byte-for-byte identical to a local build of the same commit. It has not been checked on a real Obsidian install yet; the one thing to confirm there is that the warnings appear. Full technical record in docs/zh-CN/ (Chinese).

README file from

Github

Claudian Session Sync

Sync the raw session files of Claudian-supported agent CLIs between your computers, so a conversation you started on one machine can be resumed on another — same session ID, full history, mid-thought.

An Obsidian plugin. Desktop only (it reads and writes CLI storage on your disk). Currently in beta, distributed via BRAT.

Not affiliated with Claudian. This is an independent companion plugin for users of the Claudian plugin (YishenTu/claudian). It is not made by, endorsed by, or part of that project.

What it does

  • Watches the session storage of the agent CLIs Claudian drives (see the provider table), and mirrors those files into a local sync folder you choose — point it at a folder inside Dropbox, OneDrive, Google Drive, Syncthing, anything that syncs a directory. The plugin itself never talks to any cloud API and needs no account.
  • On your other machine, the same plugin pulls those files into that machine's CLI storage, where the CLI finds them by its own normal discovery. claude --resume <id> or codex resume <id> then continues the conversation.
  • Merging is append-only and prefix-safe: a file is only ever fast-forwarded to a version that provably contains it byte-for-byte. Timestamps are never trusted. If two machines extended the same session separately, that is a conflict — both versions are kept and you choose (see below). Nothing is silently overwritten, ever.

Which conversations are synced

Only conversations this vault's Claudian knows about: the plugin reads the conversation records Claudian keeps inside the vault (.claudian/sessions/) and syncs exactly those sessions. A session you started with a bare claude or codex in a terminal has no Claudian record and is not synced. Conversations you deleted in Claudian stop syncing (but see Claudian 2.3.3 if you use either optional records feature). Old records that carry no session ID (conversations from older Claudian versions, or ones that never got a first reply) cannot be matched to a CLI file and are skipped — continuing that conversation in Claudian once usually fixes this.

What is never synced

Why
Credentials & CLI config (auth.json, config.toml, .credentials.json…) Never read, never copied
Any SQLite database (*.sqlite, -wal, -shm) Machine-local, absolute paths inside
.claudian/ inside your vault Not by default — it travels with your vault's own sync. An opt-in provider exists for setups whose vault sync cannot carry it; see the warning below
Files the plugin doesn't recognise Conflict copies from sync tools, backups, anything foreign: reported, left exactly where they are, never touched
Deletions Deleting a session on one machine never deletes it elsewhere

Provider support

Support is evidence-tiered: a provider only gets write access after its CLI's on-disk lifecycle has been measured (strict append-only across new / resume / compact / fork / kill) on real machines.

Provider Status Notes
Claude Code ✅ Supported Lifecycle measured on macOS + Windows; cross-machine resume verified in a two-machine acceptance run
Codex ✅ Supported Lifecycle measured on macOS + Windows incl. compact; cross-machine resume verified in a two-machine acceptance run (2026-08-15)
Claudian records ✅ Optional, off by default Claudian's own conversation records (.claudian/sessions/), whole-file synced with converged-base fast-forward — for vaults whose own sync cannot carry dotfolders
OpenCode ❌ Cannot be supported Its history lives entirely inside one SQLite database; there is no per-session file to carry and no official export. This is structural, not a missing feature
Grok ✅ Supported, off by default Lifecycle measured on macOS + Windows (2026-08-24); cross-machine resume verified in a two-machine acceptance run in both directions (2026-08-26). A Grok session is a folder whose files disagree about how they are written — the history is appended, the record that makes the session visible is rewritten whole — so they are carried under different rules, and the files the CLI rebuilds are left where they are
Pi ⏳ Planned Not yet measured

Every provider is off by default. Enabling one for the first time runs a dry run immediately — it writes nothing at all — so you can open Show last sync report and see exactly which of your existing conversations would start travelling before any of them does. That set is usually larger than the one you have in mind: it is every conversation this vault has a Claudian record for, not just today's.

Install (BRAT)

  1. Install BRAT from Obsidian's community plugins.
  2. BRAT settings → Add Beta Plugin → powoct/claudian-session-sync.
  3. Enable Claudian Session Sync in Community plugins.
  4. Repeat on your other machine(s).

Setup

On each machine:

  1. Sync folder — in the plugin settings, point Sync folder at a local directory that your file-sync tool replicates (e.g. ~/Dropbox/agent-sessions). Use the same folder (as seen by each machine) everywhere.
  2. Initialise — the first machine initialises the folder with one click; the others join it. An empty-looking folder is never written to without that explicit step, so a half-downloaded folder can't be mistaken for a fresh one.
  3. Workspace identity — created inside the vault (.claudian-session-sync/) and shared through your vault sync; if your vaults don't sync to each other, copy that one small folder across once (or set the ID by hand).
  4. Enable providers — toggle the CLIs you actually use. First enable = forced dry run.
  5. Sync runs on an interval (default 5 min) and on demand from the status bar.

Resuming on the other machine

  • CLI: claude --resume <session-id> / codex resume <session-id> works as soon as a sync pass has landed the file. The session may not appear in interactive pickers (they can filter by origin) — resuming by ID always works.
  • Claudian's UI: Claudian lists conversations from its records in .claudian/sessions/ inside the vault. Those records travel with your vault's sync, not with this plugin — see the next section.

There is a setting for this. Share this device's conversations with your other devices (off by default, and set per machine) moves each of this machine's conversation records into the layer every device reads. All of them then list the conversation, and all of them write to the same record. Three things to know before turning it on. Claudian decides where to save a conversation once per session, so after a move it keeps writing a copy in this device's folder until you next restart Obsidian; each sync folds that copy forward into the shared one, and where it cannot tell which version should win it keeps both and asks you — the command Repair shared conversation records lists those with both sizes and dates, one at a time. Turning the setting back off stops further moves but does not un-share what has already moved. Claudian's Assign to this device is not supported while it is on — with Claudian 2.3.3 or later on any of your devices, the next sync moves the conversation back into the shared layer. To keep a conversation on one device, turn the setting off and leave it off: turning it back on shares it again. (If any of your machines still runs Claudian 2.2.6 or earlier, a shared conversation also carries the folders it had been given access to as absolute paths, which on the other machine may point at something else; Claudian 2.2.7 removed that feature.)

Claudian 2.2.5 and later: the conversation may not be listed on the other machine, even though resuming works. From 2.2.5 each new conversation's record is filed under the device that created it (.claudian/sessions/devices/device-<hash>/), and Claudian's list is device-scoped — a record belonging to another device is not shown. This plugin still carries the session file, so claude --resume <id> / codex resume <id> work normally; what is missing is the entry in Claudian's sidebar. The Assign to this device button does not help here: it promotes a record from the top level, not from another device's folder. Moving that one conv-*.meta.json up to .claudian/sessions/ makes the conversation listed and assignable again. Move it, do not copy it, and do it while Obsidian is closed on the machine that created the conversation (or restart Obsidian there before using it again): Claudian keeps writing to whichever copy it loaded at startup, and deleting the conversation there removes only that copy.

⚠️ Keep .claudian/ in your vault sync

Claudian's conversation list lives in <vault>/.claudian/. This plugin deliberately does not sync it (it is rewrite-style data with machine-local paths inside; carrying it safely is planned work). So:

  • If you sync your vault with git / Syncthing / a cloud-drive folder: make sure .claudian/ is not excluded. Then both halves arrive — records via your vault sync, session files via this plugin — and conversations appear in Claudian's UI on both machines.
  • Obsidian Sync users: note that Obsidian Sync excludes hidden folders other than .obsidian, so it will not carry .claudian/. For exactly this case the plugin ships an optional Claudian records provider (off by default): enable it on both machines and the records travel through the sync folder instead — identical files are left alone, a one-sided change fast-forwards (with a backup), and anything else becomes a conflict for you to settle. Do not enable it if your vault sync already carries .claudian/ — two transports over one folder feed your sync tool conflicts.

Claudian 2.3.3 and later

Claudian 2.3.3 changed how it deletes a conversation: it now removes the record and leaves no deletion marker, and Assign to this device no longer leaves an assignment marker either. The default setup is not affected — a deleted conversation's record is gone, so its session file simply stops syncing.

Two optional features, both off by default, relied on those markers and are not yet compatible:

  • Claudian records provider: a conversation whose record is in the shared layer (an older conversation, or one the sharing setting moved there) comes back after you delete it and restart Obsidian, because the next sync restores its record from the sync folder. Your other devices keep it either way. Conversations you deleted under an older Claudian can also reappear once you upgrade.
  • Share this device's conversations: a conversation you delete can come back after a restart if it was started in that Obsidian session or used shortly before Obsidian was last closed, and one another device deleted or assigned to itself can be shared again from this machine. This starts as soon as any device syncing the vault runs Claudian 2.3.3, including while the others are still on an older version — so upgrade all of them together, or turn sharing off on the ones you have not upgraded yet.

No session file is ever deleted and every overwrite is backed up, so no conversation is lost — but deleted ones may reappear.

When this plugin detects Claudian 2.3.3 or later on the same device with either feature on, it says so in its settings, at the top of every sync report, and once per launch. A device still running an older Claudian cannot tell that another one has upgraded, so it stays silent. The version is read from Claudian's manifest.json; Obsidian Sync carries that file but not Claudian itself (it is over Obsidian Sync's size limit), so update Claudian on every device and the two will agree.

How your data is protected

  • Backups before every overwrite. Any file about to be replaced — on either side — is backed up first (default: 3 versions per file per direction, configurable). No backup, no overwrite. Restore an earlier version (command palette) lists what was kept and puts one back — and says, before you click, whether the next sync will undo it, propagate it to your other machines, or raise a conflict for you to settle.
  • Verified writes. Overwrites re-check the target immediately before renaming the new version into place; anything that moved gets re-planned instead of written.
  • Conflicts keep both versions. A genuine fork is detected by content, quarantined (both branches, content-addressed, shared by both machines), and surfaced with three choices: keep this machine's version, keep the other's, or open the folder and look. Each machine that extended the session confirms once. The losing branch stays in quarantine and in backups.
  • Unknown files are never touched. Sync-tool conflict copies and other foreign files are recognised, reported ("Files left alone"), and never moved, renamed or deleted — moving one would make your sync tool propagate a deletion to every machine.
  • Stability gating. Files still being written (by the CLI or by your sync tool) are observed, not copied; a pass acts only on files that have provably held still.

What it touches on your disk, and why the store review says what it says

The community listing's automated review flags two things about this plugin. Both are accurate readings of the code, and both are worth explaining rather than explaining away.

"Direct filesystem access — can read and write any file on the system." True, and unavoidable: the files this plugin exists to sync are your CLIs' session files, which live in ~/.claude, ~/.codex, ~/.grok — outside the vault, where Obsidian's vault API cannot reach. That is also why the manifest says isDesktopOnly: true. What it actually touches is a short list:

Reads the session files of the providers you switch on (all off by default), Claudian's conversation records inside your vault, and the manifest.json files in the vault's plugins folder (only to learn which Claudian version is installed)
Writes your sync folder, those same session files when pulling a conversation from another machine, and its own state under ~/.claudian-session-sync
Never anything else. Every path is resolved segment by segment and rejected if it escapes a known root or passes through a symlink; files it does not recognise are reported and left alone; credentials (auth.json, config.toml, .credentials.json) are excluded by name and never read. The one exception to the symlink rule is reading Claudian's manifest.json, which follows a linked plugin folder the way Obsidian does, because a plugin installed from a working copy is usually linked there

"Persists data in localStorage instead of the Obsidian plugin data APIs." This one is a false positive, and the distinction matters. This plugin's own settings go through loadData()/saveData() — the plugin data API, as expected. It reads exactly one localStorage key, claudian.deviceSettingsKey, which belongs to Claudian: from 2.2.5 Claudian files each conversation's record under a folder named for a hash of that seed, so deriving the same hash is the only way to know which of those folders is this machine's. It is read, never written, used only to name a folder inside your own vault, and never sent anywhere. main.ts marks the call site with the same explanation.

Honest limitations

  • Two machines writing the same session at the same time is detected and contained (conflict, both versions kept), not prevented — this is a file-sync architecture, not a real-time collaboration protocol.
  • Files larger than Max file size (default 64 MB) are skipped and reported.
  • The CLIs themselves append metadata to session files — Claude Code, for instance, appends title records even when you merely open a session. That is normal, absorbed by the merge, and not this plugin (or Claudian) writing to your files.
  • If your vault lives behind a symlink, note that Claude Code derives its project directory from the resolved path; if the resolved paths differ between machines, set the directory override in the provider's settings.
  • Windows: if Claudian itself can't find a CLI (.cmd wrapper detection), that is a Claudian issue unrelated to this plugin — sessions sync regardless of how the CLI is launched.

Development

npm ci
npm run verify   # typecheck, lint, secret/docs gates, ~1000 tests, build, bundle checks

Design documents (Chinese): architecture · testing & acceptance · measured findings. Every behavioural claim above traces to a decision record (ADR 1–67) and, where it matters, to a real-machine measurement.

License

MIT


简体中文摘要

在多台电脑之间同步 AI agent CLI(Claude Code、Codex 等)的原始会话文件,让你在 A 机器上的对话能在 B 机器上 resume 继续。桌面端专用;不接任何网盘 API,只认你指定 的本地同步文件夹(Dropbox / OneDrive / Syncthing 均可)。

  • 只同步本 vault 的 Claudian 有记录的会话;纯终端起的会话、已在 Claudian 里删除 的会话、没有 session id 的旧记录,都不同步。
  • 合并只做前缀快进,从不信时间戳;双机分叉 = 冲突,两个版本都保留,由你选择。 覆盖前必备份;不认识的文件永远原地不动;不传播删除。
  • 请勿把 .claudian/ 排除在你的 vault 同步之外——Claudian 的会话列表靠它; 注意 Obsidian 官方同步不带隐藏文件夹(.obsidian 除外)。
  • Grok 已通过两机验收(2026-08-26,双向),同步的是会话本体(记录 + 历史),其余文件由 对端 CLI 自行重建;和所有 provider 一样默认关闭,首次打开会先跑一轮 dry-run 让你先看 范围——那一轮什么都不写。
  • 本插件与 Claudian 项目无隶属关系。

设置与安全细节见上文英文说明;设计文档在 docs/zh-CN/。