Writing bridge to the open-source QingAgent client: the agent drafts and revises documents through qing_ prefixed host tools, typeset on a rice-paper panel with mermaid, drawio, tables and KaTeX; edits stage as reviewable diffs and land only on commit, and it requires the QingAgent desktop app on the same machine.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-qingagent
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:void2anything/dsh-qingagent
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
dsh-qingagent
QingAgent inside DeepSeek Harness
A plugin built to the DSH spec: one command to install or remove, and you can write and review documents with QingAgent right inside DSH.
QingAgent repo · qingagent.com · Feature board · 中文
What is this
DeepSeek Harness (DSH) is DeepSeek's open-source "everything is a plugin" agent framework. Install dsh-qingagent and DSH gains a pen:
Describe what you want in the conversation, and the agent drafts, edits and submits reviews through the QingAgent engine. A paper panel grows on the right — rendering from the same source as the QingAgent desktop app: serif type, warm paper, square corners, with formulas, Mermaid, draw.io, tables, footnotes and a seal-stamped colophon.
The chat keeps a summary; the manuscript is the real thing.
What you can do
- Draft from one sentence: the agent writes the finished piece into the paper panel; while the page is still empty you get QingAgent's own "qing character diffusion" loading animation;
- Per-change verdicts: every AI edit is a candidate — walk through them on the page, accept or reject, commit to land. When the change ratio is high it switches to a full-document old/new comparison;
- Annotation carousel: review annotations sit in place on the page and can be flipped through one by one;
- Selection chips: select text on the page and it becomes a "selection" chip in the input box — multiple chips supported, hover for the full quote, and sent messages render them as chips too;
- Review and export live on the page: export to PDF / Word / HTML / Markdown / TXT and download directly;
- Several drafts per session:
qing_list_docs/qing_focus_docswitch the preview on the right; - "Open in QingAgent": a deep link launches the desktop client so you can keep editing — same local library.
In action: writing a piece with diagrams, tables and formulas inside DSH
| Chat on the left, manuscript on the right — state the requirement once and the agent writes through the QingAgent engine while the paper panel fills in; Mermaid diagrams carry "visual edit / edit Mermaid" buttons and drawio drawings open on double-click | Full typesetting — tables, inline and block math (KaTeX), task lists and code blocks, rendered exactly as in the QingAgent desktop app |
| Per-change verdicts — the header shows "reviewing · N changes", additions and deletions are marked in the text, and the bottom bar offers previous / next / commit / discard all | Three-state onboarding — not installed, installed but not running, or handshake failed, each with the right guidance; once QingAgent is up the plugin recovers without restarting DSH |
Relationship with the QingAgent repo
This plugin is the DSH frontend of QingAgent, not a standalone product.
Because of the plugin's own complexity — the paper rendering is deeply coupled with the manuscript engine, and documents and versions live in a local database — the QingAgent desktop client must be installed first for the plugin to work. The client hosts the engine and the local library; the plugin wires it into DSH's conversation and UI.
That coupling buys you something: a draft written in DSH can be opened and edited in the QingAgent client, and vice versa — one local library, not two copies.
Install (three steps)
① Start DeepSeek Harness (Node.js 20+)
npx @deepseek-ai/dsh web
② Install the QingAgent plugin
npx @deepseek-ai/dsh plugin --profile web add dsh-qingagent@latest
Restart dsh web afterwards.
③ Download and launch QingAgent once
Get it from qingagent.com or QingAgent Releases. Launching it once starts the engine and writes credentials to ~/.qingagent/instance.json; the plugin connects automatically.
If QingAgent is missing or not running, the panel shows an onboarding card: not installed → download instructions; installed but not running → a one-click "Launch QingAgent"; handshake failed → the specific reason (a corrupted
instance.json, for example). Once QingAgent is up the plugin recovers on its own — no need to restart DSH.
Requirements: DSH 0.1.0-rc.6 as the baseline (peer dependency ^0.1.0-rc.6), with a profile that already composes the storage hub, storage-domain and a KV backend (usually @deepseek-ai/dsh-storage-json).
Supported setups
Officially supported: dsh running on Windows with the Windows QingAgent desktop client, same machine and same user.
The implementation also includes macOS client detection (mdfind with an Applications-directory fallback), but it has not been fully validated — issues welcome.
WSL and cross-OS setups are not supported: the plugin reads ~/.qingagent/instance.json from the current system's home directory, so dsh in WSL cannot see a client installed on Windows and cannot reach the engine.
Capabilities
Host tools (callable by the agent)
| Tool | Parameters | Purpose |
|---|---|---|
qing_write_draft |
qingml required; title? requirements? docRef? |
Directly submit the complete QingML authored by the main model. Length requirements only produce a status and gap; the tool never rewrites internally. Without docRef it creates a new draft; with a docRef bound to this session it rewrites the whole piece (requires explicit user authorisation) |
qing_edit_draft |
docRef?; ops[] required |
Atomically submit a batch of structured local edits; refused while a review is in progress |
qing_read_draft |
docRef?; mode defaults to outline |
Tiered reads: outline / full / base (committed baseline) / lines (numbered Markdown) / blocks (block ids) |
qing_review_commit |
docRef?; action: accept_all | reject_all |
Accept or reject the pending review wholesale; hard-limited to one call per turn |
qing_list_docs |
scope: session | library |
List drafts bound to this session; library lists recent documents from the whole QingAgent library (max 50) |
qing_focus_doc |
docRef required |
Switch the paper panel; unbound documents can be adopted by engine id or an exact unique title |
The eight qing_edit_draft operations:
kind |
Semantics |
|---|---|
strReplace |
old → new, optionally the nth match |
markText |
Add / remove inline marks on matches: bold, italic, strike, underline, code, highlight(color), textColor(color), link(href,title?); supports all, isRegex, withinRef |
insertAfterLine |
Insert after line N of the committed Markdown |
insertAfterBlock |
Insert a block after a top-level block, or a sibling item after a list item |
appendSection |
Append a section |
deleteBlock |
Delete a whole top-level block |
deleteListItem |
Delete a list / task item; the engine cleans up the parent list after the last one |
setTitle |
Change the metadata title, leaving the body untouched |
Request-level
opIdidempotency applies only todeleteBlock,deleteListItemandinsertAfterBlock; every proposal also carries a randomclientMutationId.
The paper panel (client)
QingAgent's web editor is compiled straight into the plugin from the vendor/qingagent submodule, so the look matches the desktop app:
- Per-change verdicts:
DocumentSnapshotViewtakes the patch set; the PatchNav at the bottom handles previous/next, reject-all and settlement. After settlement a structured review-result message flows back only when something was rejected; - Whole-document review: a high change ratio switches to old/new navigation with "apply new" / "revert to old";
- Annotation carousel: external annotations become the product's
AnnotationGroup, decorated into ProseMirror and rendered with QingAgent's native carousel; annotations hide themselves while body patches are under review; - Selection chips: the selected text plus block coordinates go through the bridge and become an input-box reference — multiple, de-duplicated, with full quotes on hover;
- Diagrams and export: double-click a draw.io block to open the offline editor and write back; export supports PDF / DOCX / HTML / Markdown / TXT;
- Deep link:
qingjian://open?engineSessionId=<id>launches the desktop client.
Attribution: every external write from this plugin is tagged x-qa-client: deepseek and shows up as a "DeepSeek Harness" source inside QingAgent.
Connection & self-healing
- Instance discovery: reads
~/.qingagent/instance.jsonfor the current user, requiresschemaVersion=2, and validatesport/pid/version/attachProtocolVersion/token/startedAt; - Port authority: when an instance exists the configured
engineUrlport is ignored and the plugin connects tohttp://127.0.0.1:<instance.port>(the desktop port defaults to 21823 and falls back to a random one when taken); - Handshake: checks the attach protocol and process liveness, then calls health with a Bearer token; on a 401 it re-reads the instance file and token once;
- Four states:
online/offline/starting/handshake-failed, each with a specific reason; - Backoff: retry intervals of 5s → 10s → 20s → 30s, then holding at 30s; back to a 5s health cadence once online;
- Client detection: on Windows, the HKCU protocol registration plus HKCU/HKLM uninstall entries (including the
/reg:64view); on macOS,mdfindby bundle id with/Applications/青简.appand the user Applications directory as fallbacks. Detection results are cached for 30 seconds. The launch endpoint only accepts paths resolved andstat-ed by the detector — never a path submitted by the browser.
With
autoLaunchandengineCommandconfigured, the wait budget for the engine to come up is 20 seconds.
Configuration
| Field | Default | Notes |
|---|---|---|
engineUrl |
http://127.0.0.1:8080 |
Fallback only — used when no instance.json can be read; a live instance's port wins |
engineCommand / engineCwd |
unset | Optional launch command and working directory, executed only with autoLaunch |
autoLaunch |
false |
Starts the engine detached when offline; removing the plugin never kills your engine |
workspaceProjection |
true |
Reserved field — no runtime effect today |
Security boundaries
- The token never reaches the browser:
instance.jsonand its token are read only by the Node host, which attaches the Bearer header to health checks, external API calls and export requests. The bridge payload sent to the browser carries engine status, bindings, documents and selections — no token. - The bridge is loopback-only:
/qingagent-bridge/*and/drawioreject non-loopback addresses before any business logic (IPv4, IPv6 and IPv4-mapped loopback accepted). - Session isolation: document reads/writes, assets, exports and reviews are all checked against the
dshSessionId + engineSessionIdbinding.focuswithadopt:trueis the explicit adoption exception, which probes the engine document before joining it to the session. - Style isolation: dynamically imported vendor CSS is wrapped in
@scope, while the mechanically extractedqingdoc.cssis rewritten with a[data-qingagent-doc-panel]selector prefix — neither leaks into the host UI. - QingML rendering: production rendering goes through QingAgent's
qingmlParsewith an explicit tag allowlist, allowlists for links and images, and a final Zod schema check before anything enters ProseMirror;scriptandstyleare dropped. - draw.io assets: GET/HEAD only, directory traversal blocked, CSP and
SAMEORIGINon HTML; iframe messages validate bothevent.sourceand a same-origin origin.
Binding data lives in the dsh_qingagent v1 domain of @deepseek-ai/dsh-storage-domain.
Developing from source
git clone --recursive https://github.com/void2anything/dsh-qingagent.git
cd dsh-qingagent
npm install
npm run check # CSS pinning check + typecheck + tests + build
# POSIX shell
npx @deepseek-ai/dsh plugin --profile web add link:$(pwd)
# Windows PowerShell
npx @deepseek-ai/dsh plugin --profile web add link:${PWD}
Forgot
--recursive? Rungit submodule update --init. The build scripts use POSIX tools (rm -rfand friends), so on Windows run development builds in Git Bash or WSL.
The dsh.bundle.patch entry in package.json merges the in-repo cordis.patch.yml; do not keep a hand-written mount alongside the bundle mount or the plugin registers twice.
Build-time dependency: the vendor/qingagent submodule
The paper rendering reuses QingAgent's apps/web sources and CSS, read at build time from QING_ROOT:
- default
vendor/qingagent(a submodule pinned to a verified commit); QING_ROOT=/path/to/qingagentoverrides it (point it at your own QingAgent worktree during development);- the offline draw.io runtime is published from there too, with
QINGAGENT_DRAWIO_ROOTas a separate override.
CSS is extracted mechanically by "file + line range" (scripts/extract-qingdoc-css.mjs). npm run check:qingdoc-css does a byte-level comparison and is wired into check and prepack: run it right after upgrading the submodule — drifting line numbers cut the extraction in the wrong place and produce a broken build. A red check means do not publish; realign the pinned ranges, then run the full check.
Tests
npm run check # everything: CSS pinning + typecheck + vitest + build
npm test # unit tests only
Contract tests lock down: the 800px page width, serif type, square corners and warm palette applying only to the panel root; CSS extraction matching the pinned ranges; bridge loopback and session isolation; the QingML XSS allowlist; review-state interception and 401 token re-reads.
Community
Scan to join the WeChat user group — report problems, request features, follow updates:
Contact
- Usage questions and bugs: GitHub Issues
- Feature requests and upvotes: Feature board · DSH plugin — the most requested ones get built first
- Issues with QingAgent itself: QingAgent Issues | Feature board · desktop client
License
Apache-2.0 for this repository. The vendor/qingagent submodule is QingAgent, MIT.
Links
More in this category
tt-a1i/archify#integrations/deepseek-harness★ 81709
Generate validated, self-contained interactive architecture, workflow, sequence, data-flow, and lifecycle diagrams from repositories or system descriptions.
dream-num/dsh-univer-office★ 494
Give DeepSeek Harness a real office environment. Univer Office Plugin brings spreadsheets, docs, slides, canvases, relational tables, and more into one runtime — with connected data, validation, versioned changes, and isolated worktrees for multi-agent collaboration.
PerryLink/dsh-industry-research★ 214
Deterministic industry research reports for DeepSeek Harness — company and industry research flows produce structured, verifiable reports from staged evidence.
PolinniZhong/dsh-knit★ 53
Lists the Markdown documents, images and video that already exist anywhere in the session workspace in the DSH sidebar, ranked by relevance to the current conversation: recent messages are matched locally against document title, summary and body with IDF weighting, with no model calls and no network. Because the list is scanned from the workspace instead of remembered, restarting DSH or starting a new session does not empty it. Images and video preview in place, with relative-path images resolved and video streamed over HTTP Range. A references bar under the preview header shows which documents cite the one being previewed and which it cites, with one click to jump between them. The same ranking is exposed to the agent as a knit_docs tool, which returns the most relevant documents along with the passage that matched in each, where one is found.
HuanLinOTO/dsh-plugin-mineru★ 46
Expose MineRU document parsing tools to the model.
kw78/dsh-office-tools★ 28
Workspace-safe Office tools for agents: create/read Word, create/read/update Excel, and create/read PowerPoint decks with PNG/JPG/GIF image placement.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.