dshplugin.devDeepSeek Harness Plugins
DSH Annotation plugin logo
DeepSeek Harness Plugin

DSH Annotation

9
Published by omdsh-dev

DSH Web 选中批注插件:选文字→批注→回车随消息发送;气泡隐藏批注块(零闪烁);回复按 Annotation N 逐条对照(可悬浮芯片)。官方 bundle,零核心改动

Developer Toolsdshdsh-plugin

Get this plugin

Review the source, then continue to the publisher.

dsh plugin add @omdsh-dev/dsh-annotation@latest
Get this plugin
Share on X ↗

About this plugin

Source snapshot 8/13/2026

dsh-annotation

English · 简体中文

Selection-annotation plugin for DSH Web: select text → annotate → press Enter to send it along with your message; the model replies to each annotation by number.

license

image image image image

Select any text in an assistant reply to annotate it (the annotation body may be left empty = just mark the passage). Annotations accumulate across messages and turns. An Annotations ×N chip appears next to the input box — hover to view all annotations, remove them one by one. Press Enter and the annotation block goes to the model together with whatever question is in the input box. The annotation block never shows up as text in your own message bubble — only the question plus the chip (content visible on hover; hidden before paint, zero flicker). The model replies with Annotation 1: …Annotation N: …, one per annotation, and every Annotation label in the reply is a hoverable chip showing the annotated passage and your note.

Form: official bundle plugin (dsh.bundle + a dsh.client declaration in package.json, injected into the browser via client-modules; the Node half is an empty implementation). Zero core changes — no DSH files are touched; cordis.patch.yml only inserts its own id once, and the profile patch stays [].

Features

FeatureDescription
Select-to-annotateSelect assistant text → toolbar "Annotate" → write your note (may be empty); dismiss by clicking elsewhere or pressing Esc
Numbered marker + highlightA blue numbered marker + highlight anchored to the passage, viewport-anchored with collision avoidance, never lost when scrolled out of view
Cross-turn collectionAny number of annotations accumulate across messages/turns, numbered from 1
"Annotations ×N" chipSmall chip beside the input box; hover shows every annotation, deletable individually
Enter sends with your messageAnnotation block + the question in the input box are sent to the model together (the model receives the full content)
Hidden in your bubbleThe annotation block is removed from your bubble's DOM the moment you send (before the browser paints), leaving only the question + the chip (hover to view); historical messages self-heal after a refresh
Numbered reply correspondenceA format instruction is injected into the message so the model replies Annotation 1: …Annotation N: … one by one
Reply annotation chipsAnnotation N: in the reply renders as hoverable chips showing the passage + your note

Interaction flow

Select assistant text ──▶ Toolbar "Annotate" ──▶ Write note / save empty ──▶ Blue numbered marker + highlight
        ▲                                                        │
        └────────────── any number, accumulate across turns ◀────┘
                                │
                                ▼
              "Annotations ×N" chip beside the input (hover to view / delete)
                                │
                            Press Enter
                                ▼
    Model receives: annotation block (number + passage + note) + your question
    Your bubble: question only + "Annotations ×N" chip (zero flicker)
    Model reply: Annotation 1: … Annotation 2: … (hoverable chips)

Install (official bundle path · the only one)

# Public GitHub install (works without an npm account)
dsh plugin --profile web add git+https://github.com/omdsh-dev/dsh-annotation.git
# local path install (development / debugging)
cd /path/to/dsh-annotation
dsh plugin --profile web add .
# restart the web service
launchctl kickstart -k "gui/$(id -u)/com.dsh.web"
DoDon't
Only dsh plugin add / only write bundlesNever insert the same id again in the profile/home cordis.patch.yml

Self-check:

dsh --profile web --dump-config | rg "id: dsh-annotation"   # must be exactly 1 line
curl -s -o /dev/null -w '%{http_code}\n' "http://127.0.0.1:3080/plugins/@omdsh-dev/dsh-annotation/client.js"   # 200

Architecture notes

  • Pure browser-side: everything lives in client.js (a hand-written CJS bundle, no build step, served no-cache per request)

  • Message format (the literal protocol block sent to the model):

    我批注了以下 N 处内容…\n\n1. 原文\n   批注:…\n\n请用「Annotation 1:…」…\n\n提问:
    

    The delimiter is 「提问:」(ask:) rather than 「问题:」(question:) — the heading line "回答我的问题:" also contains the latter, and the bubble-hiding surgery would misfire on it.

  • Bubble hiding: user bubbles are plain-text rendered (a single MessageText node, not markdown); a MutationObserver in the microtask phase (before paint) splits at the last \n提问:, cuts the annotation block, and attaches the chip; a 1 s polling fallback plus historical-message repair after refresh

  • Reply chips: after streaming settles (data-streaming removed), each Annotation N: is replaced with a hoverable chip; item data is stored on the most recent user message carrying the annotation tag (tag.__annotationItems) and rebuilt after refresh; snapshot the text nodes collected by the TreeWalker before touching the DOM, then replace one by one — replacing a child mid-walk invalidates the walker pointer and only the first node gets processed

  • IME-safe: the Enter interception carries isComposing / keyCode 229 guards; never hard-edits the composer textarea's DOM; setDraft only assembles the annotation block at the last moment before submit and never clobbers the user's draft

  • No reliance on send-completion event chains: bubble decoration uses MutationObserver + polling (watchInputDraft can be ineffective before the session is loaded at init; it is only a staging entry)

Version history

VersionHighlights
v1.3.xNumbered reply correspondence: format-instruction injection + hoverable Annotation N: chips (TreeWalker snapshot fix)
v1.2.xHidden annotation block in bubble: MutationObserver microtask zero-flicker + polling fallback + historical-message repair
v1.xSelf-contained annotation flow (replaces the v0.9 chip design): capture-Enter assembles the block and sends it with the message
v0.9.xEarly chip design (insertReference + slash codec), superseded by v1.x

Friendly links

  • Linux.do

License

MIT