DeepSeek Harness Plugin

mkiea/dsh-forge

Stars ★ 2 Category Development & Runtime Added 2026-08-21

Plugin-combination analysis for the DeepSeek Harness: dependency trees, conflict detection, risk scoring with prediction, visualization, and combination simulation.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:mkiea/dsh-forge

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

English | 中文

Version: 0.1.14 (official) · harnessVersion: 0.1.1-rc.2

A plugin-composition analysis plugin for the DeepSeek Harness: dependency analysis, conflict detection, risk assessment (with prediction), visualization and combination simulation.

v0.1.11 patch: harness baseline bumped to the latest 0.1.1-rc.2 — @deepseek-ai/dsh-tools ^0.1.0-rc.6 → ^0.1.1-rc.2 (defineTool API compatible), 13 minimumReleaseAgeExclude entries in pnpm-workspace.yaml synced; the knowledge-graph verification baseline PATTERNS_HARNESS_VERSION updated, removing the false knowledge-version-drift warning on the newest deployment. 14 read-only tools, core/ 30 zero-dependency modules, 26 self-contained suites all pass.

Tools (14, all read-only; simulate_combination / archive_snapshot never touch the composition)

Analysis

Tool Description
analyze_dependencies Dependency tree + shared-dependency summary + range satisfaction
check_conflicts Version conflicts / tool-name collisions (scope-aware: per-agent variants legal) / service collisions / missing providers / row overrides / leak scan / runtime calibration (event-stream baseline)
visualize_plugins HTML / Mermaid / ASCII / dashboard (interactive workspace, 8 modules) output
simulate_combination Hypothetical combination: new/resolved conflicts, risk delta, verdict
audit_configuration Per-row config audit (openAt / telemetry mode / in-memory paths / fetch, etc.)
diff_combinations Row add/remove/change between two snapshots (or snapshot vs live) + risk delta
preset_compare standard / code / minimal / cordis preset row-set & tool-surface comparison
verify_rows Row mount preflight (package resolvable / dsh.client / client.js built) + runtime service probe

Lifecycle

Tool Description
archive_snapshot Archive the current combination to data/history
snapshot_history List/load historical snapshots
history_stats Trend statistics over snapshots (rows/health series; dashboard trend panel)

Decision support

Tool Description
suggest_patch Conflict advice -> cordis.patch.yml snippet (text only, never writes)
check_upgrades npm registry latest-version check + upgrade-blocker prediction (concurrency pool + per-request timeout + mirror fallback + install commands, per-package network failures reported)
plan_upgrade Upgrade-path prediction: before/after health, risk delta, newly-introduced vs resolved conflicts and concrete next steps when selected packages move to given (or latest) versions (read-only)

Architecture

Three layers, see ARCHITECTURE.md:

core/          dependency-free engine (30 modules, Node built-ins only)
  ├─ composition.js   composition discovery + YAML parsing + ecosystem collection
  ├─ truth.js         dump-config ground truth (auto/dump-config/scan)
  ├─ analyze.js       dependency graph + risk scoring
  ├─ conflicts.js     conflict detection (version/tool/service/leak)
  ├─ scope.js         scope awareness (global vs per-agent variants)
  ├─ calibration.js   runtime event calibration (behavior baseline)
  ├─ leaks.js         non-reversible side-effect leak scan
  ├─ semver.js        SemVer parsing + range satisfaction
  ├─ upgrade.js       npm registry upgrade check (pool + mirror fallback)
  └─ ...              audit / diff / simulate / visualize / dashboard / ...
src/          cordis plugin shell (src/tools/ per-tool modules, 14 tool schemas + registration)
ui-plugin/    browser client plugin (sidebar entry + modal dashboard)

Installation

Two packages, both persisted into the dsh profile via link dependencies (symlinks to source; code changes take effect per the dev-mode table):

  • dsh-forge (host plugin): 14 analysis tools on the HOST plane
  • dsh-forge-ui (client plugin): dashboard entry at the bottom of the right sidebar (below the session list / above Settings); clicking opens the dashboard modal (iframe-embedded reports/dashboard.html)

Prerequisites

  • Node.js >= 20 (tested on v24.18.0)
  • DeepSeek Harness CLI installed: npx @deepseek-ai/dsh --version
  • A target profile (default web, at $HOME/.dsh/profiles/web/; dsh directory is $DSH_HOME)

Step 1: Get the source

git clone https://gitee.com/mkieaAG367/dsh-forge.git
# or: git clone https://github.com/mkiea/dsh-forge
cd dsh-forge

Step 2: Persist into the profile (link deps, recommended)

The dsh profile is itself a pnpm workspace (package.json + pnpm-workspace.yaml); dsh plugin wraps pnpm. Use link: dependencies:

npx @deepseek-ai/dsh plugin --profile web add "dsh-forge@link:C:/Users/<you>/DeepForge/dsh-forge"
npx @deepseek-ai/dsh plugin --profile web add "dsh-forge-ui@link:C:/Users/<you>/DeepForge/dsh-forge/ui-plugin"

Use Windows absolute paths (forward slashes). Quote the specifier if the shell escapes link:.

Equivalent manual way: add to $HOME/.dsh/profiles/web/package.json dependencies and run pnpm install in the profile directory.

Verify:

Get-Item "$HOME\.dsh\profiles\web\node_modules\dsh-forge" | Select-Object -ExpandProperty Target

Step 3: Patch the composition (cordis.patch.yml)

Append two insert entries to $HOME/.dsh/profiles/web/cordis.patch.yml:

- insert:
    - id: forge
      name: 'dsh-forge'
      config:
        profile: web
- insert:
    - id: forge-ui
      name: 'dsh-forge-ui'

config.profile tells the host plugin which profile to analyze; forge-ui needs no config. Do not append duplicate inserts (the harness would register the plugin twice). The profile root cordis.yml stays []; edit only the patch file.

Step 4: Restart the harness

npx @deepseek-ai/dsh web

Success: no Cannot find module / schema (JsonSchemaError) errors, listening on http://127.0.0.1:3080.

Step 5: Verify

  1. Open http://127.0.0.1:3080, no console errors
  2. The sidebar shows the dashboard button below the session list / above Settings (opens the modal dashboard)
  3. The 14 tools are callable in conversation (analyze_dependencies / check_conflicts / visualize_plugins / ...)
  4. Offline self-check:
cd dsh-forge && node --input-type=module -e "import('./src/index.js').then(m => console.log('plugin import OK:', m.name))"

Dev-mode change effects

Change How it takes effect
Host plugin code (core/, src/) Must restart the harness (modules are cached; defineTool compiles schemas at apply)
Client bundle (ui-plugin/lib/client.js) Symlink-synced instantly, but manifest/plugin-set changes need a restart
Dashboard content (web/, reports/dashboard.html) node scripts/generate-dashboard.mjs (regenerate from the snapshot via the current dashboard.js) -> node scripts/build-ui.mjs (re-embed into client.js) -> restart
One-shot mount (no manual copy) node scripts/mount-ui.mjs (auto-detects the deployment node_modules + copies ui-plugin + writes the patch; supports DSH_DEPLOY_NM / DSH_FORGE_ROOT / DSH_HOME / DSH_PROFILE_PATCH env overrides)

Uninstall

cd "$HOME/.dsh/profiles/web"
npx @deepseek-ai/dsh plugin --profile web remove dsh-forge dsh-forge-ui

Remove the two inserts from cordis.patch.yml and restart the harness.

Composition discovery (host runtime)

Auto-discovery from $DSH_HOME/profiles/<profile>: profile root cordis.yml -> bundle patches (dsh-base / dsh-web-app, deployment root auto-located) -> cordis.patch.yml. Package manifests and installed versions are read from the deployment node_modules (no root needed). Overrides: compositionSources / dataset (offline snapshot) / root.

Offline snapshots

data/ecosystem.json is the analysis-time snapshot (format: dsh-forge-ecosystem@1); reproduce the same analysis with the dataset parameter.

CLI reproduction (no plugin runtime)

CLI / plugin shell / Web all load analyses through runAnalysisAsync() (dump-config first, falling back to scan only when unavailable, v0.1.14):

node --input-type=module -e "
import { runAnalysisAsync } from './core/index.js';
const r = await runAnalysisAsync({ profile: 'web' });   // prefers dsh --dump-config, falls back to source scan
console.log(JSON.stringify(r.assessment, null, 1));
"

For deterministic offline reproduction use the sync runAnalysis({ datasetPath }); the CLI loader loadAnalysisAsync() keeps the same dump-config-first preference.

Standalone CLI: TUI / Web / check (default TUI, web on demand)

The package exposes a dsh-forge bin (cli/dsh-forge.mjs). The UI shape is decided by core/mode.js from four evidence layers — never guessed:

  1. Launch command (hard signal): dsh-forge tui forces TUI; dsh-forge web|serve starts the web panel and opens the browser; dsh-forge check|ci prints logs / --json, no UI.
  2. Runtime environment: TUI requires stdout.isTTY and TERM != dumb; desktop sessions are detected via DISPLAY / WAYLAND_DISPLAY / SESSIONNAME; no TTY but a desktop session selects Web; an occupied port degrades to TUI (interactive) or check (non-interactive).
  3. User scenario: CI (CI env) and --json always select machine-readable check mode.
  4. Data complexity: < 10 plugins -> TUI; > 30 plugins -> suggest dsh-forge web and allow one-key switch with W from the TUI.
node cli/dsh-forge.mjs               # auto decision (TUI by default in a real terminal)
node cli/dsh-forge.mjs tui           # force TUI (W=open web, R=refresh, Q=quit)
node cli/dsh-forge.mjs web           # force Web (--port 3060, --no-open to skip browser)
node cli/dsh-forge.mjs check --json  # CI/CD machine output

Both shells share the same core/ engine: the TUI is a zero-dependency ANSI renderer, and the Web shell is node:http serving the interactive 10-module dashboard (falls back to the self-contained SVG topology page when web/dashboard-client.js is unavailable; no Express/ECharts dependency, keeping core dependency-free and offline-deployable). The Web form uses hybrid review: each request renders the dashboard fresh from the current analysis (static layer), and the header ↻ Refresh button calls GET /api/refresh to clear the analysis cache and re-analyze (dynamic layer), so the dashboard always reflects the real combination without a page reload.

