DeepSeek Harness 插件

dsh-plugin-perf

Out-of-tree dsh web-performance plugin: compression and immutable caching for shell assets and client bundles, plus preload hints — additive, disposable, no dsh source changes required.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
royenheart/dsh-plugin-perf
最近更新
2026年8月16日
分类
工具与能力
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/royenheart/dsh-plugin-perf
插件名:dsh-plugin-perf
作者:royenheart

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器2 个文件
README.md来源说明 · 只读预览

dsh-plugin-perf

An out-of-tree DeepSeek Harness plugin that makes the Web GUI faster over slow or high-latency links (ssh -L, nginx, Tailscale, …) without changing a single line of dsh source. It works purely through public Cordis/dsh extension points:

  • Registers named routes for /, /favicon.svg, /manifest.webmanifest, and prefix /assets that shadow the frontend-static fallback (no route collisions) and replicate its observable behavior exactly, while adding negotiated gzip/brotli compression and immutable Cache-Control for content-hashed shell assets.
  • Registers per-entry prefix routes /plugins/<entryId> that shadow the /plugins owner for its own entries (longer prefix wins) and serve client.js / client.js.map with compression and immutable caching; the bundle URL already carries ?rev=<content-hash>.
  • Injects optional <link rel="preload" as="script" fetchpriority="low"> hints through ctx.webServer.tapIndex for stage-one client bundles.
  • Never touches /api, event streams, sessions, or any other behavior.

Compatibility statement

  • No dsh source changes required. The plugin is a profile bundle: its package manifest declares dsh.bundle.patch: ./cordis.patch.yml, and dsh plugin add reconciles that bundle into dsh.profile.bundles automatically.
  • Additive and unloadable. Every route, index tap, and graph subscription is a Cordis effect; unloading the plugin removes all registrations and clears its caches.
  • Behavior-preserving. For the shadowed paths it keeps the frontend fallback's 405 (non-GET/HEAD), 403 (traversal outside the dist root), SPA index fallback on miss, MIME map, and unknown-extension octet-stream semantics. For bundle routes it keeps the client-modules owner's 404/405 and source-map behavior for any suffix other than client.js / client.js.map.
  • Degrades to a no-op when optional services are absent. In a profile with no webServer the plugin stays idle; with no clientModules it still serves static routes and preload taps; with no frontend dist it skips static routes and still provides bundle routes and preload taps.
  • Tracks upstream fixes automatically. At startup the plugin probes the official server once per optimization point (static compression, static immutable cache, bundle compression/cache, bundle preload). When the official deepseek-harness code already implements a point, the plugin leaves that point unregistered instead of double-applying it. As upstream adopts these optimizations, this plugin will keep updating the detection set in lockstep; even if a new official release arrives before this plugin is updated, the startup probe still prevents conflicts by falling back to official behavior for the features it detects.

Measured effect (simplified report)

How this was measured

The numbers below come from the checked-in benchmark harness tests/benches/bench.mjs, not from ad-hoc local commands: run pnpm fetch-harness to clone the pinned upstream deepseek-harness into gitignored vendor/, pnpm build to build this plugin, then pnpm bench. The harness starts dsh web twice on the same free port with fresh throwaway DSH_HOME directories — once unmodified (baseline) and once with the plugin's bundle mounted through a generated temp patch — so the only difference between the two runs is the plugin overlay. The plugin build used the defaults in cordis.patch.yml (compression: gzip+br, immutableCache: true, preloadClientBundles: immediate). The plain node:http pass measures /, shell assets, and every /plugins/*/client.js bundle; the optional Chrome pass (CHROME_PATH=... pnpm bench) loads the same pages through Chrome DevTools Protocol with Network.emulateNetworkConditions at 50 ms RTT / 2 Mbps down and cache disabled. Raw per-route JSON and server logs are written to gitignored results/run-*/, and the tables below are one such run — rerun pnpm bench at any time to reproduce or refresh them.

Chrome CDP, emulated remote link (50 ms RTT / 2 Mbps down)

MetricBaselineWith dsh-plugin-perfDelta
Encoded bytes received4,497,2401,025,900−77.2 %
Request count6063+3 preload-related fetches under disabled cache
TTFB of /58.1 ms56.7 ms~same (HTML itself is not on the critical savings path)
Time until last plugin bundle17,696.9 ms4,649.7 ms−73.7 %
Total page load (loadEvent)17,855.6 ms4,842.9 ms−72.9 %

Plain node:http, loopback (no emulated latency)

MetricBaselineWith dsh-plugin-perfDelta
Encoded bytes4,412,820898,770−79.6 %
Request count4343unchanged
TTFB of /29.3 ms53.1 msfirst-request brotli warm-up
Last plugin bundle54.2 ms1,552.9 msfirst-request compression cost; subsequent requests hit the in-process compression cache
Total page load57.4 ms1,552.9 mssee the compression-cache note below

Representative routes (Chrome CDP run)

RouteBaseline TTFBPlugin TTFBEncoding added
/assets/index-*.js (442 KB raw)3818.2 ms1938.6 msbrotli
/assets/vendor-*.js (745 KB raw)4981.7 ms2031.6 msbrotli
/plugins/.../dsh-client-connection/client.js4170.0 ms1481.7 msbrotli
/plugins/.../dsh-client-trajectory/client.js(part of the 17.7 s tail)2204.7 msbrotli

Why this is the right fix and why it is safe

