dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Doc Present for the DeepSeek Harness (dsh): let the agent show plans and designs instead of dumping long text into the chat.
When the agent has a proposal to present — an architecture, a flow, a state
machine, a message sequence, a numeric curve, a UI walkthrough — it publishes a
self-contained interactive HTML page (inline CSS/JS, FX animation
framework included) and you view it in an in-GUI panel or any browser,
including colleagues on the LAN.
方案展示插件:agent 把方案做成自包含 HTML 动态演示页(状态机/时序/曲线/UI 四类动图配方),你在 GUI 内嵌面板或浏览器里看,替代对话框长文。
| Surface | What you get |
|---|---|
| In-GUI panel | 📄 方案预览 button in the session header opens a drawer with the doc list and a live iframe preview (same-origin route /doc-present/... on the dsh web server — no CORS, no extra port needed for local viewing). |
| Tool card | Each doc_present tool call renders a card in the conversation with 在面板中打开 / 浏览器打开 / 复制内网链接 buttons. |
| LAN server | A standalone preview server on 0.0.0.0 (default port 8899, auto-scans upward if occupied) so colleagues open http://<your-LAN-IP>:<port>/<slug>/ directly. Started lazily on first publish; survives nothing but a dsh restart (docs persist on disk; it re-ensures itself on next use). |
package.json plugin manifest (dsh.client declaration, exports["./client"])
lib/index.js host half: doc_present tool, /doc-present command, prompt section, /doc-present web route
lib/server.js document server core (pure Node, no dsh imports — standalone-testable)
lib/client.js client half: header button + overlay drawer + doc_present tool card
assets/template.html self-contained doc template with the FX animation framework
references/ authoring guides the agent reads before writing pages
writing-guide.md skeleton catalog (review / explainer / tutorial / comparison /
diagnosis), badge vocabulary, cross-link convention, self-check table
html-authoring.md FX framework usage + 4 copy-paste demo recipes + publish checklist
scripts/smoke.mjs standalone smoke test for lib/server.js
The doc template, the FX framework, and both guides are ported from the
design-preview agent skill; the preview server is a Node port of its
doc_server.py with the same lifecycle rules (unpublish → 410, delete →
trash, etc.).
doc_present(action="new") copies assets/template.html and fills two
placeholders — __DOC_TITLE__ (HTML-escaped) and __DOC_DATE__ (local
YYYY-MM-DD). It also supports an optional __DOC_AUTHOR__ slot: it is
blanked, and the now-empty 作者: span plus its trailing separator are dropped
so the meta line never renders a dangling 作者: ·. No __X__ placeholder
ever reaches a rendered page.
Two deliberate properties of the template, both learned from how pages were actually written:
A → B → C demo, every block marked
「待改 / 示例」. The real section-shape guidance lives in
references/writing-guide.md: the guides are what agents actually read
(18/18 publishing sessions), while the template file itself was read once in
18 sessions.TEMPLATE-NOT-EDITED marker so an unedited page
is recognizable; removing it (which the header comment tells the writer to
do) is the signal that the page has real content.The CSS and the FX framework are the intentionally stable part: they are the design system copied verbatim into every published page.
This package is a profile bundle: package.json declares
dsh.bundle.patch, and cordis.patch.yml inserts the host row. The row
declares inject: ["tools", "systemPrompt", "commands", "webServer"], so it
needs the web profile (the webServer service only exists there). One
command installs it — it links the package, registers the bundle and enables
the row — and the change applies immediately through HMR:
plugin_manager action=install_bundle target=E:\dsh\dsh-plugin-doc-present
Do not write the profile's package.json or cordis.patch.yml by hand, and do
not copy or Junction the package into $DSH_HOME\profiles\node_modules.
Why the old copy/Junction method broke on Desktop 0.2.0: a package placed or linked in
$DSH_HOME\profiles\node_modulesresolves its@deepseek-ai/*peers against that same shared directory, which the Desktop module resolver treats as an obsolete fallback and rejects.install_bundlelinks the package under the profile instead, so peers resolve from the app's own install.
Every session gains the doc_present tool, the /doc-present command, the
prompt section, the header button, the panel, and the tool card.
include:doc-present reports enabled: true, fiberPhase: "active"
(plugin_manager action=list_plugins), then📄 方案预览 button appears in the session
header (top-right actions row).Published documents live in the doc root on disk, not in the plugin package, so reinstalling the bundle leaves every existing document in place.
doc_present — one tool for the whole lifecycle:
| action | What it does |
|---|---|
new | Create <root>/<slug>/index.html from the template (needs slug, optional title), ensure the LAN server, return the file path and all URLs. The agent then writes the content with its normal write/edit tools. |
status | Server state, root, port, doc counts, URLs. |
ensure | Start (or reuse/adopt) the LAN server; prints share URLs. |
list | List published docs with update times (all: true includes withdrawn, query: "..." filters by slug/title). |
unpublish | Take a doc offline (visitors see a 410 page); files kept, restorable. |
republish | Re-publish a withdrawn doc. |
delete | Move a doc to the trash (hard: true deletes permanently). |
trash | List the trash (empty: true empties it). |
restore | Move a trash item back to the doc root (needs name from the trash list). |
Authoring rules the agent follows (enforced by the prompt section): a doc is
one self-contained HTML file — inline CSS/JS, no CDN / web fonts /
external images (LAN readers may not reach the public internet), demos
paused by default with a static caption each, semantic colors (blue = active,
green = done, yellow = attention, red = risk, purple = self-call). The two
guides in references/ teach the FX framework and the writing structure; the
prompt section points the agent at their absolute paths.
📄 方案预览 button (session header, top right) — toggle the preview
drawer: doc chips on top, live preview below; 浏览器打开 / 复制链接 /
↔ 全宽 / ⟳ / ✕ in the drawer header; Esc closes.撤回 /
重新发布 and 删除 (soft delete into the trash, confirmed first); the
回收站 section restores items individually or empties the trash. These
actions call the loopback-only POST /doc-present/__api__/manage
endpoint, so LAN visitors keep read-only access.doc_present result renders a
card with 在面板中打开 (opens the drawer straight at that doc),
浏览器打开, and 复制内网链接./doc-present status|start|stop|list — the service as a command.
(/doc-present json is the machine-readable state the panel uses.)/doc-present/... on the dsh web server (e.g.
http://127.0.0.1:3080/doc-present/) serves the doc root directly from
disk. It is always on while the plugin is mounted and powers the in-GUI
panel. Only people who can reach your dsh web server can see it.0.0.0.0:8899) exists for sharing:
it is what colleagues open. It starts lazily on the first
new/ensure/start, stops on /doc-present stop, and is closed when
the plugin unloads (docs persist on disk). If the configured port is taken
by a foreign process it scans upward (up to +20) and persists the chosen
port back to <root>/.server/config.json; if it finds a healthy
doc-present instance already on the port, it adopts it instead of starting
a second one.DOC_PRESENT_ROOT env var, default ~/.dsh/doc-present
(docs + .server/ metadata: config.json, state.json, trash/).DOC_PRESENT_PORT env var > <root>/.server/config.json > 8899.assets/ and references/ next to lib/.lib/server.js is pure Node and covered by a standalone smoke test (new →
serve → unpublish/410 → republish → delete/trash → port persistence):
node scripts/smoke.mjs
Client-half edits hot-reload only while a watcher rebuilds plugin bundles
(pnpm run dev:web from the dsh checkout); otherwise refresh the page after
copying the package into the profile. Host-half changes load when the row
reloads (edit the patch file) — note that webServer.register returns a raw
disposer, and while the plugin captures and disposes its route on unload, a
route leaked by an older build is detected and reused (a warning is logged);
restart the profile for a completely clean slate.
MIT