opencode-migrate
Migrate OpenCode sessions between servers.
Exports full session state — messages, parts, inputs, todos, context epochs, and git-based file snapshots — from one OpenCode instance and imports it into another.
Installation
pip install -e .
# or
pip install opencode-migrate
No external dependencies required (stdlib only: sqlite3, json, subprocess, tarfile).
Quick start
from opencode_migrate import SessionMigrator
# Push a session to another server via SSH
m = SessionMigrator()
m.migrate_to_remote(
session_id="sess-abc123def456",
remote_host="server2.example.com",
remote_user="deploy",
)
CLI usage
# List sessions on this machine
opencode-migrate list
# Export to a portable bundle
opencode-migrate export <session-id> -o /tmp/bundle
# Import a bundle on the target machine
opencode-migrate import /tmp/bundle
# Push directly over SSH
opencode-migrate push <session-id> --host server2 --user deploy
# Pull from a remote server
opencode-migrate pull <session-id> --host server1 --user deploy
Path remapping
Since the project directory differs between machines, use --remap-directory:
opencode-migrate push sess-abc --host server2 --remap-directory /home/deploy/myproject
Database path resolution
opencode-migrate automatically detects the database location using the same
environment variables as OpenCode itself. No manual --db flag needed in most cases.
How OpenCode resolves the DB path
The resolution logic (from packages/core/src/database/database.ts) is:
-
OPENCODE_DBenv var (highest priority):- Absolute path → used directly (e.g.
OPENCODE_DB=/srv/opencode/my.db) - Relative name → joined with data dir (e.g.
OPENCODE_DB=custom.db→$XDG_DATA_HOME/opencode/custom.db) :memory:→ in-memory SQLite (not migratable)
- Absolute path → used directly (e.g.
-
Channel-based naming (when
OPENCODE_DBis not set):- Channels
latest,beta,prod→$XDG_DATA_HOME/opencode/opencode.db - Other channels (e.g.
local) →$XDG_DATA_HOME/opencode/opencode-{channel}.db - Set
OPENCODE_DISABLE_CHANNEL_DB=1to force the defaultopencode.dbname
- Channels
-
Data directory (
$XDG_DATA_HOME/opencode/):XDG_DATA_HOMEenv var if set, otherwise~/.local/share
Custom database isolation
To point OpenCode (and this migration tool) at a custom database:
# Set XDG_DATA_HOME to isolate all data
XDG_DATA_HOME="/path/to/custom-dir" opencode
# Or set OPENCODE_DB for just the database file
OPENCODE_DB="/path/to/custom.db" opencode
OpenCode will create and read a separate opencode.db inside the specified
folder's opencode/ subdirectory.
Using with opencode-migrate
# Auto-detects DB from your environment (same as OpenCode would use)
opencode-migrate list
opencode-migrate detect # shows the resolved path
# Explicit env var override
OPENCODE_DB="/custom/path/opencode.db" opencode-migrate list
# XDG override
XDG_DATA_HOME="/srv/data" opencode-migrate export sess-abc -o /tmp/bundle
# Channel-based (for non-standard installations)
opencode-migrate --channel local list
# Manual override still works (takes precedence over env)
opencode-migrate list --db /explicit/path/to/opencode.db
Docker / isolated environments
When running OpenCode in Docker or wanting to isolate from your host machine:
# In your Dockerfile or docker-compose.yml
ENV XDG_DATA_HOME=/app/data
# Then migrate into/out of the container
opencode-migrate push sess-abc --host docker-host --user root \
--remote-db /app/data/opencode/opencode.db
Exported data format
The bundle is a directory containing:
bundle/
├── session_data.json # All DB rows (see schema below)
└── snapshots-<id>.tar.gz # Git-based file snapshots (if any)
session_data.json structure
{
"version": "1",
"session": { ... },
"project": { ... },
"messages": [ ... ],
"parts": [ ... ],
"session_messages": [ ... ],
"session_inputs": [ ... ],
"todos": [ ... ],
"context_epoch": { ... } | null
}
See DATA_FORMAT.md for full field-level documentation.
Python API
from opencode_migrate import SessionExporter, SessionImporter, SessionMigrator
from opencode_migrate import resolve_db_path, resolve_snapshot_dir
# Check resolved paths (respects OPENCODE_DB / XDG_DATA_HOME)
print(resolve_db_path()) # e.g. /root/.local/share/opencode/opencode.db
print(resolve_db_path("local")) # e.g. /root/.local/share/opencode/opencode-local.db
# Export — auto-detects DB from environment
exporter = SessionExporter() # uses OPENCODE_DB / XDG_DATA_HOME automatically
exporter.list_sessions()
exporter.export_session("sess-id")
exporter.export_to_bundle("sess-id", "/tmp/out")
# Or with explicit path
exporter = SessionExporter(db_path="/custom/opencode.db")
# Import
importer = SessionImporter() # auto-detects target DB too
importer.import_from_bundle("/tmp/out", remap_directory="/new/path")
# Migrate (orchestrates export + transfer + import)
migrator = SessionMigrator()
migrator.migrate_to_remote(session_id="...", remote_host="...", remote_user="...")
migrator.migrate_from_remote(session_id="...", remote_host="...", remote_user="...")
migrator.migrate_local(session_id="...", target_db="/other/opencode.db")
Requirements
- Python >= 3.10
- SSH access for remote transfers (ssh, scp in PATH)
opencode-migratemust be installed on both source and target for push/pull
Testing
python -m pytest tests/
# or directly:
python tests/test_migrate.py
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opencode_migrate-0.1.0.tar.gz.
File metadata
- Download URL: opencode_migrate-0.1.0.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d1a0778cf9b0fa04d679e6c8ee72175cc8c58a46947a3a08c3ca4847a252a1a
|
|
| MD5 |
a19fb173fcf8f838be95c9a3d9744a74
|
|
| BLAKE2b-256 |
51b57b8a7521f35803d97fe8e0580aeb5c3147d842214c09e601521d02c9b700
|
File details
Details for the file opencode_migrate-0.1.0-py3-none-any.whl.
File metadata
- Download URL: opencode_migrate-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d037898c1184af29705fedb6a710d876d79a1d272175d4f938f44e9532701d80
|
|
| MD5 |
6b6910af2e1a011723f165bb37da1803
|
|
| BLAKE2b-256 |
4b2cd8e9cffeda6f9b01819ef20d6e08177bd99afaf4fba11c1ce770f8a3f5c1
|