Common Word Box — DeepSeek Harness Client Plugin
English | 中文

A web client plugin for DeepSeek Harness (dsh web): a "词/W" button sits to the right of the message input; clicking it opens a persistent slide-up panel where you manage your frequently used words/phrases and insert them into the input with one click.

Words live in two buckets: Global (shared across all workspaces) and Current project (isolated per workspace directory).
Features
- 🖱️ Click the "词/W" button → slide-up panel with an entrance animation, stays open (click again / click outside / press Esc to close)
- 🔀 Three display scopes: All / Global / Current (switch control at the far right of the "+ Add" row)
- ⏎ Click a word → appended to the input (focus preserved, one undo step, panel stays open for consecutive inserts)
- 🌐 Bilingual zh/en (follows the DSH UI language)
Install
Prerequisites: DeepSeek Harness dsh web + pnpm (the dsh plugin command forwards to pnpm, so pnpm must be on PATH).
This is a standard DSH bundle plugin (dsh.bundle.patch declaration with the plugin-row patch shipped inside the package), so both install and uninstall are a single command:
Install
# Prerequisite: install the official CLI (skip if already installed)
npm install -g @deepseek-ai/dsh
# Install the plugin
# Option 1: from npm (recommended, published on npm)
dsh plugin --profile web add dsh-wordbox
# Option 2: from GitHub (the repo root is the plugin package; no build step, works directly)
dsh plugin --profile web add github:arcmosin/dsh-wordbox
# Option 3: local development (link to this repo)
dsh plugin --profile web add link:D:/path/to/dsh-wordboxAfter installing, restart dsh web and the "词/W" button appears next to the input.
> dsh plugin add installs the package into the profile and automatically mounts it into dsh.profile.bundles thanks to the dsh.bundle declaration; no patch file editing required.
Uninstall
dsh plugin --profile web remove dsh-wordboxThen restart dsh web and the button disappears. Words saved in the browser (localStorage) are not removed on uninstall; to wipe them, delete these keys manually: dsh.common-word-box.words.v1, dsh.common-word-box.words.project.v1, dsh.common-word-box.mode.v1.
> In some cases remove leaves an empty directory/link at profiles\web\node_modules\dsh-wordbox; deleting it by hand is harmless.
Usage
1. Click the "词/W" button next to the input; the panel slides up and stays open; 2. Switch between All / Global / Current at the bottom-right; 3. Click a word to append it to the input (several in a row); hover a row to reveal the × delete button; 4. In "Current" mode, hovering a row reveals an "Add to global" button that copies the word into the global bucket in one click (the current project's word list is untouched; the button is hidden once the word is already global); 5. Hovering a long word slowly flows through the full text at a fixed speed.
Storage
| Data | localStorage key |
|---|---|
| Global words | dsh.common-word-box.words.v1 (string[]) |
| Project words | dsh.common-word-box.words.project.v1 ({normalized-dir: string[]}, empty buckets are pruned) |
| Display scope | dsh.common-word-box.mode.v1 (all / global / current) |
Words are stored in the browser (isolated per browser profile) and synced across workspaces and tabs via the storage event.
Development
- Local debug install:
dsh plugin --profile web add link:<absolute-path-to-repo>; no reinstall needed after code changes; - Edits to
lib/client.jsneed no restart: the hostclient-hmrpolls the bundle hash every 500ms and hot-reloads on change (React state resets); a restart is only required after the first install/uninstall or changes tocordis.patch.yml. - The bundle is plain JS in
window.__ModuleLoader__.load({ id, factory })format — no build step, edits take effect immediately. - Long-word flow speed constant:
FLOW_SPEEDinlib/client.js(default 60 px/s).
Architecture
| Part | File | Description |
|---|---|---|
| bundle patch | cordis.patch.yml | The plugin row declared via dsh.bundle.patch; auto-mounted into the profile by dsh plugin add |
| node half | lib/index.js | Empty apply so the loader entry activates on the host |
| browser half | lib/client.js | Client bundle: conversation.input.right slot registration + all interaction logic |
| manifest | package.json | dsh.bundle + dsh.client (platform: "web" + inject) + exports["./client"] |
- Mount point: the
conversation.input.rightslot (declared by@deepseek-ai/dsh-client-ui-conversation, list kind, session scope), rendered in the composer card's trailing area. - Writing to the input: standard kit
inputActions.setDraft(text); reading the draft withuseInput((s) => s.draft). - Waiting for the slot declaration:
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({...}, Component)). - Reference shape:
@deepseek-ai/dsh-client-ui-model-selection(official pure-UI client plugin).
License
[MIT](LICENSE)