dsh-profile-sync: Plugin Migration Tool

In DeepSeek Harness (DSH), plugin configurations often differ across profiles (for example, the web profile web and the desktop profile desktop). Manually copying files is error-prone: you may omit allowBuilds, causing native builds to fail silently, or trigger port conflicts. dsh-profile-sync is a plugin migration tool that, by default, safely pulls the web profile’s plugin set into the desktop profile.

It does not install anything directly itself; it performs only four things: computing differences, running preflight checks, writing a “script to run after exit”, and verifying after the next startup that the changes actually landed. The actual installation is delegated to official channels (the desktop profile uses the in-app manager; other profiles use dsh plugin).

Core Features

  • Compute differences: compares the source and target plugin lists to identify newly added plugins, changed plugins, differences only in pinning, etc.
  • Preflight checks: before installation, checks potential blockers, including entry-id collisions, loadable entry points, declaration completeness, engine scope, git source conditions, etc.
  • Script generation and verification: generates a script to be executed after exit, and verifies actual changes after restart.
  • Panel interaction: adds a “Plugin Migration” panel in the left sidebar, allowing users to select plugins to migrate, generate an execution script, or apply immediately.
  • Agent tool: provides the profile_sync tool for agents, supporting operations such as plan / write / status.

Installation and Enablement

Installation does not rely on Node.js to run the plugin itself; instead, install.cmd registers the plugin into DSH.

  1. Open DeepSeek Harness (it should already be running).
  2. Double-click install.cmd.
  3. Refresh the page — the “Plugin Migration” panel appears in the left sidebar.

install.cmd first runs a self-check (manifest invariants + real loading) and confirms the official /api/plugin-manager endpoint is available before installing the plugin into the profile. The desktop app must remain running because it needs to invoke the official in-app manager.

Usage

Double-click Operations

  • install.cmd: Runs pre-install self-check + installs this plugin into the profile.
  • sync-plan.cmd: Computes differences and generates a plan + generates apply.cmd.

Command Line

Node.js 20+ must be available on PATH.

# 算差异并落成产物(plans/<时间>/plan.json + plan.txt + apply.cmd)
node bin/plan-cli.mjs plan --source web --target desktop --write

# 只看报告
node bin/plan-cli.mjs plan

# 核对上一次迁移是否真的落地
node bin/plan-cli.mjs status

# 应用计划(会先查目标端是否还在运行)
node bin/apply.mjs --plan "<plans/.../plan.json>"

# 只算不写,看看会改什么
node bin/apply.mjs --plan "<...>" --dry-run

# 退回最近一次快照
node bin/apply.mjs --rollback

# 装前自检(清单不变式 + 真加载)
node bin/check.mjs

Panel Operations

In the “Plugin Migration” panel on the left sidebar:
1. Select source/target.
2. Compute differences and select the plugins to migrate.
3. Click “Generate Execution Script” or “Apply”.
4. Verify the result of the last migration.

Preflight Mechanism

Before installation, six items are checked. The official dsh plugin add does not check items 2 and 3, so this plugin must block them:

  1. Local-path specs: whether the path referenced by link: / file: exists.
  2. cordis entry ID collisions: when two bundles insert the same loader entry ID, cordis rejects launching the entire tree. Only IDs inside insert: blocks are counted.
  3. Packages without loadable entry points: packages without lib/ in a source checkout that are promoted into the bundle layer can cause startup failure.
  4. Did you declare dsh.bundle.patch?: a package included in the bundles list but not declared will only be installed as a regular dependency by the official tool and will not become a profile-layer plugin.
  5. Engine scope: handles prerelease versions correctly (for example, 0.2.0-rc.2).
  6. git source conditions: only a warning, not blocking. A successful git ls-remote does not guarantee that pnpm can connect; the mechanisms differ. Provides a tarball alternative syntax.

Notes

  • Desktop profile must not be modified via CLI: This is hard-blocked; there is a guard in @deepseek-ai/dsh/lib/bin.js that blocks all CLI invocations by name. This plugin only calls the official manager on desktop.
  • cordis.patch.yml is not synchronized: It contains instance configuration (ports, coordinates, Tailscale addresses); it is not synchronized to avoid port conflicts.
  • Different pinning styles ≠ version changes: Some profiles pin exact versions, while others use version ranges. This plugin classifies these separately as repin, reporting them only and leaving them unchanged by default.
  • Version downgrades are only warned: if version-downgrade warnings appear in the plan, the official manager will reject and roll them back. The plugin states this in advance to avoid ineffective operations.
  • Preserve allowBuilds semantics: An explicit false intentionally disables build scripts. During synchronization, the source-side value is retained, rather than uniformly writing true or flipping false to true.
  • You can preview effects without installing the plugin: bin/plan-cli.mjs is completely standalone and does not depend on DSH being running.

Summary

dsh-profile-sync reduces the error-prone nature of plugin migration between DSH profiles through difference calculation, strict preflight checks, and script generation. It delegates installation to official channels and ensures instance configurations such as cordis.patch.yml are not mistakenly synchronized. It is suitable for developers who need to synchronize plugin sets between web and desktop profiles.

GitHub | Directory page

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye