Preface

The core philosophy of DeepSeek Harness (abbreviated as DSH) is “Everything is a plugin”: model adapters, tools, and chat interfaces can all be assembled using plugins. After using the web-based chat interface for a while, you will encounter a very specific problem: the assistant’s reply is very long, and you actually only want to ask questions about two or three specific parts of it, but every time you have to copy the paragraphs into the input box, number them yourself, and then instruct “Please answer item by item”. Once the numbering is messed up, the alignment breaks.

dsh-annotation turns this task into a simple selection operation in the web page: select a piece of text in the assistant’s reply, write an annotation (you can also just mark it without typing anything), and after pressing Enter, the annotation block will be sent to the model along with the current question, and the reply will be aligned item by item as Annotation 1, Annotation 2. This article is organized after checking against the plugin directory page, GitHub repository README, and package.json, explaining what it is, how to install it, and how to use it. The community plugin directory is an independent site and has no official affiliation with DeepSeek / HyperSage. You should still check the source code and license agreement yourself before installing.

What it is

dsh-annotation is an interface enhancement plugin for the DSH Web interface, maintained by the GitHub organization omdsh-dev, with the npm package name @omdsh-dev/dsh-annotation. It is categorized under “Interface Enhancements” on the directory page, and its license is MIT. The version of the repository package.json checked when writing this article is 1.3.16, which requires Node.js >=20, and dsh.client.platform is declared as web.

The problem it solves is the act of “asking questions against the original text and getting replies item by item” in web-based conversations, rather than adding capabilities for TUI or headless profiles. Technically, it follows the DSH official bundle plugin mechanism: dsh.bundle and dsh.client are declared in package.json, and they are injected by client-modules on the browser side; the apply() method on the Node side is an empty implementation, and all real logic is in client.js. The README emphasizes zero core changes — it does not modify the DSH core files, cordis.patch.yml only inserts its own ID once, and the profile patch remains an empty array.

As of 2026-08-17, the GitHub repository has 67 stars (the directory page showed 46 at the time, please refer to the repository page for the latest count). The repository was created on 2026-08-10, and it was added to the directory on 2026-08-15.

Core Features

The following capabilities come from the feature table in the Chinese README of the repository, which is consistent with the introduction on the directory page.

One-click Annotation via Selection

Select any text in the assistant’s reply, the “Annotation” toolbar will appear, write an explanation after clicking it and save. The annotation body can be left blank, which is equivalent to just marking this original text. Clicking on a blank space or pressing Esc will collapse the toolbar.

A bright blue numbered footnote and highlight will be left at the position of the original text. The footnote is anchored within the viewport and avoids collisions; it will not be lost even if it scrolls off the screen.

Cross-turn Collection, Send All at Once with Enter

Annotations can be accumulated across messages and rounds, with numbering starting from 1. A “Annotations ×N” tag will appear next to the input box: hover your mouse over it to view all content, and you can also delete entries one by one.

Just press Enter when you are ready with your question. What is sent to the model is: Annotation block (number + original text + annotation) + the question in the input box. Your own chat bubble will not show the entire annotation text, only the question and the “Annotations ×N” tag, and you can only see the content when you hover over it. The README states: the annotation block is removed from the chat bubble DOM before rendering in the browser, to avoid a flash of the original text. After refreshing, the historical messages will be fixed again.

Reply Aligned by Numbering

During sending, format instructions will be injected into the message, requiring the model to respond item by item as “Annotation 1: …” “Annotation N: …”. After the streaming response ends, these tags in the reply will be rendered into hoverable chips, and hovering will display the corresponding original text and your annotation.

Compatible with Focused Chat

The README states that it is compatible with the focused chat view of dsh-focus-chat. Selection annotations, reply chips, and footnote repositioning work in both focused tabs and the main chat view. This is the compatibility declared by the repository, not a third-party evaluation.

Installation and Activation

The installation command given on the directory page is as follows, run it in the DeepSeek Harness terminal:

dsh plugin add github:omdsh-dev/dsh-annotation

This plugin only declares support for the Web end, and the repository README writes the official bundle installation path as specifying the web profile (the author calls it the “only” path), no npm account is required:

dsh plugin --profile web add git+https://github.com/omdsh-dev/dsh-annotation.git

For local development and debugging, you can run dsh plugin --profile web add . in the cloned directory.