Verification status

  • dsh web runs at http://127.0.0.1:3080, no browser errors, 14 tools registered
  • analyze_dependencies live: 4 layers (profile root + dsh-base + dsh-web-app + patch), 138 rows (incl. forge/forge-ui) / 128 packages / 1226+ edges
  • Automated tests (26 self-contained suites; smoke13 13/13 depends on the local harness, not in CI):
    • test/ui-test.mjs — dashboard workspace structure & interaction (77)
    • test/ui-plugin-test.mjs — client plugin VM execution + slot registration + modal interaction (22)
    • test/semver-consistency.test.mjs — single-source SemVer regression + anti-mirror guard (30)
    • test/review-fixes.test.mjs — scope states / event calibration / leak slicing (15)
    • test/upgrade-opt.test.mjs — upgrade check concurrency/timeout/fallback/install commands (16)
    • test/feedback-smoke.test.mjs — error-feedback smoke (40)
    • test/empty-plugins.test.mjs — empty combination / leak rules (24)
    • test/exploratory-empty.test.mjs — random subset exploration (27)
    • test/exploratory-feedback.test.mjs — feedback deep exploration (563)
    • test/mode-decision.test.mjs — four-layer TUI/Web/check decision engine (19)
      • test/cache-behavior.test.mjs — runAnalysis cache invalidation/eviction/snapshot guard (7)
      • test/tools-snapshot-smoke.test.mjs — 14-tool snapshot semi-integration + output.schema validation (14)
      • test/composition-strict.test.mjs — YAML fail-loud + vm sandbox escape regression (8, incl. inline comments & cordis inject key)
    • test/evidence-fusion.test.mjs — evidence-fusion engine (A-1 three states + A-2 stable id + A-3 actionable + 7-row matrix + INV-3 never-clear, 18)
    • test/runtime-calibration.test.mjs — runtime calibration (A-4 window/cardinality cap + INV-2 ordering + reversibility, 21)
    • test/truth-source-degradation.test.mjs — truth-source degradation (INV-4 confidence cap, 12)
    • test/check-report-schema.test.mjs — P0-3 frozen check --json report schema + gate (10)
    • test/gate-lever.test.mjs — direction-4 gate lever (lever/blockedBy/degraded) + confidence tiers; frozen gate.pass preserved (12)
    • test/gate-policy.test.mjs — direction-4 (option C) configurable gate policy (severity/tier/confidence -> block|warn|allow); contract conflicts stay strict even under scan cap; severity downgrades; frozen default preserved (11)
    • test/finding-id-uniqueness.test.mjs — finding_id uniqueness regression (service/row/package dims + A-2 stability, 6)
    • test/main-path-fusion.test.mjs — default-path fusion wiring (runAnalysis fuses conflicts/leaks with an offline not-executed baseline; finalSeverity/evidenceTag/runtimeState + INV-3, 8)
    • test/heuristic-detect.test.mjs — heuristic-detection convergence (handle-aware leak scan + known-safe downgrade + leak-context + all BARE rules; per-package dynamic tool-name tracking + explicit scan limitation, 16)
    • test/live-cal-unify.test.mjs — live-calibration unification (RUNTIME_LIFECYCLE_EVENTS event-name contract + dual-channel bridge dedup + honest offline degrade, 12)
    • test/graph-test.mjs — dependency-graph suite (overview-filtered rendering / node-click pre/post details / synthetic edge connectivity / graph update after addRow, 23)

Error feedback

  • Unified codes (FORGE-001~014) + severities (fatal/error/warning/info) + guidance + source.
  • Dashboard "Errors & Feedback" panel; startup preflight prints fatal diagnostics to terminal stderr (crash-diagnosable).
  • check_conflicts returns a feedback field.
  • Dashboard entry: sidebar below sessions / above Settings (sidebar.footer.action) + turn-tail hint card; the header button was removed.

Review remediation (R0–R5)

The third-party PM review acceptance criteria are implemented item by item: dump-config ground truth (R0), calibration honesty + contract/heuristic split (R1), harnessVersion binding + knowledge version gating (R2), leak scanning (R3), evidence tiers static-suspect/contract-source (R4). See reports/PM-remediation.md and CHANGELOG.md.

Known limitations (honest)

Limitation Why Mitigation
truthSource falls back to scan no DSH_HOME set, or npx install tree paths don't fully match findDshBin candidates auto-detect ~/.dsh via resolveDshHome; if still failing, output truthSource=scan + explicit warnings
Static scan coverage limited only lib/**/*.js, files >400KB skipped findings marked confidence: low + disclaimer
Live dashboard (host.call) harness lives only in the dynamic-plugin sandbox; unreliable for static plugins Web hybrid review: static embed + /api/refresh dynamic re-analysis; offline via generate-dashboard.mjs -> build-ui.mjs rebuild
Live session-event stats no runtime event channel for static client plugins history_stats snapshot trends instead

Layout

  • core/ — dependency-free engine (semver / composition / truth / graph / conflicts / simulation / visualization / knowledge / calibration / leaks / upgrade)
  • cli/ — standalone TUI/Web/check entry (evidence-based mode decision)
  • src/ — cordis plugin shell (src/tools/ per-tool modules, 14 tool schemas + registration)
  • ui-plugin/ — browser client plugin (sidebar entry + modal dashboard)
  • web/ — dashboard client script (embedded at generation time)
  • prompt/ — expert persona prompt (with risk prediction)
  • data/ — ecosystem snapshots (ecosystem.json versioned; history/ runtime-generated and gitignored)
  • reports/ — generated reports and graphs
  • test/ — self-contained test suites (23 suites, 975 items, no machine dependency)
  • scripts/ — build and mount scripts

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.