The remote-access trace showed the page spends almost all of its time waiting on HTTP: dozens of uncompressed, uncacheable JS/CSS responses over HTTP/1.1 with a six-connection limit. The plugin removes the two largest costs without touching logic: compressed bodies shrink the dominant payload by roughly three quarters, and immutable caching (safe because shell assets are content-hashed and plugin bundles are addressed by ?rev=<content-hash>) makes repeat visits revalidate nothing. Preloading the stage-one bundle tier starts plugin fetches while the shell still executes. All of this happens in transport/serving behavior only: route semantics, MIME handling, 404/405 behavior, the boot manifest, and every /api/event-stream path are untouched, and every registration is a reversible Cordis effect.

Known caveats: the loopback HTTP run shows the first plugin-served response pays compression CPU before the compressed-buffer cache warms up; under a real slow link this is negligible compared with the saved transfer time. With the Chrome benchmark's cache disabled, preloads can add three requests; with normal browser caching the preloaded response is reused by the later script fetch.

Install / load

install.py is a LOCAL-only installer: it never calls dsh plugin, npx, or a registry, and it never edits the profile's own cordis.patch.yml. Every run rebuilds this checkout's host/client bundles, symlinks the package into the profile node_modules, and updates the profile package.json (link: dependency + dsh.profile.bundles). The profile itself must already exist — run any dsh plugin --profile web ... command once to initialize it.

python3 install.py install --profile web
python3 install.py uninstall --profile web

Options are --profile (default $DSH_PROFILE/web) and --home (default $DSH_HOME/~/.dsh). There is no --skip-build or remote spec: local iteration is python3 install.py install then restart dsh. The self-contained bundle patch inserts this row (override it later with a normal profile patch if needed):

- insert:
    - id: web-perf
      name: dsh-plugin-perf
      config:
        compression: gzip+br
        immutableCache: true
        preloadClientBundles: immediate

Restart vs hot reload

A restart of dsh --profile web is required after install/uninstall and after rebuilding this plugin's host code. Host-plane changes (webserver routes, index taps, settings registration) load only at process boot: the shipped web profile disables host-side cordis-plugin-hmr (- id: hmr disabled: true in the web-app bundle patch). The plugin now also ships a client bundle, so while pnpm run dev:web runs from the harness checkout the browser can hot-reload client-side changes; host-side iteration remains python3 install.py install (which always rebuilds) followed by a dsh restart.

Settings UI

Installing the bundle also registers a Performance navigation entry in dsh web → 设置(设置 → 性能). It edits the same durable settings document the host reads at startup and exposes: compression mode, immutable cache, preload tier, auto-detect, probe timeout, compression-cache limits, and the log summary switch. All of these fields are registered with applies: restart, so the UI shows a restart note and changes take effect after restarting dsh --profile web; the bundle patch in cordis.patch.yml remains the composition-level default that user settings override.

Configuration

| Field | Type | Default | Description | |---|---|---|---| | compression | 'gzip' \| 'br' \| 'gzip+br' \| 'none' | gzip | Content-Encoding(s) the plugin may emit when the request accepts them. | | immutableCache | boolean | true | Emit Cache-Control: public, max-age=31536000, immutable for content-addressed shell assets and plugin bundles. | | preloadClientBundles | 'none' \| 'immediate' \| 'all' | immediate | Inject <link rel="preload" as="script"> for stage-one (immediately:true) entries, every entry, or no entries. | | cacheMaxEntries | number | 128 | Compressed-buffer cache entries. | | cacheMaxBytes | number | 67108864 | Total bytes of cached compressed buffers (64 MiB). | | logSummary | boolean | false | Log one bytes-served summary line on unload. | | autoDetect | boolean | true | Probe the official server at startup and skip each optimization point it already implements. | | probeTimeoutMs | number | 2000 | Timeout for one official-capability probe request; probe failures keep the plugin enabled. |

All fields are optional and conservative; the schema is exported as Config (Schemastery) and the plugin also works with no config at all.

Repository contents

  • src/ — the standalone dsh-plugin-perf plugin (this README).
  • tests/benches/ — before/after benchmark harness and report templates; concrete run data stays in gitignored results/.
  • scripts/fetch-deepseek-harness.sh — generic pinned fetch of deepseek-harness into gitignored vendor/ (DEEPSEEK_HARNESS_REPO / DEEPSEEK_HARNESS_REF overridable).
  • analysis/ — trace/session case reports and reusable measurement scripts (trace_analyze.py, session_timeline.py, cdp_bench.py, throttle_proxy.mjs).

Development

pnpm install
pnpm build   # tsc --noEmit + tsdown
pnpm test    # vitest unit tests with fake webserver/clientModules contexts

Unit tests cover route registration/disposal, compression negotiation, cache headers, traversal safety, preload injection, bundle suffix 404/405 semantics, and graph-change resync. No real dsh process is needed.

Benchmark

pnpm fetch-harness   # clones vendor/deepseek-harness (gitignored), ref override: DEEPSEEK_HARNESS_REF
pnpm bench           # before/after runs with fresh throwaway DSH_HOME dirs

pnpm bench boots dsh web twice on a free port (baseline, then with the plugin mounted through a generated temp patch), measures with plain node:http, and — when Chrome/Chromium is found or CHROME_PATH is set — also runs an optional CDP trace with emulated network conditions (default 50 ms / 2 Mbps, tunable via BENCH_LATENCY_MS / BENCH_DOWNLOAD_KBPS). Metrics: total encoded bytes, request count, per-route TTFB distribution, TTFB for /, time until the last plugin bundle, and total page-load time. Raw data goes to the gitignored results/ directory; methodology and report templates are in tests/benches/reports/.