Part of the DEVIN ecosystem
Track: Control · Nature: product
For: Local-first ops, Security engineers
Interface: CLI
Path: Local-first ops · step 4/5 — afterdevin-office, beforedevin-janitor
devin-backup
Unofficial community project. Not affiliated with, endorsed by, or sponsored by Cognition AI. "Devin" is a trademark of Cognition AI.
Linux · Personal Windows · Corporate Windows
Part of the awesome-devin ecosystem: the curated hub for the devin-* tools.
Safe backup & restore for Devin Desktop stores: timestamped snapshots of
sessions.db, acp-messages/, state.vscdb and .devin/ config — with
SQLite-consistent copies, integrity verification and rotation.
The problem
Everything Devin keeps about your work lives in a handful of local SQLite
databases and config files. Two failure modes make naive copy/robocopy
backups dangerous:
- Live SQLite files. Copying
sessions.dbwhile Devin is running can produce a corrupt copy — mid-write pages, unmerged WAL. It looks fine until you restore it. - Silent schema drift.
sessions.dbhas already had 17 migrations. Restoring an old backup over a newer install silently downgrades your data; nothing warns you.
Prior art
General-purpose backup tools — restic, borg, robocopy, Windows File
History — copy bytes faithfully, but they know nothing about SQLite
consistency or about which files under a Devin data dir actually matter.
This project adapts the standard practice (sqlite3's online backup API +
checksum manifests + retention rotation); it does not reinvent it.
What makes it Devin-native
It knows which stores are Devin's brain — and warns you when the brain's format changed underneath a backup.
- Side-by-side: snapshots are made through
sqlite3.Connection.backup()(consistent even while Devin runs, with file-copy fallback), and every manifest recordsschema_versionviadevin-internals-spec. - No-Devin: remove Devin and there is nothing to discover — the extra disappears.
- One sentence: on restore you get "backup is v15, current is v17" instead of a silent downgrade.
Install
Requires Python ≥ 3.10. Install with pipx install devin-backup, uv tool install devin-backup or pip install devin-backup. Per-OS setup lives in the platform guides: Linux · Personal Windows · Corporate Windows.
Usage
devin-backup create [--data-dir <session-data-root>] [--config-dir <ui-config-root>] [--out <backups-dir>]
devin-backup verify <snapshot-dir>
devin-backup diff <snapshot-dir> [--data-dir <session-data-root>] [--config-dir <ui-config-root>] [--json]
devin-backup list [--out <backups-dir>]
devin-backup restore <snapshot-dir> --to <session-data-root> [--config-to <ui-config-root>] [--apply] [--no-backup] [--smoke]
devin-backup rotate [--keep N] --yes
createsnapshotssessions.db, ACP message databases,state.vscdband.devin/files when present. A v2 manifest records which source root each file came from; old v1 snapshots remain readable.- On Linux, the CLI data root and UI config root are separate. The default
createdetects both. If you pass--data-dir, also pass--config-dirto include the UI stores. verifyre-checks every hash and runsPRAGMA integrity_checkon DBs; exit code 1 on failure.diffcompares a snapshot against the live stores — same/different per file, size deltas, files present on only one side — and never writes anything (exit 0 even on differences). For SQLite stores it compares a logical content digest plus per-table row counts, becausesqlite3.Connection.backup()copies are not byte-identical.restoreis a dry-run by default. It restores data-root files to--toand config-root files to--config-to(default: detected UI config root). Pass--applyto write. Existing files are saved to apre-restore-<ts>backup first;--no-backuprefuses overwrites.--smokeruns a post-restore integrity pass:PRAGMA integrity_checkplus schema-version detection per SQLite store, printed per store — the restored files with--apply, the snapshot sources (a pre-restore preview, still read-only) without it. Exits 1 if any store fails.rotatekeeps the newest N snapshots (default$DEVIN_BACKUP_KEEPor 10) and is a no-op until--yes.pre-restore-*dirs are never rotated.- A snapshot is a copy of every secret the stores hold. Snapshot dirs
are created owner-only (
0700dirs,0600files — make sure the backups dir you pick is too).create --exclude <PATTERN>skips stores by path substring/glob (repeatable);create --exclude-secretsskips the stores a live audit found carrying OAuth tokens and PII:globalStorage/state.vscdb,credentials.toml,*.pem,*.key. Exclusions are listed in the manifest under"excluded".
Defaults: the session data root is $DEVIN_DATA_DIR or
%APPDATA%\\devin on Windows and $XDG_DATA_HOME/devin (normally
~/.local/share/devin) on Linux. The UI config root is %APPDATA%\\Devin
on Windows and $XDG_CONFIG_HOME/Devin (normally ~/.config/Devin) on Linux.
--out defaults to $DEVIN_BACKUP_DIR or <data-root>/backups.
from devin_backup import diff, restore, smoke, snapshot, verify
snap = snapshot.create_snapshot(data_dir, backups_dir, config_dir=config_dir)
verify.verify_snapshot(snap) # {"ok": True, ...}
diff.diff_snapshot(snap, data_dir, config_dir=config_dir) # read-only report
restore.restore_snapshot(snap, data_dir, config_dir=config_dir) # dry-run
smoke.smoke_restored(snap, data_dir) # integrity + schema per store
Works with Devin alone (Devin-only mode)
devin-backup copies Devin's local stores to a destination folder you pick — an external drive, a synced folder, anywhere on disk. No cloud account, VM or network service is required.
Snapshots contain real session data (prompts, paths, commands). Treat the backup destination as sensitive: keep it on a private/encrypted volume and apply the same care you give the original stores.
Adapters (MCP server, Devin skill, plugin)
devin_backup.mcp_server exposes the read-only surface as MCP tools — backup_verify, backup_list and
backup_diff (same payloads as the corresponding --json CLI
commands)
— via the devin-backup-mcp entry point (pip install 'devin-backup[mcp]'). The
adapters/ directory is a self-contained Devin plugin root
(adapters/.devin-plugin/plugin.json + adapters/skills/devin-backup/SKILL.md),
installable with devin plugins install Icaro0310/devin-state#packages/backup/adapters. Restoring a snapshot stays a
human-confirmed CLI action and is deliberately not exposed through any
adapter.
The same stdio server registers in other MCP hosts:
Zed — context_servers in settings.json:
{
"context_servers": {
"devin-backup": { "command": { "path": "devin-backup-mcp", "args": [] } }
}
}
JetBrains — Settings → Tools → AI Assistant → Model Context Protocol → Add:
{ "mcpServers": { "devin-backup": { "command": "devin-backup-mcp" } } }
Antigravity — ~/.gemini/config/mcp_config.json:
{ "mcpServers": { "devin-backup": { "command": "devin-backup-mcp" } } }
Platform support
Tested on Windows and Linux (windows-latest + ubuntu-latest in CI).
Windows stores share the %APPDATA%\\Devin root. Linux stores are discovered
separately under XDG_DATA_HOME/devin and XDG_CONFIG_HOME/Devin. Use
--data-dir and --config-dir for non-default locations.
devin-backup copy-to — verified secondary destination (BK-2)
Copies a whole snapshot into a secondary directory (mounted drive, NAS mount, synced folder) and re-verifies every sha256 at the destination — a corrupt copy is removed and reported instead of silently archived. Encryption/remote sync is intentionally out of scope (personal-track P-8).
devin-backup install — daily scheduled snapshots (BK-1)
devin-backup install [--out DIR] [--backend auto|tasksch|cron|elapsed]
registers a daily devin-backup create job using the F6 scheduling
foundation (shared .devin-ecosystem/scheduled.json registry): Task
Scheduler on Windows, a tagged crontab line elsewhere, and — where
schedulers are banned — the elapsed backend ticked by a UserPromptSubmit
hook (see devin-powerups tools/schedule.py). Opt-in; nothing is scheduled
unless you run it.
Limitations
- Private, volatile internals. These stores are Devin implementation
details; paths and schemas can change in any release. Store discovery is
pattern-based (
*.db,*.vscdb,.devin/) and best-effort. - Schema versions only exist where Devin keeps a ledger —
sessions.dbgets a realschema_version;acp-messages/state.vscdbdo not have one to record. - Not a scheduler. M1 takes snapshots when you run it; Task Scheduler /
cron integration is queued for M2 (see
docs/SPEC.md§10). - Writes only on
--apply. Backup never touches Devin's databases except through the read-only backup API.restore --applyis the only write path and is always guarded by a pre-restore backup. - Tested only against synthetic fixtures — no real session content is ever copied, by design.
Development
pip install -e ".[dev]"
python -m pytest
Ground rules in CONTRIBUTING.md: fixtures before code, small commits, a shared README and Windows/Linux platform guides. Canonical spec: docs/SPEC.md.
When to use this
- You want point-in-time, restorable snapshots of everything Devin keeps
locally —
sessions.db,acp-messages/,state.vscdb,.devin/config. - You need copies that are consistent even while Devin is running — the SQLite online backup API avoids corrupt mid-write copies.
- You want integrity guarantees: hash manifests plus
PRAGMA integrity_checkonverify, and a schema-version warning on restore instead of a silent downgrade. - You want bounded retention —
rotate --keep Nprunes old snapshots without touchingpre-restore-*safety copies.
When NOT to use this
- You need scheduled backups — M1 only runs when you run it; wrap
devin-backup createin cron/Task Scheduler yourself for now. - You need encrypted or offsite/cloud backup — snapshots are plain files in a folder you pick; put that folder on an encrypted volume or sync it with your own tool.
- You only want the session text, not restorable state —
devin-historyexport may be all you need.
FAQ
What is devin-backup? A CLI that takes consistent, verifiable snapshots
of Devin's local stores and can restore them safely. Every snapshot carries
a manifest with checksums and the sessions.db schema version, so restores
warn you before downgrading your data.
Can I back up while Devin is running? Yes. Snapshots go through
sqlite3.Connection.backup(), which is consistent on live databases, with
a file-copy fallback for non-SQLite files. You do not need to close Devin
to create or verify.
Is restore destructive? Not by default. restore is a dry-run until
you pass --apply, and even then every existing file is moved to a
pre-restore-<timestamp> backup first; --no-backup refuses overwrites
entirely.
Does it encrypt or upload my backups? No. Snapshots are plain copies in a local folder. They contain real session data (prompts, paths, commands), so keep the destination on a private or encrypted volume and apply the same care you give the original stores.
License
MIT — see LICENSE.
Metadata
Release files for devin-backup 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| devin_backup-0.1.1.tar.gz | 45.0 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| devin_backup-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.2 kB
Release files / devin_backup-0.1.1.tar.gz
| Download URL | devin_backup-0.1.1.tar.gz |
|---|---|
| Size | 45.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c28a7b57f5efa642d88d4d1f0184aa4adf745e9d2b20407dc5928b8c5b3cf27f
|
|
BLAKE2b-256 checksum How to use checksums |
3e876c730e0272556d352a123d4215ecadcb84a3519aff9af8bb0bde3fabefca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / devin_backup-0.1.1-py3-none-any.whl
| Download URL | devin_backup-0.1.1-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
80e3e5710cf9fcd89f77237e32462ba9dba000999cf8e5fd16726a142eb2499c
|
|
BLAKE2b-256 checksum How to use checksums |
abd28d06bcf42812eaaaa0f61691e67be267a670118545ac314f5d1746f5b338
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for devin-backup 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for devin_backup-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.