dsh-quote-annotate
hanshuang2683/dsh-quote-annotate
Select any passage in a DSH conversation to annotate it in place; the quoted text, the turn it came from and your comment are folded into the message on send, so the model can tell exactly what each remark refers to.
설치
dsh plugin --profile web add github:hanshuang2683/dsh-quote-annotateREADME
dsh-quote-annotate
Select any passage in a DeepSeek Harness conversation, annotate it in place, and send the quote + your comment with your next message.
A small, dependency-free Web UI plugin for DeepSeek Harness (DSH 0.2.1-rc.3+). No build step — one hand-written browser module.
What it does
- Select any text in the transcript (your message, an assistant reply, a tool output) → a floating Annotate button appears above the selection.
- Click it → a floating comment box opens next to the selection (quote preview + textarea + Cancel / Save;
⌘/Ctrl+Entersaves,Esccancels). - Save → the quoted passage is highlighted with a numbered badge (
①). Click a badge to edit its comment later. - A strip the same width as the composer appears directly above the composer:
① annotations · attached to your next message— expand it to review, edit, jump back to the source, or delete each annotation. - Send as usual (Enter or the send button). The plugin folds every annotation into the message as a compact block:
my question …
【我的批注】
批注 1|Assistant · turn 3
原文:
the paragraph you selected
批注:your comment
The model therefore receives the exact quoted text, where it came from, and what you think about it — which is the whole point: no more "I meant the thing above".
Install
Requires DeepSeek Harness 0.2.1-rc.3 or newer (Web / Desktop Web UI).
Using the plugin_manager tool (or the Plugins page → Add plugin):
action: install_bundle
target: https://github.com/HansHuang2683/dsh-quote-annotate
or point it at a local checkout directory, or at a packed tarball:
pnpm pack --pack-destination dist
# then: install_bundle, target: <abs path>/dist/dsh-quote-annotate-1.0.0.tgz
After installing, reload the page (in the Desktop app: Ctrl+R, or fully quit and relaunch). Plugin Manager → Plugins shows “Selection Annotations”.
Design notes
- Official seams only.
shell.overlayrenders the selection toolbar, the comment box, the numbered badges and the annotation strip;conversation.input.overlayholds an invisible “input bridge” that exposes the composer'sinputActionsto the plugin. Standard slot propsuseInput/inputActions(setDraft,submit) drive the composer. - Highlighting without touching foreign DOM. Highlights use the CSS Custom Highlight API (
CSS.highlights) overRanges rebuilt from stored text offsets, so no other plugin's DOM is wrapped or mutated. - Send interception is deterministic. On
Enter(capture phase, IME-aware) or a send-button click, the plugin writesbody + annotation blockinto the composer, waits until the new draft is actually published, then callsinputActions.submit()itself. The native submit path never reads a stale draft. - Shared state on
window. HMR can leave the two halves of a bundle from different module generations; the annotation list / bridge live onwindow.__DSH_QUOTE_ANNOTATE_SHARED__so both halves always see the same state. - Light / dark themes. Reads the host
themeservice (getTheme().active.colorScheme), reacts totheme/change, falls back to the luminance of--dsw-alias-bg-base, and renders its own two palettes (--dqa-*). Filled accents deliberately use--dsw-static-deepseek-500, because--dsw-alias-brand-primaryis white in dark mode.
Known limitations
- The composer is not focused automatically after saving an annotation (DSH exposes no “focus the editor and keep the caret” seam); click the composer and start typing.
- Badges and highlights depend on the transcript's
data-chat-flow-key/data-chat-turnattributes. If a future DSH changes them, highlighting degrades gracefully (annotations still listed and still sent) — the send fold only uses text. - A long quote is truncated to 1200 characters in the sent block (the annotation list keeps the whole quote).
- Web / Desktop Web UI only; the TUI is not supported.
- If the annotation strip ever disappears or annotations stop being attached after a plugin update, fully quit and relaunch DSH — a half-mounted bundle after hot reload is a known host quirk, and the strip's 「Insert」 button is a manual fallback that always works.
Repo layout
| File | Purpose |
|---|---|
client.js | Entire feature: selection tracking, floating UI, badges, strip, send interception |
index.js | Inert Host half — exists so DSH mounts the package's dsh.client entry |
cordis.patch.yml | Bundle patch inserting the quote-annotate row |
locale/{zh,en}.json | Plugin Manager title / description |
icon.svg | Plugin icon |
License
MIT © 2026 HansHuang2683