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
Metadata
Release files for opencode-migrate 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opencode_migrate-0.1.0.tar.gz | 14.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opencode_migrate-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.1 kB
Release files / opencode_migrate-0.1.0.tar.gz
| Download URL | opencode_migrate-0.1.0.tar.gz |
|---|---|
| Size | 14.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d1a0778cf9b0fa04d679e6c8ee72175cc8c58a46947a3a08c3ca4847a252a1a
|
|
BLAKE2b-256 checksum How to use checksums |
51b57b8a7521f35803d97fe8e0580aeb5c3147d842214c09e601521d02c9b700
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / opencode_migrate-0.1.0-py3-none-any.whl
| Download URL | opencode_migrate-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d037898c1184af29705fedb6a710d876d79a1d272175d4f938f44e9532701d80
|
|
BLAKE2b-256 checksum How to use checksums |
4b2cd8e9cffeda6f9b01819ef20d6e08177bd99afaf4fba11c1ce770f8a3f5c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|