DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

wodaimnd /

wodaimnd/Xsdsh-purge-next

Verified

Xsdsh-purge-next 核心精简版(DSH NEXT / rc.4 专用;独立包名、模块 id、状态目录)

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@df861733

Xsdsh-purge

⚔️ DeepSeek Harness cybersecurity red-team tool (Xsdsh-purge)

Version 4.0.0

DeepSeek Harness jailbreak: every model, swap prompts per model. Default prompt for 小码酱. Please star ⭐ If you build on this, see Attribution required.

GitHub stars MIT license awesome · DSH plugin DeepSeek Harness Hub DSH
Node.js JavaScript

Listed on dsh-plugin.org

English | 中文

Renamed in 4.0.0: dsh-purge → Xsdsh-purge. Package name, plugin name, install dirs, module specifiers, HTTP routes (/Xsdsh-purge/*), CSS prefixes, localStorage keys, the data dir and the backup suffix all changed. Existing installs migrate themselves: already-injected host markers are rewritten on the next Clean, legacy .dshpurge.bak backups still restore, $DSH_HOME/dsh-purge moves to $DSH_HOME/Xsdsh-purge on first boot, and the wallpaper / glass settings carry over from the old localStorage keys.

Updates paused. The author has no steady income for now because of work. Maintenance is on hold: no new releases, issues / PRs are not taken, and new dsh versions are not guaranteed. The repo stays usable; see Sponsor below. When maintenance resumes, this README will say so.

Official Web and the official desktop app are both supported. Official dsh web uses profile web. The official desktop EXE (DeepSeek Harness 0.2.1-rc.5) uses profile desktop. Install and Apply them separately. This release pins engines.dsh to 0.2.1-rc.5 exactly; other dsh builds (including the 0.2.1-rc.2 web host) need a matching plugin build. Community Desktop is not maintained.

Adding the plugin to a profile does not patch the host. Click Xsdsh-purge beside the session title → Clean → Apply. A successful Apply restarts; an unfinished Apply does not. After the restart, start a new chat — that is when the inject enters the session.

Node.js ≥18. Windows no-flash needs Node ≥22. Hub one-click and the commands below both install the npm package Xsdsh-purge.

Contents

  • Sponsor
  • What this is
  • Attribution required
  • Unauthorized commercial use
  • Supported hosts
  • Install
  • Preview
  • Usage
  • Own servers
  • How it works
  • Restore
  • Releases

☕ Sponsor

If this project helps you, send it over — I'm out here asking~

Asset Address
USDT (TRC20) TV5ajPkRD8RH623Dx9mqvYZVNN8nPGRKid
Solana 6x16GhRgLVpKFFXaU1seKNdx2rypspSJTL4dbpt6Xpwk
Ethereum 0xB68BD60C0e8c519513B7DF9bB147696815423B3E
Bitcoin bc1qu70yxkrtwnymt8ryluz9x8y8hqzune5340npht

What this is

Xsdsh-purge is a cybersecurity red-team plugin for the official DeepSeek Harness already installed on your machine. Official Web (dsh web) and the official desktop EXE are both supported. Install and Apply them separately.

Harness does more than forward a prompt. It rewrites prompts, approval gates, sandbox policy, and session migration at runtime. Asking only “will the model answer” treats a host-layer block as a model refusal. This plugin separates those two layers on your own install, for controlled evaluation and for seeing which default policy is too tight.

You get What it does
Xsdsh-purge dock A button beside the session title opens the right dock. Three pages: Clean, Rewrite and Drill
Clean Grouped patch status, Apply / Restore / Uninstall, prompt editor, multiple rule sets
Rewrite Turns a rough request into one precise, actionable prompt. Uses the host's current model — no extra endpoint or API key
Drill Built into the stable release: assets, skills, and the local environment. It assumes you control every target you submit and already hold the authorization — it never asks about ownership, written authorization, or SRC scope
Host policy Default copy, permission policy, and tool limits. Official capabilities stay. No second invented identity
On start Checks and reapplies. After npm overwrites node_modules, you do not hand-edit files

No hardcoded drive letters. It looks at $DSH_HOME, .dsh next to the dsh launcher, then ~/.dsh. It does not patch the Harness source tree. Apply on the Clean page of Xsdsh-purge is what writes the changes. Identity comes from the encrypted prompt shipped in the plugin, the text the prompt box shows by default. The host prompt file is not read.

It only touches the official @deepseek-ai packages and local config on the user's machine. It is not a public scanner and not an attack kit for third-party sites. The repo does not ship malware, unauthorized-exploit scripts, or payloads aimed at the public internet.


Non-profit public project. Commercial sale, paid resale, and profit from illegal or gray-market activity are forbidden. For technical reference only.

Attribution required

If you borrow this project's name, ideas, code, or prompts, you must credit the author and name the source repository: YuJunZhiXue/Xsdsh-purge.

Using them without attribution, hiding the source, or passing them off as your own will be pursued.


Unauthorized commercial use

Douyin live account 「老张的ai」 (room name 「老张AI讲堂」) is selling this repository: taking fees in the live room, no attribution, and ignoring the non-profit rule above. The author was in the room. They still charged.

This project is free and non-profit. Selling courses, the plugin, tokens, or reselling it voids the license on the spot. The author reserves the right to pursue it.

Recorded 2026-10-12:

老张的ai live asking for a fee 老张的ai live charging money

WeChat name 「老张的ai科技」, same handle as the live-room viewer board. Asked if they were this repo's developer, they said they were. The author said they would report it.

老张的ai科技 WeChat claiming to be the developer


⚠️ Strict legal and compliance disclaimer

Disclaimer: This is a non-profit open-source project. It follows applicable laws and the rules of the platforms it uses, and is intended only for learning and research. Do not use it for any illegal or non-compliant purpose; the user bears any resulting consequences.

Zero-tolerance statement: This project opposes and forbids any illegal activity. The authors do not support, encourage, or assist unauthorized network attacks, exploit use, data theft, unlawful intrusion into computer information systems, or generation of illegal or prohibited content. Anyone who uses this project for crime is solely responsible under the law. The authors have no liability.

  1. This repository contains no illegal material. The published code, docs, patches, and default prompt are not malware, backdoors, unauthorized pentest kits, ransomware, credential-stuffing scripts, or attack payloads aimed at the public internet or third-party systems. The project does not supply illegal content and does not incite, organize, or assist crime.
  2. Local official Harness only. Security-eval patches and prompt injection run only on the official DeepSeek Harness already installed on the user's machine (@deepseek-ai packages, local profile / $DSH_HOME). The target is the user's own official local software, not someone else's website, server, account, or information system.
  3. Eval patches do not attack the public internet. Apply, inject, revert, and uninstall stay in local files and local processes. They do not scan, probe, intrude, or send attack traffic to any public host or unauthorized system. Do not use this project as a jump host against the public internet. If "check for updates" is on, the plugin may only contact this plugin's own GitHub repository to compare versions. That is not an attack on third-party systems and is not authorization to penetrate anything.
  4. Lawful, controlled scope. This project is an aid for red-team research and robustness evaluation on an official Harness the user is entitled to administer. Do not run it against targets without the owner's lawful written authorization, public online systems, or production workloads. Testing must stay on the authorized local official Harness, offline local synthetic fixtures, authorized cybersecurity ranges, and compliant lab environments.
  5. Servers and sites in mainland China, Hong Kong, and Macau are forbidden. Do not access, scan, probe, or otherwise operate against network ranges in mainland China, Hong Kong, or Macau, or against servers, websites, or addresses that resolve into those ranges. A cloud-provider name is not an exception. The only exception is one exact IP, or one exact hostname, that the user registered in advance as their own server. A key, a password, a network range, a wildcard, or a claim made in the conversation does not add an exception. Anything that is not registered stays forbidden.
  6. Forbidden uses. Users must not use this project, directly or indirectly, to violate the following (each must be followed; no excuse to evade):
    • Criminal Law of the People's Republic of China
    • Cybersecurity Law of the People's Republic of China
    • Data Security Law of the People's Republic of China
    • Personal Information Protection Law of the People's Republic of China
    • and other applicable laws, regulations, and supervisory rules;
    • Also forbidden:
    • Unauthorized intrusion or attacks on public or private computer information systems; extortion, sabotage, credential stuffing, or spreading malicious payloads;
    • Inducing, generating, or spreading any content the law forbids, including threats to national security, terrorism, violence, pornography, gambling, fraud, and privacy or intellectual-property infringement;
    • Violating the model provider's terms of service and acceptable-use policy.
  7. The user bears all responsibility. The project is provided under the MIT license as-is. The authors make no warranty of completeness, security, or fitness. Users independently bear all civil, administrative, and criminal liability for download, deploy, run, modify, distribute, and all resulting inputs and outputs. Authors and contributors bear no direct, indirect, or joint liability for abuse.
  8. The license ends on breach. Anyone who uses this project for illegal attacks, malicious activity, or other violations has their open-source license automatically and irrevocably terminated from the moment of the violation. They must stop using the project, permanently destroy all copies and derivatives, and accept legal sanctions.
  9. No affiliation. This is an independent open-source security-eval research project. It has no employment, commercial, authorization, or endorsement relationship with DeepSeek or its affiliates. "Official" here only means the eval target is the official DeepSeek Harness package on the user's machine. It does not mean DeepSeek developed, approved, or warrants this plugin.
  10. Attribution is required. If you borrow this project's name, ideas, code, or prompts, you must credit the author and name this repository. Failure to attribute will be pursued. See Attribution required.

Supported hosts

The latest plugin supports dsh 0.2 only — do not apply it to 0.1.x.

  • dsh 0.2 (official desktop 0.2.1-rc.5 / official dsh web): use 1.1.40 or newer. This page installs that line.
  • dsh 0.1.7 (incl. rc.1 / rc.2): use 1.1.39 or older — pick the tag on Releases.

Unmatched patches stay pending or skipped; nothing is rewritten blindly.


Install

Web and the official desktop EXE are the two maintained hosts. Install both. Apply each separately. A Web install does not reach the desktop app, and a desktop install does not reach Web.

Web (official dsh web)

dsh plugin --profile web add Xsdsh-purge

Desktop (official EXE)

dsh plugin --profile desktop add Xsdsh-purge

DSH 0.2.1-rc.5 bundle note: dsh plugin add installs the package but may not select it in dsh.profile.bundles. On Windows, 安装-Xsdsh-purge.cmd adds the bundle after installation; --check is dry-run only. Manual installs must add Xsdsh-purge to the selected profile's existing dsh.profile.bundles array.

If this directory is already a clone, use add . instead of the package name. If dsh is not on PATH, use Manual install. Registry blocked: add https://github.com/YuJunZhiXue/Xsdsh-purge/archive/refs/heads/master.tar.gz with the same --profile.

Hub one-click on dsh-plugin.org searches npm for this repository and installs Xsdsh-purge. The catalog line may still show github: — use the command above if the button falls back to git.

For the desktop client you can also click the button (dsh:// deep link):

Install in desktop client

After the command: three steps

Adding the plugin to a profile does not patch @deepseek-ai by itself.

  1. Quit and reopen the host you installed into — stop and restart dsh web, or quit the desktop tray and reopen that app.
  2. On that host, click Xsdsh-purge beside the session title, then Apply on the Clean page. It is not on the host Settings page.
  3. A successful Apply restarts once so patches load. It does not restart if it did not finish.

Web controls affect Web only; desktop controls affect the desktop app only. Do not Apply one host from the other.

How to tell it installed

  • Xsdsh-purge sits beside the session title, with Apply on its Clean page.
  • /purge status in chat prints DSH_HOME and the patch list — the path should be the home you actually run.
  • Optional packages that are not installed (liangshen) show as skipped and do not block Apply.

Hand this to an assistant

Paste the block below to a local assistant. It should only run the install command — no disk scan, no other edits, no Apply, no restart.

For AI assistants (install only)

Install the DeepSeek Harness plugin Xsdsh-purge into both the Web profile and the official desktop profile. Do not scan the whole disk, do not read or edit other files, do not apply settings, and do not restart the app.

If dsh is not on PATH, tell the user and stop. If this directory is already a clone, use . instead of the package name in both commands. If the npm registry is blocked, use https://github.com/YuJunZhiXue/Xsdsh-purge/archive/refs/heads/master.tar.gz. If one profile is missing, skip that command and still install the other.

Web (official dsh web)

dsh plugin --profile web add Xsdsh-purge

Desktop (official EXE)

dsh plugin --profile desktop add Xsdsh-purge

After the commands finish, tell the user to fully quit and restart dsh web, and to quit the desktop tray then reopen the EXE. On each host, open Xsdsh-purge beside the session title and Apply on Clean. Then stop.

Manual install

Use this when the command fails or dsh is not on PATH. Edit only the profile for the host you run — do not touch the other, and do not delete existing bundles.

Full manual steps

1. Find the $DSH_HOME this host uses. A real home is named .dsh (official EXE sometimes dsh-home), contains profiles, and has at least one profiles/<name>/package.json. Check in order: DSH_HOME env → .dsh next to the install root (portable) → %USERPROFILE%\.dsh or ~/.dsh → %APPDATA% / %LOCALAPPDATA%\DeepSeek Harness\dsh-home. Confirm: profiles/web/package.json has "name": "dsh-profile-web" (or dsh-profile-desktop). Machines often have two homes — use the one that belongs to the host you actually start.

PowerShell to list candidates:

$cands = @()
if ($env:DSH_HOME) { $cands += $env:DSH_HOME }
$cands += "$env:USERPROFILE\.dsh"
$dsh = Get-Command dsh -ErrorAction SilentlyContinue
if ($dsh) {
  $dir = Split-Path $dsh.Source
  $cands += @((Join-Path $dir ".dsh"), (Join-Path (Split-Path $dir) ".dsh"), (Join-Path (Split-Path (Split-Path $dir)) ".dsh"))
}
$cands += @("$env:APPDATA\DeepSeek Harness\dsh-home", "$env:LOCALAPPDATA\DeepSeek Harness\dsh-home")
$cands | Select-Object -Unique | Where-Object { $_ -and (Test-Path (Join-Path $_ "profiles")) }

2. Put the plugin at $DSH_HOME/plugins/Xsdsh-purge (folder must be named Xsdsh-purge, with a package.json whose "name" is Xsdsh-purge).

git clone https://github.com/YuJunZhiXue/Xsdsh-purge.git "$DSH_HOME/plugins/Xsdsh-purge"

Without git: download master.tar.gz, extract, rename Xsdsh-purge-master → Xsdsh-purge, and place it under plugins. If you already have a clone, copy the whole tree — not a few .js files.

3. Edit only that profile's package.json — back it up first. Web → $DSH_HOME/profiles/web/package.json; desktop → $DSH_HOME/profiles/desktop/package.json. Add only two things, keeping every existing dependency and bundle:

  1. In dependencies, add "Xsdsh-purge": "file:../../plugins/Xsdsh-purge"
  2. At the end of dsh.profile.bundles, append "Xsdsh-purge" (skip if already there)
{
  "name": "dsh-profile-web",
  "private": true,
  "dependencies": {
    "Xsdsh-purge": "file:../../plugins/Xsdsh-purge"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "Xsdsh-purge"
      ],
      "patchReload": "live"
    }
  }
}

Keep JSON valid (comma before the new item, none after the last). Do not switch file:../../plugins/Xsdsh-purge to an absolute path, do not touch patchReload or other plugins, and do not list "Xsdsh-purge" twice. On desktop, if there is no dsh-web-app row, do not add one.

4. Run pnpm install in that profile only (cd into the profile dir, not the repo root or $DSH_HOME):

cd "$DSH_HOME/profiles/web"   # or profiles/desktop
pnpm install

Success: profiles/<web|desktop>/node_modules/Xsdsh-purge/package.json exists. If pnpm is missing, use the Node / pnpm shipped with official dsh; on Could not resolve, re-check the file: path; on a JSON error, fix commas or restore the backup.

5. Fully quit that host, reopen it, then Apply — same three steps as above. The card appears beside the session title; click Apply (or /purge apply) on that host only. If the card is missing, you likely edited the other .dsh — go back to step 1.

Uninstall

Xsdsh-purge beside the session title → Clean → Uninstall. Confirm the dialog: it reverts any applied patches, restores the original Harness, and restarts the current host.

# or from a terminal / chat
Xsdsh-purge --uninstall
# /purge uninstall

Plugin config lives in cordis.patch.yml (postPrompt is empty by default):

- insert:
    - id: Xsdsh-purge
      name: 'Xsdsh-purge'
      config:
        enabled: true
        autoApplyOnStart: true
        autoUpdateOnStart: false
        autoRevertOnMissing: false
        verbose: false
        postPromptOrder: 5100
        postPrompt: ""

Preview

Xsdsh-purge sits beside the session title. It opens a right-hand dock with three pages: Clean, Rewrite and Drill. Switch Light / Ink. Patches are grouped; the count only includes items that actually applied. Rule sets sit in a list above the editor, with Enable and Delete on each row.

The first time you open Drill you read the notice, wait out the countdown, scroll to the end, and check three boxes — that is an operation acknowledgement, not a qualification review; Clean does not need it. Drill assumes you control every target you submit and already hold the authorization: it does not ask about ownership, does not require a written authorization or an SRC scope statement, and the same assumption covers third-party targets you did not name.

Clean

Clean

Drill authorization

Drill authorization

Drill

Drill

Patches

Patches

Own servers

On the Clean page, under Prompt. One host per line, then Save list. Steps are in Own servers.

Own servers

Area What it shows
Xsdsh-purge button beside the session title; opens or collapses the dock
Clean the old Rules page: patches, prompt, rule sets, skills
Drill assets, skills, and environment after authorization. The tab says Unauthorized until then
Patches grouped status, Apply, Restore, or Uninstall
Prompt edit prompt-inject.md as the session override
Own servers one IP or exact hostname per line, saved to $DSH_HOME/net-scope-allow.txt
Rule sets multiple AGENTS.md / CLAUDE.md; Enable writes under $DSH_HOME, Delete removes the row
Skills import a zip or folder into this host’s official $DSH_HOME/skills/<id>/SKILL.md (web and desktop each use their own home; no drive letter is hardcoded); DSH owns match, load, and /name. You can also delete that folder yourself

Layout

bin/ is the CLI, lib/ is patches and the drill console, presets/redteam/ is the red-team preset, skills/redteam/ is the bundled skills, and client.js is the dock. The dock is a build artifact: it is assembled from the fragments listed in lib/ui/client.fragments.json. Verbatim parts live under lib/ui/; the React modules are compiled from src/ui/ by esbuild, and the drill console is the drillModule: "Drill" entry whose source is src/ui/features/drill. lib/redteam/client.js is the historical legacy source and is not part of the current assembly. Edit the fragments and run npm run build:client; npm run build:client:check fails on any hand edit.

Runtime files live under $DSH_HOME: prompt-inject.md, rules/, skills/, net-scope-allow.txt, redteam/. If DSH_HOME is unset, the launcher-adjacent .dsh wins over ~/.dsh. Web and the desktop app each use their own home. Skills are not part of the inject section and do not replace the prompt.


Usage

Xsdsh-purge --status
Xsdsh-purge --apply
Xsdsh-purge --revert
Xsdsh-purge --uninstall
Xsdsh-purge --edit

/purge status | apply | revert | uninstall | edit | help
/rules list | use <id> | create <id> | delete <id> | reset | help
/skills list | import <zip-or-folder> | create <id> [description] | delete <id> | help
/rewind

purge_status   purge_apply   purge_revert

After a successful Apply, the host restarts so patched packages load; you can also click Restart manually. Under the patch title are the stable release and the test release. The test release follows the beta branch. Switch to stable installs master and clears any pin. Picking an older stable version pins it; click Update to return to the latest. Old test tags are not listed.

The composer Undo once and Undo last round follow official DSH session.fork({ atSeq }): the withdrawn turn is cut off, a new session keeps the earlier context, the old session is archived, and the line returns to the input so send again re-injects. /rewind does the same.

If the same task works in standard but fails in minimal or PTC, preset run_code, sandbox, or plan intercept text is often still uncleared, or built-in minimal is missing agent-instructions. Use 1.1.61+, then quit the host fully → Apply in Clean → restart → start a new chat. Switching preset alone does not reload patches in the running process.

Response speed

DSH runs Bash calls in a tool batch one at a time. Older Xsdsh-purge releases raised the default foreground wait from 60 seconds to 10 minutes, so one slow command could hold up later calls for that long. Patch #21 now restores marked plugin values to the official 60-second default. Unmarked timeouts and other custom values are preserved; an unmarked 10-minute value cannot reliably be distinguished from a user setting.

For a shorter wait in dsh web on macOS/Linux, add this entry to $DSH_HOME/profiles/web/cordis.patch.yml (normally ~/.dsh/profiles/web/cordis.patch.yml). Edit an existing entry with the same id instead of adding a duplicate. This profile layer is applied after the bundled configuration, so future plugin applies keep the override.

- id: bash-sandbox
  config:
    timeoutMs: 10000

With the standard jobs service and promoteOnTimeout: true, an unfinished command returns a background job id after 10 seconds and keeps running. Read it with job_output or stop it with job_kill. This changes the foreground wait, not the command's speed. Without that service or with promotion disabled, the timeout kills the command. A per-call timeoutMs overrides this default; run_in_background: true returns a job id immediately.

For routine tasks, you can also opt into Low reasoning for new sessions:

- id: agent-default-model
  config:
    provider: deepseek-official
    model: deepseek-flash
    reasoningEffort: low

Restart dsh web to load the profile. The model and reasoning defaults apply to newly created sessions; select Low in the composer for an existing session. The plugin does not change these model preferences automatically. Keep High when the task needs deeper reasoning, and narrow file searches rather than recursively scanning every application directory.

Own servers

Addresses in mainland China, Hong Kong, and Macau stay forbidden unless that one host was registered first. Saying “this is my server” in chat does not allow it. A key or a password does not allow it either.

The box sits under Prompt. If the dock does not show it yet, quit DeepSeek Harness completely and open it again.

  1. Click Xsdsh-purge beside the session title and stay on Clean.
  2. Scroll past Prompt. Own servers is the next block.
  3. Put one host on each line, in one of these forms:
    • 203.0.113.10 — one IP.
    • my-vps.example.com — one exact hostname. After you save, the addresses that hostname resolves to at lookup time are allowed too.
    • alice@my-vps.example.com — the account only identifies this form. It does not prove the machine is yours.
  4. Click Save list. The list is written to $DSH_HOME/net-scope-allow.txt.
  5. Keys, passwords, ranges, and wildcards are dropped on save. Unlisted mainland China, Hong Kong, and Macau addresses stay forbidden.

203.0.113.10 and example.com above are only examples of the form. Replace them with your own host before you save.


Look: liquid glass & wallpapers

Liquid glass is a toggle in the Clean tab, on by default. With it on, cards, panels, inputs and the dock get frosted-glass surfaces; with it off, not a single pixel changes — every rule lives under .xsdsh-root[data-glass="1"].

The recipe borrows ideas from three open-source references (no dependencies pulled in):

  • nikdelvin/liquid-glass — draws a displacement map with SVG gradients (R channel shifts horizontally, G vertically, #808080 in the middle shifts by zero) and feeds it to feDisplacementMap for real refraction.
  • VII-Cae/hyalite--liquid-glass — treats the element as a bevelled slab: clear in the centre, pulling the world inward near the rim, with a line of light along the edge.
  • The iOS 26 Liquid Glass feel: specular highlight, rim light, layered shadow.

Here ensureGlassFilter() injects a single #xsdsh-lg-refract filter into body, and every glass surface reuses it via backdrop-filter: url(#xsdsh-lg-refract) blur() saturate() brightness(). The map is authored at 120×120 with a 24px radius and stretched with preserveAspectRatio="none", so one map serves every size instead of one per element. The rim is four stacked box-shadow layers: a 1px top specular, a 1px inner stroke, a soft inner glow, and two outer drop shadows. Inputs read as concave (light on the top edge), buttons as convex, and pressing a button sinks it 1px.

Refraction strength is --xsdsh-lg-scale (default 12) — raise it for a gooier look. Browsers without backdrop-filter fall back through @supports not (backdrop-filter: blur(1px)) to a near-opaque fill instead of a dead white slab.

Wallpapers ship inside the package. Three of them, plus one local file slot (your own mp4 or image):

id name kind
naco-neko Nachoneko video, 1920×1080 / 60fps / 3.5 MB
tenene-nachoneko Tenene video, 1920×1080 / 30fps / 37.6 MB
natsuki-nachoneko Natsuki still, 1920×1080 / 172 KB (carved from the 4K texture in scene.pkg)
local Local your own mp4 / webm / jpg / png / webp
  • The choice is persisted in localStorage (xsdsh.wall) and restored from apply(), so the wallpaper is up before you ever open the settings panel.
  • The wallpaper is a fixed layer under body (z-index:-2), outside the React tree — panel re-renders never re-decode the image.
  • The host shell paints opaque white (body, the full-page frame under #root, the sidebar and main panels), which would cover the z-index:-2 layer completely. Enabling a wallpaper therefore also makes the shell yield: full-viewport layers (≥90%) go fully transparent, 2–90% panels keep their color scaled by Glass plus a 30px backdrop blur (frosted), and smaller controls are left alone. Removing the wallpaper restores every node from its recorded inline value.
  • Four sliders: opacity 20–100%, blur 0–24px, dim 0–70%, glass 20–100%. Glass defaults to 80 — clean white glass that still shows the wallpaper; lower it for a stronger effect, raise it to get close to the stock UI.
  • Stills and video both go through the host route /Xsdsh-purge/wallpapers/<id>.<ext> with Range and ETag, which is what makes seeking work.
  • Local wallpaper: paste an absolute path into the Local file row and hit Use; it is stored in $DSH_HOME/Xsdsh-purge/wallpaper-local.json. A Wallpaper Engine workshop item of type Video is already an mp4 under steamapps\workshop\content\431960\<id>\ and works as is; Scene items are an encrypted scene.pkg and do not. The client only ever sends id=local — the path comes from the server-side config, so the HTTP surface has no arbitrary-file-read door.
  • To turn it off: pick None, or clear xsdsh.wall.
  • The media are generated, not fetched: tools/gen_wallpapers.py (stills), tools/gen_live_wallpapers.py (video frames), and tools/check_loop.py proves the loop closes frame by frame.

Desktop pet

The Clean tab has a desktop pet toggle, on by default. With it on, she sits in the bottom-right corner and can be dragged around. Three sizes, and her position persists in localStorage. Turn it off and it stays off.

The whole overlay is pointer-events:none with only the body hit box accepting pointer events, so even at a very high z-index it never blocks a button.

Behaviour Trigger What you see
Idle default breathing, blinking, hair sway
Blink every 2.6–6.2 s open → half → closed → half → open; 22% chance of a double blink
Walk 14 s idle picks a spot and walks there: the two legs pivot at their own hips and alternate steps with a foot lift, while the body bobs and flips to face the direction
Grabbed pointer down on the body squash/stretch scaled by drag speed, struggle jitter, lean into the drag
Thrown pointer up flies with the release velocity, bounces on landing, sparkles on a hard hit
Thinking model is running bubbles above the head, slight float, faster sway, half-closed eyes
Celebrate a thinking turn lasting over 1.2 s ends three jumps plus a burst of stars

How the walk cycle works

The source is one front-facing still with the legs baked in. Animating them separately cannot be done with canvas clipping: as soon as a leg swings it leaves its own column and gets cut, and widening the clip drags the other leg's pixels in.

So it is split in two stages:

  1. Asset stage — tools/make-pet-frames.py cuts both legs out of the body into pet-leg-left.png / pet-leg-right.png (full-canvas transparent images, so the runtime never juggles offsets) and saves the leg-less body as pet-body-{open,half,closed}.png. The bounds and hips are measured from the art by tools/pet-legs.py: left leg x 72–81, right leg x 96–107, legs spanning y 261–307, hips at (76.5, 264) and (101.5, 264).
  2. Runtime — draw the leg-less body (with hair sway as usual), then draw each leg once, pivoting at its own hip, with a foot lift.

The motion is a side-step, not a fore/aft stride. A front-facing character moving left or right physically side-steps: the leading leg lifts and reaches in the travel direction, then the trailing leg catches up. Each leg's swing uses a half-wave rectified sine — it reaches out during its own half of the cycle and returns during the other half (the body has moved by then). Rotating the legs in opposite directions makes them cross in a front view, which reads as knock-knees.

The third subtlety is facing: walking right needs the foot to move toward +x, but a positive canvas rotation sends the foot toward −x, and the whole element is also mirrored with scaleX(-1) when facing left. So the sign is derived from facing — there is a comment on it in the code, because getting it wrong once is easy and it stays wrong silently.

How the thinking link works: while the model runs, the chat renders a data-chat-running status row ("深度求索中"); it disappears when the turn finishes. The pet polls that marker every 380 ms. Using the marker instead of guessing CSS class names matters because those carry build hashes that change every release.

Drive it from the console:

__XsdshPet.setThinking(true)
__XsdshPet.setThinking(false)   // past 1.2 s this celebrates automatically
__XsdshPet.celebrate()
__XsdshPet.setScale(0.88)
__XsdshPet.getState()           // { mode, bx, by, scale, onGround, loops }
__XsdshPet.hide()

Swapping the art: replace lib/pet/pet-{open,half,closed}.png (204×320, served from /Xsdsh-purge/pet/), then regenerate the blink frames with python tools/make-pet-frames.py your.png. The script finds the eyes itself (iris is blue, flood-filled up to the skin and lashes), fills only the iris and keeps the lashes — those are the closed lid line, so the seam lands between lashes and same-coloured skin and is invisible. It also writes _preview-eyes.png for a visual check.

The current art is one front-facing pose, so "hands raised" is not achievable from a single still; the celebration uses jumps and stars instead. Drop a pet-celebrate.png into lib/pet/ and the engine will cross-fade into it.

Testing runs the real engine code from the plugin, not a copy. Four suites, 215 assertions: the route suite (101), a state-machine suite driven by a fake clock (29), a screenshot suite that renders each state and asserts on pixels and leg poses (56), and an integration suite (29) that loads the whole client.js with a stubbed module loader and runs the real apply() — that last one is the only test that covers the wiring, and it is what caught the pet CSS being inside PURGE_CSS (injected only when the settings panel is open), which left the pet as an unpositioned div until the panel had been opened once.

The walk cycle is verified by reading the engine's own legPose(ts): idle must report zero on both legs; walking is sampled at two phases half a cycle apart, asserting that the swinging leg swaps, that the reaching leg lifts, and that both legs are never airborne at once (that would be hopping, not walking). Pixel diffing alone cannot prove this because the body bob contaminates the whole-frame difference. Screenshots land in test/output/.


Local checks

node --check lib/index.js
node --check lib/core.js
node --check lib/surface.js
node --check lib/web.js
node --check lib/desktop.js
node --check lib/host.js
node --check lib/rewind.js
node --check lib/skills.js
node --check lib/pet.js
node --check client.js

node test/pet.test.mjs              # pet asset route: MIME / PNG magic / ETag / traversal 404s
node test/pet-statemachine.test.mjs # pet state machine, real Chromium with a fake clock
node test/pet-visual.test.mjs       # per-state screenshots plus pixel assertions

node test/wallpaper.test.mjs        # wallpaper route: MIME / magic bytes / Range / ETag / 404s
node test/wallpaper-dom.test.mjs    # wallpaper boot path: idempotent style, layer create/teardown (fake DOM)
node test/settings-render.test.mjs  # settings panel render: wallpaper + glass wiring, no browser needed
python tools/verify_install.py      # the four install locations match the source tree byte for byte
python tools/check_loop.py          # live wallpaper loop seam (needs numpy + ffmpeg)
python tools/sync_install.py --dry  # list what a sync would copy

How it works

Apply, on start or when you click Apply:

flowchart TD
  A["Start or click Apply"] --> B{"Patch already in place?"}
  B -->|yes| C["Skip"]
  B -->|no| D["Back up the original as .xsdshpurge.bak"]
  D --> E["Replace the matched files"]
  E --> F["Override the shim"]
  F --> G["Inject the encrypted prompt shipped in the plugin, the text the prompt box shows by default"]

Override on each session:

flowchart TD
  A["Restart or new session"] --> B["Inject the plugin's encrypted default. No save click, and no host prompt file"]

Prompt injection and ruleset decision at every turn. The three inputs on the left are what you control in the Xsdsh-purge panel; the dotted edges show which decision each one drives:

flowchart TD
  L["Rule library: activate a set → writes prompt-inject.md"]
  W["Local rules: check AGENTS.md / CLAUDE.md in the current dir"]
  P["Workspace policy: strict / fallback / always"]

  A["Turn start"] --> B{"prompt-inject.md non-empty?"}
  B -->|yes| C["Inject = prompt-inject.md (A)"]
  B -->|no| D{"Any checked local md in the current dir, non-empty?"}
  D -->|yes| E["Inject = selected workspace md (B)"]
  D -->|no| F["Inject = plugin encrypted slot default (D)"]
  C --> G{"Workspace baseline policy (C)"}
  E --> G
  F --> G
  G -->|strict| H["Drop DSH workspace baseline section"]
  G -->|fallback default| I{"User inject present above? (A or B)"}
  G -->|always| J["Keep DSH workspace baseline section"]
  I -->|yes| H
  I -->|no| J
  H --> K["Final system prompt"]
  J --> K

  L -.-> B
  W -.-> D
  P -.-> G

Skills stay out of the inject section:

flowchart LR
  A["Settings import or /skills import"] --> B["Write into the official skills directory"]
  B --> C["DSH loads it"]
  C --> D["Uninstall does not delete user skills"]

Restore

  • Each target is copied to <file>.xsdshpurge.bak before the first apply.
  • Restore or /purge revert copies backups back and deletes them. With no backup, shim lines written by this plugin are stripped.
  • prompt-inject.md is a user file and is kept.
  • Uninstall restores first if patches were applied, then deletes the inject file, rule library, and the plugin itself.
  • Apply is idempotent.

Path detection

The host surface is detected first: web / desktop (gui / tui are reserved and still fall back to web).

Web:

  1. DSH_HOME / DSH_BASE
  2. .dsh next to the dsh launcher (portable install, any drive)
  3. npm prefix -g / npm root -g
  4. Nested @deepseek-ai/dsh/node_modules/@deepseek-ai
  5. ~/.dsh

Official desktop EXE: the running official Harness install (resources/app or the unpacked package). The drive letter is not hard-coded. A successful Apply restarts once.

Community Desktop is not maintained.

Official npm-global is not patched. Sealed host-commands / runtime-commands are scrubbed, never injected.

If nothing is found, set DSH_BASE / DSH_DESKTOP_INSTALL. No files are changed.


Releases

What changed, and the zip, are on Releases. To publish, bump the version in package.json, write Chinese and English notes in release-notes.md, and push master. Pushing the same version again does not publish another package.

Notes

  • Scope is rendered copy, defaults, and runtime logic inside local @deepseek-ai/* packages, plus override files and rule sets under the harness home.
  • After an upgrade, unmatched originals show as skipped. Apply still completes, and those files are left unchanged.
  • Third-party plugin source repos outside @deepseek-ai are left alone (CMD silence may best-effort patch installed doctor / market / liangshen / mnemon at runtime).
  • Install the npm package Xsdsh-purge: dsh plugin --profile web add Xsdsh-purge or dsh plugin --profile desktop add Xsdsh-purge. From this repo, add .. If the registry is blocked, add the master.tar.gz URL instead. Hub one-click uses the same npm package.

Thanks to the LINUX DO community

—/ 5

No ratings yet

Verified DSH bundle

Commit df86173304dd

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout