dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
dsh-web-enhance is a browser plugin for the DSH (DeepSeek Harness) web UI that adds small quality-of-life features. It currently ships:

💡 Thinking chain default-expand — the third floating button (lightbulb icon) in the bottom-right corner, below the navigation pair:
⬆ ← back to the start of the current turn
⬇ ← to the end of the current turn
💡 ← thinking chain default-expand toggle (highlighted when on)
⬆️⬇️ Turn-by-turn navigation — a floating button pair in the bottom-right corner of the conversation, right above the built-in "scroll to bottom" button:
⬆ ← back to the start of the current turn
⬇ ← to the end of the current turn
dsh plugin --profile web add @yangzhe1991/dsh-web-enhance
Restart the Web GUI (Ctrl+C the dsh web process and run it again) and refresh the browser tab. (dsh plugin runs pnpm add and auto-appends the bundle to dsh.profile.bundles.)
For local development, install from a path instead — the link: spec keeps a live symlink so edits take effect after a rebuild + restart:
dsh plugin --profile web add link:/path/to/@yangzhe1991/dsh-web-enhance
The plugin subscribes to the conversation snapshot through the standard useSession hook and reads the turn model (chat.timeline.turnOrder + chat.locations.getTurn(turn) from dsh-client-runtime). A turn's "final result" is its last node that contains non-empty text and whose blocks end with a text block (transition sentences look like [reasoning, text, tool…] — the agent is still working — while a final result looks like [reasoning, text] or [text]); turns without a closing summary fall back to their last text-bearing node.
Scrolling reuses the same DOM primitives as the built-in UI: rows are located via the official data-chat-anchor-key marker inside the [data-chat-flow] list, the scrollport is [data-conversation-scroll], and the start anchor skips the leading thinking block (DisclosureRow, carrying aria-expanded) so the viewport lands exactly on the reply text. "Already pinned to the turn start/end" is decided by scroll distance (< 60px) to the anchor, not by which row happens to be at the viewport edge.
The thinking-chain default-expand works on the official reasoning rows ([data-variant="think"] with a [data-disclosure-row][aria-expanded="false"] row inside). Because the full reasoning text is only mounted when a row is open, the plugin clicks each collapsed row to flip the built-in component's own React state. A MutationObserver on document.body watches for newly mounted rows (streaming output, new turns) and expands them as they appear; a one-time sweep covers rows that are already rendered. Only added subtrees are scanned, so a row you collapse by hand is left alone.
npm install
npm run build # lib/index.js (node half) + lib/client.js (browser half)
npx tsc --noEmit # type-check
dsh plugin --profile web remove @yangzhe1991/dsh-web-enhance
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。