For reproducible installations, the directory page recommends pinning the commit hash. This article checked that the latest commit on main is 0b0ceb6415c5c1204b9f73716e905b392acd729b (2026-08-16), which can be written as:

dsh plugin add github:omdsh-dev/dsh-annotation#0b0ceb6415c5c1204b9f73716e905b392acd729b

Or add #<commit> after the git URL as shown in the README. The commit will change as the repository updates, please double-check GitHub before installing.

The README reminds: only access it via dsh plugin add or by writing bundles; do not do another insert for the same ID in cordis.patch.yml of the profile / home, otherwise duplicate entries will appear in the configuration.

After installation, perform a self-check according to the README (rg refers to ripgrep; the default Web port is subject to the actual local one):

dsh --profile web --dump-config | rg "id: dsh-annotation"   # Must have 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"   # Expected 200

The restart example given in the README is as follows, this is the launchctl syntax for macOS:

launchctl kickstart -k "gui/$(id -u)/com.dsh.web"

For other systems, just restart DSH Web in the way you normally start it on your machine, the repository does not provide separate Linux / Windows commands.

Typical Usage

The interaction process can be reproduced as follows according to the repository README:

  1. Drag and select a piece of text in the assistant’s chat bubble.
  2. Click “Annotation” on the toolbar, write an explanation or leave it blank and save; the original text will show a bright blue number and highlight.
  3. Continue selecting other paragraphs if needed, and the numbers will increment in order.
  4. Check the “Annotations ×N” tag next to the input box, hover over it to verify, and delete unwanted entries.
  5. Write your question in the input box and press Enter to send.
  6. Check your own chat bubble: there should only be the question + tag, no full annotation block.
  7. Wait for the reply to finish, align it according to “Annotation 1” “Annotation 2”; hover over the chips to check the original text.

The protocol block actually received by the model has the following structure (the delimiter marker is “Question: “, not “Problem: “):

I have annotated the following N pieces of content...

1. Original text
   Annotation: ...

Please respond in the format "Annotation 1: ..."...

Question:

The README explains why “Question: ” is not used: the “Answer my question:” in the assistant’s chat bubble title line also contains these words, and if we split by it, the bubble hiding will mistakenly hit this string. This is an implementation detail, you do not need to change it during daily use; if you modify the protocol field yourself, you need to avoid this conflict.

When typing in Chinese, Enter interception has isComposing / keyCode 229 guards to avoid sending the draft before the pinyin is fully typed in. setDraft only assembles the annotation block right before submission, and will not overwrite the draft being typed in the input box.

Applicable Scenarios and Notes

It is suitable for users who are already using the DSH web interface and often need to follow up or correct specific sentences in long replies. Pure terminal TUI and headless profiles are not within the scope of dsh.client.platform declaration. If you use dsh-focus-chat at the same time, the repository declares that the focused view is also available.

Please note the following before using:
- Permissions and Source: The directory page states that the plugin runs with the permissions of the current DSH process, and may execute code during installation. Check the GitHub source code and MIT license before installing; do not install it if you do not trust it. Community directory inclusion does not equal official endorsement by DeepSeek.
- Install Only Once by ID: The content of cordis.patch.yml is to insert id: dsh-annotation and the package name @omdsh-dev/dsh-annotation into the configuration. Repeated inserts will result in multiple lines of the same ID in dump-config, causing the self-check to fail.
- Capability Boundaries: Annotation alignment depends on the model following the injected format instructions. The repository does not promise that any model will output according to “Annotation N” 100%; the reply chips are replaced only after the streaming ends (data-streaming is removed).
- Implementation Location: The Node side has an empty apply() method, do not look for interface logic in lib/index.js. The browser side is handwritten CJS client.js without build steps, read on request and with no-cache.
- Version: The current README marks v1.3.x as “item-by-item reply alignment + hoverable chips”; v1.2.x was bubble hiding; v1.x uses the captured Enter to assemble and send the draft, replacing the insertReference / slash codec scheme from v0.9. Please refer to the repository’s version description for details.

Summary

dsh-annotation turns “asking questions against the assistant’s original text” into a simple selection and annotation operation on the web: select text, add numbers, press Enter to send along with the message, and the reply is aligned by Annotation numbers, with no full annotation block flashing in the chat bubble. It is an MIT open-source bundle plugin maintained by omdsh-dev, following the official DSH plugin mechanism, without modifying core code, but only covering the web end.

Directory page: https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-annotation/

GitHub: https://github.com/omdsh-dev/dsh-annotation