When DSH sessions, plugin manifests, and settings are scattered across multiple machines, recovery and migration can be cumbersome. Existing Git-based approaches usually require the git binary and make conflict handling and merging complicated. The minghuo/dsh-github-sync plugin solves these issues by using the GitHub REST API to back up configurations to a private repository and restore them on another machine, either for a whole machine or a single session.

Core Capabilities

  • Multi-machine synchronization: Supports synchronizing sessions, plugin manifests, and settings across multiple machines.
  • Pure REST API: Does not depend on the git binary, works in sandbox environments, and tokens are not written into configuration files.
  • Isolated directories: Each machine has its own independent instances/<instance-id>/ directory in the repository, with no overlap and no need to merge files.
  • Restore modes: Supports restoring a whole machine, a workspace, or a single session, with dryRun preview support.
  • Content addressing: Uses SHA1 hash comparison; unchanged sessions are not uploaded repeatedly.
  • Browsing and reading: Browse session lists locally or remotely, and read zstd-compressed logs directly (requires Node ≥ 22.15).
  • Workspace remapping: During restore, maps a remote workspace directory name to a local path, ensuring files land in the correct location.
  • Local snapshots: Supports automatically taking snapshots before pushing or restoring for quick rollback.
  • Security and privacy: Enforces private repositories, tokens are write-only and never read back, and same-origin validation is applied to state-changing requests.

Installation and Enabling

Install it under the corresponding profile in the Web UI:

dsh plugin --profile web add github:minghuo/dsh-github-sync

After installation, restart dsh web to activate the plugin.

Configuration and Backup

  1. Create a private repository on GitHub (the plugin does not create it for you; public repositories are rejected).
  2. Create a fine-grained PAT scoped only to that repository. Select Contents: Read and write (if using PR mode, also select Pull requests: Read and write).
  3. Open Web UI → Settings → GitHub Sync, enter the repository URL (owner/repo or full URL), branch name, and token, then save.
  4. Click “Verify Repository” to confirm that it is writable and private, then click “Backup Now.”

Restore and Session Management

After installing the same plugin and configuring the same repository on another machine, go to the “Session Backup” page to browse and restore remote content.

  • Scheduled backup: Enable it under “Overview → Automatic Backup.” Set autoSync to true and specify intervalMinutes (minimum 5 minutes); a one-time backup at startup is supported.
  • Browsing:
    • Local browsing: Grouped by workspace, showing session count, size, last modified time, and largest log file names.
    • Remote browsing: Lists workspace and session statistics for each machine’s backup.
  • Restore: Supports whole machine, single workspace, or dryRun mode. A local snapshot (pre-restore-*) is automatically created before restore.
  • Workspace remapping: Resolves cases where the same project has different paths on two machines; during restore, maps the remote directory name to the local path.
  • Reading logs: Click a session name to decompress and view the zstd log text within the page.

Sync Scope and Limitations

Synced Content

The plugin provides sync toggles for three content categories. Disabling a category prevents both uploading that category and deleting existing cloud content:

Group Default Content Exclusions
sessions On $DSH_HOME/sessions/** *.tmp, session.lock, .dsh-mkdir*
plugins On package.json, cordis.patch.yml, pnpm-lock.yaml, and pnpm-workspace.yaml for each profile node_modules, cordis.yml, .dsh-market, .dsh-module-fallback
settings Off $DSH_HOME/settings.yaml —

Local secrets (such as .credentials.yaml and .anonymous-user-id) are never included in the synchronization scope.

Security and Known Limitations

  • Token security: Tokens are write-only and never read back; they are stored in the settings namespace or $DSH_HOME/dsh-github-sync/config.json.
  • Private enforcement: Repository metadata is checked before every push; private !== true is rejected directly.
  • Cross-machine restore: The cwd in session headers is not rewritten (absolute paths in log bodies retain the original machine’s paths).
  • File limits: GitHub’s single blob size limit is 100 MB; files larger than 45 MB are skipped by default.
  • Tree API limits: When the session directory tree is very large, the GitHub tree API may return truncated; in that case, only incremental comparison is performed.
  • Coexistence: It can coexist with the legacy ~/.dsh git repository; the plugin does not touch that directory.
  • Items not synced: $DSH_HOME/storages/workspace.json (workspace registry) and $DSH_HOME/attachments (attachments) are outside the sync scope.

Ecosystem Context

DSH’s philosophy is “everything is a plugin.” This plugin is listed in the SkillHub plugin directory (an independent site with no official affiliation with DeepSeek).