DeepSeek Harness plugin

dsh-client-paste-image

Paste clipboard images as file PATHS only on configured text-only routes: for listed models the paste is intercepted, saved through dsh-drop-caret's session upload route, and the path lands in the

Jump to install

Source facts

Repository
quei4r/dsh-client-paste-image
Latest update
Aug 20, 2026
Category
Memory
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/quei4r/dsh-client-paste-image
Plugin: dsh-client-paste-image
Author: quei4r

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.en.mdSource · read only
README language

dsh-client-paste-image

中文 | English

DeepSeek Harness (DSH) web client plugin: paste an image → it lands on disk as a file path.

The problem it solves

Text-only models (DeepSeek / GLM, etc.) cannot accept pasted images — the composer outright rejects them with "this model does not support vision, please switch to a vision model". This plugin intercepts clipboard image pastes in the capture phase, uploads the raw bytes through dsh-drop-caret's host route POST /api/dsh-drop (stored as a content-addressed file under the session directory), and inserts the resulting file path into the composer. The conversation stays pure text; when the image actually needs to be looked at, the agent hands the path to an image-capable model (e.g. a workflow with a per-agent model override, or any vision tool).

Dependency

  • dsh-drop-caret (provides the upload route and file storage; this plugin is browser-only, its host half is empty)

Behavior

  • Only acts on routes explicitly listed as text-only (config textOnlyRoutes, provider/model glob patterns): pasting an image in a listed model's session → converted to a path; vision-capable and all other models are completely unaffected — the native thumbnail, draft-attachment, and image-admission pipeline runs exactly as before
  • Empty list = intercepts nothing anywhere (fail-safe: equivalent to not being installed)
  • Interception scope: image pastes inside the composer (textarea / contenteditable); plain-text pastes are never touched
  • Files land in <session-cwd>/.dsh-drop/<sessionId>/ (drop-caret's established layout)
  • Insertion form: a filename label in the draft, serialized to the plain path text on send (ships its own trigger-source codec)
  • Alt+paste: bypasses the interception and uses the product's native behavior
  • Feedback: a bottom toast (filename on success, reason on failure)

> v0.3.0 rewired the plumbing (the v0.2.x gate never fired, two root causes): ① static client plugins receive no config at all — the boot manifest carries only id/url/rev/inject and loader.create({name}) passes none, so the host half now bridges textOnlyRoutes from cordis.patch.yml to the browser over GET /plugin-paste-image-config (loopback/Origin trust fence), cached by the client at boot; ② the session id cannot be read off a service property — the conversation slots hand sessionId to the injected component via inject(sessionId) (the same mechanism dsh-drop-caret rides), and an invisible probe component records it for the paste listener. Config-not-yet-arrived / fetch-failure never intercept (fail-safe). Ships a browser-side smoke test test/smoke.mjs (11 cases: gating, globs, boot races, fail-safe paths, Alt bypass, plain text, non-composer).

Example config:

- id: ui-paste-image
  name: dsh-client-paste-image
  config:
    textOnlyRoutes:
      - zai-coding-cn/glm-5.3
      - "opencode-go/deepseek-*"   # glob

Install

cp -r dsh-client-paste-image ~/.dsh/profiles/web/node_modules/

Add to the - insert: list of ~/.dsh/profiles/web/cordis.patch.yml:

    - id: ui-paste-image
      name: dsh-client-paste-image

(The bundled cordis.patch.yml is for dsh plugin add / marketplace installs.)

Restart dsh web to activate: since v0.3.0 the host half registers the GET /plugin-paste-image-config bridge route (static client plugins receive no config through the module pipeline — textOnlyRoutes crosses over via this route), and host routes only register at startup — a page refresh alone is not enough. Requires dsh-drop-caret as a prerequisite (it provides the POST /api/dsh-drop upload route).

Files

FilePurpose
client.jsBrowser half: paste interception + upload + path-reference insertion (reuses the drop-caret mechanism)
index.jsHost half: the GET /plugin-paste-image-config config bridge route (feeds textOnlyRoutes to the browser, loopback/Origin trust fence)

Compatibility: tested against @deepseek-ai/dsh 0.1.0-rc.6.

License

MIT