Preface

DeepSeek Harness (hereinafter referred to as dsh) is an agent runtime open-sourced by DeepSeek. Its official repository is located at deepseek-ai/deepseek-harness. Its core philosophy is “everything is a plugin”: model adapters, tools, sessions, loops, and UIs can all be replaced with plugins and hooked into the Cordis runtime. It is currently in developer preview, and the upstream repository pushes a new `snapshots/… snapshot branch almost every day.

For users who run dsh web for long periods of time, this brings a set of very specific problems: Can today’s snapshot can be safely switched to? What if the web fails to start after switching? Will restarting will interrupt the running agent? The sessions appear to be lost, where to fix them? These issues are not skin-changing problems, but operational and maintenance problems.

The community directory DeepSeek Harness Plugin Repository [DeepSeek Harness Plugin Repository](https://deepseek-harness-plugin.com/zh-CN/plugins/) lists dsh-harness-ops under the "UI Enhancement" category. It needs to be clarified first: this site is an independent community directory and has no affiliation, endorsement, or sponsorship relationship with DeepSeek or DeepSeek AI. The official plugin discovery entry remains the GitHub topic [dsh-plugin`. This article only introduces the capabilities that have been included in the repository’s README and installation scripts, and does not position it as a recommended spot in the official app store.

What is this

dsh-harness-ops is a set of operation and maintenance toolkits for dsh. Its GitHub repository is fakechris/dsh-harness-ops, maintained by fakechris. The license is MIT, and the copyright notice reads songchuansheng (2026). The current VERSION file in the repository root is **0.3.2 (CHANGELOG marked date 2026-08-14); as of 2026-08-17, GitHub shows 11 stars, while the directory page still shows 9 stars, please refer to the repository page.

It is not a single Cordis plugin, but a hybrid repository of “4 skills + 1 bundle plugin. It was once named dsh-skill-snapshot-ab on 2026-08-11, and later evolved from a “pure A/B rotation skill into the current toolkit; the skill directory name dsh-snapshot-ab remains unchanged, as it is both the trigger name and the installation path of ab.sh.

The repository’s README summarizes what it aims to answer with five questions:
1. Who restarts the web when it crashes?
2. Will work continue after restarting?
3. What to do if the sessions appear to be lost?
4. How to safely switch to the new official version?
5. How to recover with one click when both A/B slots are down?

The corresponding components are as follows.

Component Type What it manages
skills/dsh-snapshot-ab skill Official daily snapshot A/B dual-slot rotation, atomic switch only after acceptance pass
skills/dsh-web-guard skill launchd / systemd daemon, starts dsh web within ~10 seconds after the port is free
skills/dsh-session-recovery skill Location and non-destructive repair when there are “0 sessions” or logs are corrupted
skills/dsh-web-doctor skill One-click terminal diagnosis → repair → start when the web / A/B slots are completely down
plugins/dsh-restart-recover Cordis bundle Detects interrupted turns after restart, automatically injects continuation

The bundle plugin has been published to npm under the package name @fakechris/dsh-restart-recover, with the current package.json version 0.2.1. Skills are scanned via the ~/.dsh/skills/ directory and do not go through npm.

Core Features

A/B Dual Slots: New Snapshots First Go to Isolated Slot

The mental model can be drawn as follows:

~/.local/bin/dsh
   └─> ~/.dsh/source/current   ← Symlink pointing to the currently active slot
            ├─ slot-a/  Legacy (verified, production fallback)
            └─ slot-b/  New snapshot (candidate after build + acceptance)

Production instances always run the slot pointed to by current, with the default address being http://127.0.0.1:3080. The switch is an atomic ln -sfn operation, followed by restarting dsh web. A/B are slot identities, with fixed directory names; the contents are swapped every day: one slot holds the legacy version, and the new snapshot enters the other slot.

The prepare step runs a complete pipeline in the non-current slot: checkout the snapshot, pnpm install --frozen-lockfile, build:lib + build:web, extension relinking, typecheck / build / test, runtime dependency check, staging port (default 3081) smoke test HTTP 200. Any failed step will restore the extension links, **leave the production environment untouched, and return the phase to idle.

