Back to home

dd598

dsh-plugin-auto-install

Windows 下让 DeepSeek Harness (DSH) 自动执行 DSH 插件安装流程的动态 Cordis 插件:显式版本解析、沙箱 danger-full-access 授权自动升级

Stars
0
Language
JavaScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

dsh-plugin-auto-install

A dynamic Cordis plugin that makes DeepSeek Harness (DSH) automatically run the DSH plugin installation flow on Windowspure direct connection, no proxy. Platform: Windows · sample workspace: D:\DshTest · verified with @liustack/modlens@3.17.0

This plugin turns the manual DSH Plugin Installation Flow (direct-only) into a model tool — dsh_plugin_install. Whenever a DSH plugin needs to be installed, the tool runs the whole flow automatically: explicit version resolution, the install command, post-install verification, and automatic sandbox escalation — no manual commands needed.

中文说明


Why you need it

Manually installing a plugin in the DSH Web GUI on Windows (dsh plugin --profile web add <pkg>@<ver>) hits a series of well-known traps:

TrapDetails
Windows TLS stackcurl / Invoke-WebRequest go through Windows schannel and fail with credential errors (SEC_E_NO_CREDENTIALS); only Node fetch (bundled OpenSSL) works
@latest gateDSH has a release-age gate: an explicit version is required; @latest may resolve to an old release and fail with declares no dsh.bundle
Hidden sandbox failure modeunder workspace-write, the sandbox blocks writes to C:\Users\<user>\.dsh\profiles\web and the pnpm store, but the failure looks like ERR_SQLITE_ERROR unable to open database file / pnpm failed (the pnpm store DB outside the workspace cannot be opened) — not a marked [sandbox: file access denied]
Restart requiredDSH must be restarted after a successful install

This plugin automates all of the above and, when the sandbox blocks the install, automatically requests danger-full-access approval and retries once.


What the plugin does

start
 │
 ├─ 1. Resolve explicit version: fetch(<pkg>/latest).version (never @latest)
 │      └─ no version field → fail cleanly, never installs @undefined
 │
 ├─ 2. Install: node <dshBin> plugin --profile web add <pkg>@<version>
 │      └─ sandbox blocked (denied marker OR sqlite/EPERM/pnpm failed signature)
 │           → request danger-full-access approval → retry once
 │
 ├─ 3. Verify: profile package.json contains the package in
 │      dependencies AND dsh.profile.bundles
 │
 └─ 4. Return a structured result (ok / version / verified / exitCode / output tail / restartRequired)

Usage

Option 1: dynamic plugin (current session, recommended)

In a DSH session, ask the agent to:

  1. cordis_define (kind: new, idPrefix: dshi) — put the module.exports object from plugin/host.js into code.host (or paste the apply body directly);
  2. cordis_run (mode: run) to activate;
  3. The dsh_plugin_install tool then appears in the tool list and is called automatically whenever an install is needed.

Option 2: permanent mount (survives restarts)

Mount plugin/host.js as a row in an agent preset's agent.cordis.yml (e.g. a copy of standard), or add it to the host composition. It depends on the host services shell, sandboxPolicy, approval, and tools.

Tool parameters: dsh_plugin_install

ParameterRequiredDescription
packagenpm package name, e.g. @liustack/modlens
versionexplicit version; defaults to the latest resolved at install time
profileDSH profile, default web
profileRootDSH home directory holding the profiles, default C:\Users\jiang\.dsh (used for post-install verification)
nodePathoverride node.exe path (default D:\ruanjian\NodeJs\node.exe)
dshBinoverride DSH CLI bin.js path
dryRuntrue resolves the version and reports what would be installed, without making any changes
sandbox_permissionspre-request sandbox escalation (workspace-write / danger-full-access); requires justification

Returns: { ok, package, version, message, installExitCode, outputTail, sandboxMode, sandboxDenied, verified, restartRequired }.

Example:

dsh_plugin_install(package: "@liustack/modlens")
→ ok: true, version: 3.17.0, verified: true, sandboxMode: danger-full-access
  "installed @liustack/modlens@3.17.0 into profile web (direct) and verified
   (dependencies: yes; dsh.profile.bundles: yes). Restart DSH..."

Implementation highlights

  • Dynamic tool: registered with harness.defineTool + harness.registerTool, automatically torn down with the plugin Fiber;
  • Command execution: uses the host ctx.shell service (PowerShell executor on Windows), each run resolved/executed under the session's sandbox policy;
  • Pure direct: no proxy fallback at all — every network step uses Node fetch straight to registry.npmjs.org (Windows schannel is never involved);
  • Sandbox escalation: re-implements @deepseek-ai/dsh-sandbox's approveEscalation semantics — a strictly-widening ladder (read-only → workspace-write → danger-full-access) plus ctx.approval.request — with no import needed in dynamic code;
  • Failure detection: looksSandboxBlocked() recognizes both an explicit sandbox.denied marker and sqlite/EPERM/pnpm failure signatures (the observed failure shape under workspace-write);
  • Post-install verification: parses the profile's package.json and confirms the package appears in dependencies and dsh.profile.bundles;
  • Input validation: package/version/profile use a strict charset; path parameters only forbid PowerShell single quotes / line breaks, so Windows paths are never wrongly rejected.

Tested (v1.0.0)

  • ✔ version resolution returns 3.17.0
  • dryRun side-effect-free self-check passes
  • ✔ real install: first attempt blocked under workspace-write → automatic escalation to danger-full-access → retry succeeds (Done in 1.3s using pnpm), then verified in dependencies and dsh.profile.bundles
  • ✔ nonexistent package fails cleanly (VERSION NONE), never installs @undefined
  • ✔ known limitation: a dynamic plugin is process/session-scoped — redefine it after a DSH restart (see Option 2 for a permanent mount)

Related docs

License

MIT