Skip to main content

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:

  1. OPENCODE_DB env 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)
  2. Channel-based naming (when OPENCODE_DB is 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=1 to force the default opencode.db name
  3. Data directory ($XDG_DATA_HOME/opencode/):

    • XDG_DATA_HOME env 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-migrate must 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

opencode_migrate-0.1.0.tar.gz (14.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opencode_migrate-0.1.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

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

Hashes for opencode_migrate-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d1a0778cf9b0fa04d679e6c8ee72175cc8c58a46947a3a08c3ca4847a252a1a
MD5 a19fb173fcf8f838be95c9a3d9744a74
BLAKE2b-256 51b57b8a7521f35803d97fe8e0580aeb5c3147d842214c09e601521d02c9b700

See more details on using hashes here.

File details

Details for the file opencode_migrate-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for opencode_migrate-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d037898c1184af29705fedb6a710d876d79a1d272175d4f938f44e9532701d80
MD5 6b6910af2e1a011723f165bb37da1803
BLAKE2b-256 4b2cd8e9cffeda6f9b01819ef20d6e08177bd99afaf4fba11c1ce770f8a3f5c1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page