Install
Inside DeepSeek Harness, with dsh-market
dsh plugin --profile web add dshmarket
Or from the command line
dsh plugin --profile web add github:dickpy/dsh-cloud-sync
Installing runs third-party code with your own permissions — it can read your files, use your credentials and reach the network. Review the source first, and pin a commit (github:owner/repo#sha) when you can.
README
DSH Cloud Sync
Portable DeepSeek Harness profile and local-plugin source synchronization
@dickpy/dsh-cloud-sync · WebDAV / S3 / OSS / COS / MinIO / GitHub Gist · AES-256-GCM client-side encryption · Snapshot history & rollback
What is it?
DSH Cloud Sync is a DeepSeek Harness (DSH) bundle for portable profile recovery. It synchronizes small, reproducible profile files to WebDAV, S3, OSS, COS, MinIO, or GitHub Gist rather than copying node_modules, then lets DSH/pnpm rebuild packages on the target computer.
It never copies sessions, attachments, pnpm cache, node_modules, or credentials.
Features
| Feature | Description |
|---|---|
| 📦 Lightweight sync | Syncs package.json, pnpm-lock.yaml, .npmrc, pnpm-workspace.yaml, cordis.patch.yml, cordis.yml, and marketplace hot-update YAML files |
| ☁ Storage providers | WebDAV, Amazon S3, Alibaba Cloud OSS, Tencent Cloud COS, MinIO, and GitHub Gist; only one provider is active at a time |
| 🔐 GitHub device authorization | Copy a device code, authorize in GitHub, and let Cloud Sync create its managed secret Gist |
| 🔗 Source auto-archiving | Local-plugin source archives automatically captured from reachable file: / link: dependencies during Sync |
| 🔒 Client-side encryption | Optional AES-256-GCM encryption; each object carries a fresh KDF salt; passphrase never written to disk |
| 🕘 History & rollback | Every successful sync records a dated snapshot (latest 30 retained remotely) with one-click rollback |
| 🔀 Three sync policies | Smart merge (default), Cloud first, Local first |
| 🧩 Plugin lifecycle | Panel derives plugins from the synced profile; install / uninstall remote-declared plugins |
| 🔄 Automatic sync | Device name + interval from 5 minutes to 24 hours; runs only when changes are detected |
| 🆕 Self-update | Distributes its own .tgz via GitHub Releases with GitHub SHA-256 asset-digest verification and explicit updates |
Interface
The settings UI follows the active DSH light, dark, and custom theme. Its three tabs stay available while scrolling: Cloud services, Configuration & history, and Sync status.
Quick start
Pick one installation method, in order of preference. After installing, fully quit and restart DSH Web, then open Settings → Cloud Sync.
1. Let an AI assistant install it (easiest)
Send the following to DSH or Codex, and let it install and restart DSH Web:
Please install the DSH Cloud Sync plugin (npm package
@dickpy/dsh-cloud-sync) and restart DSH Web.
2. Install via npm (recommended)
dsh plugin --profile web add @dickpy/dsh-cloud-sync
3. Install from a bundled .tgz
Download the latest dickpy-dsh-cloud-sync-*.tgz from GitHub Releases, then run:
dsh plugin --profile web add .\dickpy-dsh-cloud-sync-0.20.6.tgz
Useful in intranet or offline environments without direct npm registry access.
4. Develop from source
git clone https://github.com/dickpy/dsh-cloud-sync.git
cd dsh-cloud-sync
npm install
npm run check
dsh plugin --profile web add .
For modifying the plugin, debugging, or contributing.
5. First backup
- Select Connect, choose WebDAV, S3, OSS, COS, MinIO, or GitHub Gist. Gist can be connected through a device code and will create a secret Gist automatically.
- Save the connection. Selecting and saving another provider replaces the active provider.
- Select Sync. It automatically archives every reachable local source plugin without retaining its old drive path.
.dshsyncignorecan exclude additional file or directory names.
Each provider keeps its own endpoint, region, bucket, prefix, and Access Key ID. When you return to a saved provider, the form is prefilled. If its secret is already stored locally, leave the secret field empty to reuse it.
For WebDAV, a missing target directory is created automatically when the connection is saved or the first sync runs, including nested paths and directory names containing spaces or non-ASCII characters. No manual pre-creation is required.
GitHub Gist
GitHub Gist is sufficient for configuration-only sync: profile files, dependencies, lockfiles, marketplace YAML, and history snapshots fit comfortably in one managed secret Gist.
- Each Cloud Sync object is limited to approximately 700 KiB and a managed Gist has a limit of 200 files. Sync fails explicitly rather than truncating data.
- Connecting Gist automatically enables configuration-only sync, so local-plugin source archives are not uploaded. Use WebDAV or object storage when source archival is required.
- A secret Gist is unlisted, not end-to-end private. Enable the plugin's AES-256-GCM client-side encryption for sensitive content.
- Device authorization uses this project's GitHub OAuth App and requests only
gistaccess. If the authorization service is unavailable, a token withgistaccess remains available as a fallback.
6. Restore on a new device
Install this Sync bundle and configure the same target, then:
- The Sync status tab lists remote plugins and their local installation state;
- Install missing plugins there, or choose Preview restore → Apply restore for complete profile recovery;
- Restore writes profile files only; it deliberately defers dependency installation until DSH is fully restarted.
Sync policies
| Policy | Description |
|---|---|
| Smart merge (default) | Unions plugin dependencies, bundles, and source archives; pauses and asks when both sides changed the same item |
| Cloud first | Restores the remote snapshot to the current profile |
| Local first | Replaces the remote snapshot with the current profile |
Client-side encryption
Provide a passphrase (≥ 8 characters) in the Settings panel to enable:
- Snapshots, history, and local-plugin source archives are encrypted with AES-256-GCM before upload;
- Each encrypted object carries a fresh KDF salt — a second device only needs the same passphrase, never a copied local settings file;
- The passphrase and derived key are never written to disk; re-enter the passphrase after restarting DSH.
Self-update
- Checks the latest GitHub Release when the settings page opens; no sync provider is required;
- When a newer version is available an Update button is shown: package is downloaded to
~/.dsh/dsh-cloud-sync/releases/, SHA-256 verified, then installed into thewebprofile; - Updating is explicit: a sync never silently replaces the running Cloud Sync bundle;
- Release checks compare both version and checksum, so a same-version repair can show an Update action without bumping the version.
Safety notes
- Use HTTPS for WebDAV, S3, OSS, and COS. MinIO may use HTTP on localhost or a trusted private network; public deployments should still use HTTPS;
- Source archives are checksummed before restoration, written under the DSH sync directory, and reject traversal paths;
- A restore first writes the prior profile files to
~/.dsh/dsh-cloud-sync/backups/; only the newest ten local backups are retained; - On Windows remembered passwords and Secret Access Keys are protected with DPAPI for the current user; on other platforms they are stored in a separate owner-only (
0600) credentials file;settings.jsonnever contains plaintext secrets; - Encryption protects remote snapshot contents, but it does not replace access controls or protect a device that is already compromised.
Development
Requirements
- Node.js ≥ 18
- pnpm
Commands
# Syntax check
pnpm check
# Unit tests (built-in mock WebDAV / S3-compatible server)
pnpm test
Structure
lib/
index.js # Bundle entry: registers /api/dsh-cloud-sync/* routes (loopback only)
core.js # Core logic: storage providers, snapshots, encryption, plugin lifecycle
client.js # Web panel (React, injected into the Settings "Cloud Sync" section)
test/
core.test.mjs # Integration tests with mock WebDAV / S3-compatible storage
cordis.patch.yml # Injects the host API and panel into the DSH web profile
Releasing
Versioning follows major.minor.patch:
- Bump
versioninpackage.jsonand add aCHANGELOG.mdentry; - Run
pnpm checkandpnpm test; - Create a GitHub Release with the
.tgzasset (npm pack); - Other devices detect the new version and update explicitly from the settings page.
FAQ
Q: What object-storage endpoint should I use? A: Enter the service root and provide the bucket separately. S3, OSS, and COS use their regional S3-compatible endpoints; COS bucket names commonly include the APPID. MinIO endpoints may include a reverse-proxy base path.
Q: Will it silently replace the running Cloud Sync? A: No. Updates are always explicit — click Update in the settings page and restart DSH.
Q: How do I exclude files from sync?
A: Create a .dshsyncignore in the DSH sync directory, one file or directory name per line.
Q: What about build-script approvals for remote plugin installs?
A: Cloud Sync imports the source profile's allowBuilds entries and lockfile-pinned Git revisions; approve only the build scripts you trust.
Contributing
Issues and pull requests are welcome!
License
MIT © 2025 dickpy