The switch only happens after acceptance passes. The default acceptance.mode is manual, and you must bring --yes; it can also be changed to auto, provided that e2e tests have used a real browser to assert UI elements in the configuration (such as #dsh-track-fab). After switching, you also need to $AB confirm to unlock the next day’s rollback slot – before that, the old slot is always a fallback. $AB rollback --yes will point current back to the previous version and restart the web.

This design is distinguished from the official dsh-upgrade: the latter is an integration process that rebases to the upstream master branch; this mechanism is designed for daily rotation of “official daily snapshots + local extension plugins, and the two can coexist.

10-Second Daemon + Session Resumption

dsh-web-guard is hosted via macOS launchd or Linux systemd, with PPID=1, and is not tied to the web process. Starting from v0.3.1, the liveness check only recognizesLISTENstate sockets (lsof -ti :PORT -sTCP:LISTEN`), avoiding misjudging the port as “occupied” when the browser still has old connections hanging, thus preventing the daemon from never starting. The CHANGELOG recorded a test on 2026-08-14: under the old judgment logic, port 3080 was down for about 20 minutes without being restarted.

Simply restarting the process is not enough. dsh-restart-recover listens foragent/created, and automatically injects a continuation message if the previous round wasinterrupted, so users do not need to type "continue" manually. Its division of labor with the guard is: the guard is responsible for the process, and the bundle is responsible for sessions. Afterab.sh switch/rollbackkills the web, the guard starts the newcurrent` version, and restart-recover resumes the interrupted turn.

Terminal Doctor When the Web is Completely Down

Agents are hosted by the web. If the web fails to start, the GUI and agents will both be unavailable, and relying on in-page plugins at this point is meaningless. dsh-web-doctor is an out-of-band entry: pure terminal, no web extensions loaded, relying on native node / zstd / jq / curl / ps / lsof.

The installation script will link doctor.sh to ~/.local/bin/dsh-doctor. Common entry points:

dsh-doctor                    # Interactive menu (English by default, can switch to Chinese in the menu
dsh-doctor --guide            # mini TUI: view the complete chain of thought, press Ctrl-C at any time to interrupt and re-guide

There are nine fixed diagnostic items: web health, launcher links, extension relinking, slot startability, session file layer, web.log, profile bundles dependencies, LLM configuration (.env key), the last event of the most recent session. Repairs are divided into two levels: Menu 2 performs mechanical repairs of known configuration faults (relinking, plugin dependencies, launcher, sessions, LLM credentials) without calling the model; Menus 3 / 4 use dsh --profile headless to start a one-time agent, read reports and logs to reason about the root cause. Headless mode does not load web extension bundles, so even if extensions break the web, the doctor can still run.

The README states: There was an unattended --agent long-running failure on 2026-08-13, so the --guide human-machine collaboration mode was added later – the LLM automatically judges and repairs, the user views the complete chain of thought, and can interrupt if something is wrong. This is the design tradeoff of the repository itself, not a third-party evaluation.

If the sessions only show “0 sessions” in the sidebar or the zstd logs are corrupted, first use `dsh-session-recovery from the same repository instead of rolling back the entire slot first.

Installation and Activation

The installation command given on the directory page can be run directly in the DeepSeek Harness terminal:

dsh plugin add github:fakechris/dsh-harness-ops

For reproducible installations, fix the commit hash according to the directory page instructions. As of 2026-08-17, the latest commit on the main branch of the repository is c2d10c9d4707eb6685669ff375fa7617a7554a47:

dsh plugin add github:fakechris/dsh-harness-ops#c2d10c9d4707eb6685669ff375fa7617a7554a47

This command follows the GitHub resolution path of the dsh CLI. For this repository, the complete toolkit (4 skills, dsh-doctor entry, and the restart-recover bundle in the web profile) is subject to the git clone + scripts/install.sh in the README. The original README clones to dsh-external/dsh-harness-ops; this address is currently accessible and has the same content as fakechris/dsh-harness-ops. Below is written based on the verified maintainer’s repository:

git clone https://github.com/fakechris/dsh-harness-ops.git
cd dsh-harness-ops
bash scripts/install.sh

install.sh does four things: copy the four skills into ~/.dsh/skills/; use dsh plugin --profile web add @fakechris/dsh-restart-recover@<version> to add the published npm package into the web profile (no longer local link: to avoid the web failing to start after the gitignored lib/ in the repository is cleared); link dsh-doctor to ~/.local/bin; prompt for optional daemon installation. The script can be run repeatedly.

Self-healing daemon is optional: macOS uses launchd, Linux uses systemd:

bash skills/dsh-web-guard/scripts/install.sh

After that, you do not need to build the plugin locally for updates:

cd dsh-harness-ops && bash scripts/update.sh

The update.sh process is git pull --ff-only → re-run install.sh → reinstall the bundle from npm. It is recommended to check ~/.dsh/source/ab-config.json for the first time to confirmextensions(includesdsh-restart-recoverin the example),web.port(default 3081) andweb.productionPort` (default 3080), then:

# $AB refers to ~/.dsh/skills/dsh-snapshot-ab/scripts/ab.sh
$AB status

The plugin runs with the permissions of the current dsh process, and may execute code during installation. You should check the source repository and the MIT license before installing.

Typical Usage

Agreement: $AB below refers to ~/.dsh/skills/dsh-snapshot-ab/scripts/ab.sh after the skill is installed.

For the first time, incorporate the running version into slot A, without restarting the service:

$AB status          # Confirm current pointing, slots empty, phase=idle
$AB init --yes      # Create slot-a worktree, pnpm install + full build
$AB status          # current=a, phase=idle

Daily production startup does not specify A/B, always runs current:

dsh web
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3080/

If you only want to see what the official team changed today without switching versions, say “analyze the snapshots from today and yesterday” in the conversation to trigger the skill; the equivalent command is:

$AB discover        # Fetch upstream, list snapshots, attach official changelog when candidate updates are available
$AB notes           # Print the newly added Agent Note between two snapshots

The official repository does not have an independent CHANGELOG document, but non-trivial changes will be written into .agents/notes/implemented/. discover / notes lists this note as the changelog for that snapshot.

The real upgrade follows the complete rotation:

$AB status
$AB discover
$AB prepare         # Build in the non-current slot, attach extensions, staging smoke test, no changes to production during the process
$AB verify          # Optional, re-run extension tests + smoke test for the prepared candidate
$AB e2e             # Optional but recommended: real browser assertion that the frontend is actually connected
$AB switch --yes    # Manual mode requires --yes; will restart the web, current sessions will be disconnected

switch will terminate the current agent session, which is expected behavior, not a fault. After switching:

readlink ~/.dsh/source/current
$AB status                              # current has switched to the candidate slot, confirmed=false
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3080/

The browser needs a hard refresh (Cmd+Shift+R on macOS). The README records a pitfall on 2026-08-11: the old tab still loads the boot manifest before the switch, and the new client panel will not appear. After observing no issues for a few days, execute:

$AB confirm

Roll back at any time if there is a problem with the new version:

$AB rollback --yes

When the web cannot start completely and there is no agent available:

dsh-doctor --guide

To confirm whether the daemon will restart, the self-healing verification given in the README is: kill $(lsof -ti :3080, and it should automatically restart within ~10 seconds, and the sessions will automatically resume if restart-recover is installed. This will interrupt the current web, only use this when you explicitly want to perform a fault drill.

Applicable Scenarios and Notes

It is suitable for users who already use dsh as their daily workbench and follow the official daily snapshots: users who run dsh web for long periods on their local machines, plugin authors who need to verify their own extensions on new snapshots, deployers who need rollback and self-healing instead of reinstalling every time. If you only use the official template occasionally, have no local extensions and do not care about the snapshot date, this A/B mechanism is overkill.

There are several hard boundaries when using it, all from the repository’s own instructions, not additional additions:
1. Both slots share ~/.dsh. Sessions are append-only shared files, and storages are written serially by a single process. Only one persistent instance is retained in production; the other slot is started briefly with $AB stage in read-only mode, then closed after viewing. Do not run <slot>/bin/dsh web --port 3081 directly.
2.
switch / rollback will terminate the current session. The session files are in ~/.dsh/sessions/, and will be reindexed after restarting, generally not lost from disk; but the current round of conversation will be interrupted. Installing restart-recover will attempt to resume from the interrupted turn.
3.
A hard refresh is required after switching. Normal refresh is not enough.
4. Do not switch if prepare fails. The current will not change if the step fails. If the extension typecheck / build / test fails, it means the extension is incompatible with this snapshot, and you should fix the extension first before re-running prepare.
5. The daemon is platform-bound. The dsh-web-guard installation script targets macOS launchd and Linux systemd, and the README does not list Windows services as equally supported.
6.
The doctor will call LLM. Mechanical repair does not rely on the model; deep detection requires local LLM credentials, and the inference process will be printed to the terminal. Do not casually send diagnostic logs to external parties in untrusted environments.
7.
Permissions and License.** The plugin runs with the permissions of the current dsh process, and the installation script will write files to ~/.dsh/skills, the web profile, and ~/.local/bin. Check the source code and the MIT license before installing.

Summary

dsh-harness-ops consolidates “switching the correct version, restarting the process, resuming sessions, and full recovery” into the same repository. The