DSH HUB
HomePlugin StoreRankingsPublish Guide
Plugin source
Back to catalog

beijingwahw /

dsh-conv-search

Verified

dsh-conv-search(对话内文本搜索)— in-conversation text search plugin for DeepSeek Harness (Ctrl+F, match case, whole word, streaming-aware)

★ 3 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@eff0ae1b

dsh-conv-search(对话内文本搜索)

License: MIT dsh-plugin DeepSeek Harness

English | 中文

In-conversation text search for the DeepSeek Harness web UI — the Ctrl+F you already know, scoped to the current chat session. A floating search bar highlights every match in the rendered transcript and walks between them, without touching a single line of harness core code.

Problems it solves

  • Long sessions are unsearchable: the browser's native find searches the whole page (sidebar, composer, chrome) and cannot follow a conversation that keeps streaming. This plugin searches only the active conversation scrollport and stays in sync while the model is still writing.
  • No way to jump between occurrences: native find gives no "n / total" navigation. This plugin provides Enter / Shift+Enter and prev/next buttons with wrap-around, centering each match in view.
  • Highlighting must not fight React: the transcript DOM is React-owned and re-renders continuously during streaming. Instead of wrapping matches in <mark> nodes (which would mutate React-managed text and break reconciliation), the plugin paints ranges through the CSS Custom Highlight API — an overlay that survives every re-render and needs zero DOM cleanup.

Features

  • Ctrl/Cmd+F opens the floating search bar (only when a conversation is rendered — otherwise the browser's native find stays untouched); Esc closes it from anywhere, including while the input holds focus.
  • Matching across every rendered chat node: user messages, assistant text, tool cards, and paged-in history. Two toggles mirror the browser/IDE find bar: Aa (match case) and ab (whole word) — essential for hunting error codes, function names, and API identifiers.
  • Live n / total counter with Enter (next) / Shift+Enter (previous) navigation and wrap-around; F3 / Ctrl+G work too, the browser/IDE find-bar convention.
  • Query history: ArrowUp / ArrowDown cycle through your recent queries (most recent first, deduplicated), restoring the draft you were typing when you walk back past the newest entry.
  • Zero-result queries answer back: the count turns red, the bar border follows, and the bar gives a one-shot shake (honoring prefers-reduced-motion). Repeated Enter on no results re-shakes instead of staying silent.
  • The active match is painted in a stronger color and scrolled into view automatically.
  • The header action button mirrors the open state (aria-pressed), so you always know whether search is active.
  • Streaming-aware: a MutationObserver re-runs the search (debounced) while output streams or older pages load, without stealing your scroll position. The active match is anchored by identity (text node + offset), so a paged-in older page or a streamed delta never jumps your cursor to a different occurrence.
  • Scope discipline: the composer seat and the plugin's own bar are excluded, so your draft text never produces phantom hits.
  • Follows the harness theme through --dsw-alias-* design tokens; Chinese/English UI picked from the document language.
  • Session header action button (search icon) registered through the conversation.session.header.actions slot — the additive, unload-safe composition route.

Install

Requires Node.js ≥ 22 and pnpm (npm install -g pnpm) — dsh plugin add installs the bundle into the profile with pnpm.

dsh plugin --profile web add https://github.com/beijingwahw/dsh-conv-search/archive/refs/tags/v0.1.0.tar.gz
dsh web   # restart the server to pick the plugin up

Tag URLs are immutable, so the tarball checksum never changes. (Branch URLs like refs/heads/main move with every push and trip pnpm's ERR_PNPM_TARBALL_INTEGRITY once a lockfile has recorded an older checksum.)

The package declares dsh.bundle.patch (mounts the host registration row) and dsh.client (serves the browser half at /plugins/<id>/client.js). lib/ is committed, so the GitHub tarball installs without a build step.

Verify the mount:

dsh --profile web --dump-config | grep conv-search

Usage

Gesture Action
Ctrl/Cmd+F (or the header search icon) Open the search bar
Type Search as you type (120 ms debounce)
Enter / F3 / Ctrl/Cmd+G Next match (wraps)
Shift+Enter / Shift+F3 / Ctrl/Cmd+Shift+G Previous match (wraps)
ArrowUp / ArrowDown Browse previous queries
Aa / ab buttons Match case / whole word
Esc Close and clear all highlights

How it works

  • src/client/engine.ts — pure DOM helpers: text-node walk, case-insensitive range matching, CSS.highlights paint (dsh-conv-search for all matches, dsh-conv-search-active for the focused one), and scroll-into-view. No cordis, no React — unit-testable against jsdom.
  • src/client/controller.ts — the floating bar (plain DOM, so it never couples to the shell's React version), keyboard capture, debounced search passes, and the transcript MutationObserver that keeps highlights honest during streaming.
  • src/client/index.ts — the cordis client half: installs the controller through ctx.effect and registers the header action button via ctx.slots.inject('conversation.session.header.actions', ...), so the button appears and disappears with the slot declaration and plugin fiber.
  • src/index.ts — the host half is an empty registration shell; all behavior is browser-side.

Model Experience

None. The plugin only reads the rendered transcript in the browser; it touches no prompt, message, schema, stream, tool, or provider request.

Development

npm install
npm run typecheck   # strict TS, no emit
npm run build       # tsdown: host ESM + browser client bundle
npm test            # vitest (jsdom): engine, controller, i18n

The client bundle enforces the harness purity rule: platform modules (react, cordis, the seeded client packages) stay externals, and any other @deepseek-ai/* value import fails the build.

Known Limitations and Deferred Work

  • Matching is plain-text only — no regex, no diacritic folding, no cross-node phrase matching (a phrase split across styled spans will not match).
  • Requires a browser with the CSS Custom Highlight API (Chrome/Edge 105+, Safari 17.2+, Firefox 132+). On unsupported browsers the bar still counts matches but paints no highlight.
  • The bar position is fixed (top: 64px; right: 24px); it is not draggable yet.
  • Search scope is the active conversation column only — sidebar session titles and settings pages are intentionally out of scope.

Troubleshooting

  • 'pnpm' is not recognized during dsh plugin add → install pnpm first: npm install -g pnpm.
  • EADDRINUSE ... :3080 on dsh web → a previous dsh web is still bound to the port. Stop it (Ctrl+C in its terminal; on Windows: Get-NetTCPConnection -LocalPort 3080 | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }), or start on another port with dsh web --port 3081.

License

MIT

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

APIPublish GuideAbout
—/ 5

No ratings yet

Verified DSH bundle

Commit eff0ae1bf80a

Community comments

No comments yet. Be the first to write one.