dsh-research-panel
Verifieddsh-research-panel · v0.1.1 · MIT · Web UI
Research tab for the DSH Web session page: a read-only panorama of installed agent skills — trigger commands (/skill) plus plain-language purpose notes, so users never have to memorize the skill corpus.
Install
dsh plugin add dsh-research-panel Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Readme
dsh-research-panel
A DeepSeek Harness web bundle that adds a Research tab to the session view switcher (right of 会话 / 轨迹).
It answers one question: what skills are actually installed right now? For every
skill found it shows the trigger command (/name, click to copy) and a plain-language
purpose, so the corpus does not have to be memorized. A curated Chinese overlay
(dsh/curated.json) sits on top of the live scan, with the original SKILL.md
description as the fallback — the UI records which one is showing.
How it works
The host half scans every
SKILL.mdunder the skill roots in precedence order (~/.agents/skills, then~/.claude/skills) and merges the curated overlay.It mounts one exact route on the authenticated shared
/apichannel:POST /api/research-panel/skills → { ok: true, value: { features, workflows, updated, all } }The browser half calls that route with plain
fetch, resolving the URL againstdocument.baseURIso a deployment prefix survives.
Compatibility
Built for dsh 0.2.0-rc.2. Declared peers:
@deepseek-ai/dsh-client-connection and @deepseek-ai/dsh-client-ui-conversation
at ^0.2.0-rc.2.
Why 0.1.0 broke on 0.2.0-rc.2 (and why nothing said so)
0.1.0 mounted its host endpoint with
ctx.connection.rpc.handle('/research-panel', handler). That call registers its
physical route as owner.effect(() => owner.webServer.register(route)); the
effect's own fiber carries no injects, so the owner.webServer read throws
Error: cannot get property "webServer" without inject
from any non-root caller. The host half therefore loaded cleanly, registered
nothing, and the browser's POST /research-panel/skills fell through to the
static SPA handler — HTTP 405, which is what the tab reported as
加载失败:transport failure for /research-panel/skills: HTTP 405.
Two independent reasons this stayed silent:
- The plugin declared no
peerDependencies, so dsh's 0.2.0 peerDependency gate had nothing to compare and never flagged the bundle. 0.1.1 declares both services at^0.2.0-rc.2so the next drift is caught at startup instead of at click time. rpc.handleis still exported and documented, but no package in the dsh tree calls it any more; the shared channel's singlerpc.interceptslot belongs todsh-api-gateway.
0.1.1 uses ctx.connection.fetch.register() — the documented extension point for
"exact Fetch routes that cannot use JSON Remote invocation" on the shared /api
channel, already behind the Host/Origin fence and browser authentication. It never
touches owner.webServer, so it works from any plugin context.
dsh-api-session-controller (GET|HEAD /api/file), dsh-client-file-upload,
dsh-client-ui-deliverables and dsh-session-log-export all mount their routes
this way.
Install
dsh plugin --profile web add dsh-research-panel
# restart dsh web to activate the tab
User data ($DSH_HOME settings, credentials, sessions) is never touched.
Structure
dsh/index.mjs host half — SKILL.md scan, curated overlay, /api route
dsh/client.js browser half — the Research tab (conversation.view, id "research")
dsh/curated.json curated Chinese descriptions and workflow sequences
cordis.patch.yml dsh.bundle.patch — inserts the research-panel row
test/host-smoke.mjs standalone smoke test for the pure host functions
License
MIT