dsh-plugin-chat-annotations
No description
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 24, 2026
- Updated
- Aug 25, 2026
Introduction
dsh-plugin-chat-annotations
Annotate any text in the DeepSeek Harness chat: select a fragment, attach a comment (or not), and the annotation travels to the agent with your next message — as a structured content part, not as a field decoration.
Version note. Built and verified against DeepSeek Harness
0.1.1-rc.2. The UI it hooks into is a moving target; on newer Harness versions re-verify and update the plugin if something shifted.
Features
- Select & annotate — select text in any message, click Add to chat, and a numbered marker appears above the selection.
- Non-destructive highlights — the transcript is React-owned; the plugin never mutates it. Highlights are painted with the CSS Custom Highlight API, so the annotated text always stays intact (delete an annotation → the text is untouched).
- Comment popup — optional comment per annotation, saved with the marker.
- Annotation pill — a floating counter above the composer (e.g.
◫ 2 annotations); hover it to list every annotation with its excerpt and comment. - Sent with the request — annotations are appended to
session.promptas an extra text content part, so the agent sees them as part of the message. Press Enter with annotations and an empty composer: the plugin sends the annotation block alone — no typed text required. - Auto cleanup — after a successful send the markers, pill, and highlights are cleared, freeing the buffer for the next round.
- Scroll-safe markers — markers hide when their text scrolls out of the chat viewport (or into the composer panel) instead of drifting over the UI.
Install
From the packed tarball
# build the bundle (from this repo)
pnpm install --config.strictDepBuilds=false --config.minimumReleaseAge=0
pnpm build
pnpm pack # produces dsh-lab-dsh-plugin-chat-annotations-0.0.0.tgz
# install into your profile (run from anywhere; profile path is $DSH_HOME/profiles/<name>)
dsh plugin --profile web add file:/absolute/path/to/dsh-lab-dsh-plugin-chat-annotations-0.0.0.tgz --config.strictDepBuilds=false
Then restart your dsh web server (or just refresh the browser tab — client
bundles are re-read on page load).
From GitHub
dsh plugin --profile web add github:ynnmuraii/dsh-plugin-chat-annotations
Verify it loaded
Open the web UI. The annotation pill (◫ 0 annotations) appears above the
composer once a session is open. If it does not, check the boot page
(HARNESS / Failed to load plugins) and the server logs.
Usage
- Open a session and select a word / sentence in any message.
- Click Add to chat — a numbered blue marker appears over the text.
- (Optional) type a comment in the popup and click Save; or close it with Cancel to keep a marker-only annotation.
- To edit or delete: click the marker → popup → Save / trash icon.
- Send your message. The annotation context is appended to the request automatically. If the composer is empty, just press Enter — the annotation block is sent on its own.
- After the send, annotations clear automatically.
How annotations reach the agent
The plugin intercepts session.prompt traffic and appends an extra text content
part to the message:
content: [
{ type: "text", text: "your message..." },
{ type: "text", text: "[User annotations]\n1. Selected text: «excerpt» — Comment: ..." }
]
Entering text is never required: with pending annotations and an empty
composer, Enter sends the annotation block as the sole content.
Development
pnpm install --config.strictDepBuilds=false --config.minimumReleaseAge=0
pnpm typecheck
pnpm test # vitest + jsdom (6 tests: lifecycle, selection, renumbering, clip)
pnpm build # tsc ESM host + CJS client wrapped for __ModuleLoader__.load
src/index.ts— host half (Cordis plugin entry,greettool).src/client.ts— browser half: toolbar, markers, pill, popup, wire interception.tests/index.spec.ts— jsdom behavior tests.
Layout
src/
index.ts host entry (name / inject / apply)
client.ts browser half (registered via __ModuleLoader__.load)
tests/ vitest + jsdom
scripts/
build-client.mjs wraps the CJS client emit into the module-loader contract
pack-smoke.mjs installs the tarball and executes the built entry
Compatibility
Targets: next (@deepseek-ai/dsh 0.1.1-rc.2, cordis 4.0.1).
Verified via pnpm lab verify chat-annotations --target next (inspect, install,
typecheck, test, build, pack, pack-smoke, composed profile).