DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Run In Terminal — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
R

dsh-run-in-terminal

Run In Terminal

DSH web plugin: a Run button on every chat code block that pastes into an integrated terminal, plus "Attach selection as context" from terminal output.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:DIV7NE/dsh-plugins#1ef9db37dbad68657206500abde058dcdf69d23c
READMECompatibilityVersions

Compatibility and provenance

Run In Terminal is published as dsh-run-in-terminal and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/12/2026

Versions

0.1.0stable
9/12/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/13/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in developer-tools.

Web App@deepseek-ai/dsh-web-appThe dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)Sdk Minimal@deepseek-ai/dsh-sdk-minimalThe standalone minimal SDK profile bundle: JSON-RPC, one DeepSeek adapter, persistent shell, and JSONL sessionsSdk App@deepseek-ai/dsh-sdk-appThe dsh SDK profile bundle: stdio JSON-RPC serving and process lifecycle over dsh-baseSubagent Codex@deepseek-ai/dsh-subagent-codexOne-shot Codex subagent provider over the official app-server protocol

README

dshpluginsdev

DeepSeek Harness (DSH) web plugins, by DIV7NE.

Each plugin is a self-contained package in this repository. Every one of them declares its own bundle patch, so installing a single directory is enough — the DSH CLI appends it to the profile's bundle stack and no profile file is edited by hand.

PluginWhat it does
dsh-suggest-next-prompt/Puts a model-generated next prompt in the chat composer's placeholder. Tab pastes it, ↑/↓ cycle the shortlist, Esc dismisses.
dsh-chrome-agent/Drives your real, already logged-in Chrome through a pinned companion extension, instead of a separate browser profile.
dsh-run-in-terminalA Run button on every chat code block, and an integrated terminal in the right sidebar to run it in.

Installing a plugin

git clone https://github.com/DIV7NE/dshpluginsdev
cd dshpluginsdev/<plugin>
npm install
npm run install:profile      # builds, packs, and installs into the web profile

Then restart the DSH server for that profile — a profile's bundle stack and the browser's client-module graph are both composed at boot, so a new plugin cannot appear in a running server. Once a plugin is in the graph, later changes need only a page reload.

The Chrome extension

dsh-chrome-agent ships two artifacts from one directory, and they are released separately:

  • the DSH plugin (this repository's package, installed like its siblings);
  • the Chrome extension, a plain folder under dsh-chrome-agent/extension/ packed by scripts/pack-webstore.mjs into a root-level zip, which is the artifact the Chrome Web Store uploads. It is built and attached to Releases, not published through the DSH plugin channel.

npm run pack:webstore in that directory regenerates the zip. CI runs it and asserts the zip still contains manifest.json at its root, because the plugin's own tests would not notice a broken packer.

Repository layout

<plugin>/            one self-contained DSH plugin package
  src/               source
  lib/               committed build output (see below)
  cordis.patch.yml   the bundle patch that installs it
  test/              hermetic tests, plus a non-hermetic live probe
  README.md          what it does, how to configure it, its permissions and risks
docs/superpowers/    design, plan, and implementation notes

Why lib/ is committed. A DSH plugin may not run a prepare or postinstall script, so nothing may build it at install time. The build output therefore ships in the repository, unminified. CI fails if it drifts from src/.

Development

cd <plugin>
npm run build        # esbuild
npm run typecheck    # tsc --noEmit
npm test             # node:test — hermetic
npm run install:profile

npm run build && npm run typecheck && npm test is the same gate CI runs.

Release status

Both plugins pass the DSH-Store fixed-source precheck. Submission issues:

PluginIssuePrecheck
dsh-suggest-next-prompt#778passed, 1 warning
dsh-run-in-terminal#779passed, 2 warnings, partial scan

The precheck is a bounded static read of the pinned commit. It is not a security audit, not a runtime verification, and not an automatic listing — the Catalog gate that follows re-pins the source and applies stricter licence, dependency, lifecycle, bundle and runtime-source checks before anything appears in the store.

Two known constraints, stated rather than hidden:

  • scripts/install-profile.mjs in each plugin invokes npm, npm pack and the dsh CLI through child_process so that a rebuild-and-reinstall is one command. Both plugins' prechecks flag it. It is a local development helper: it is not in the files list, so it is never part of a published package, and no runtime code path reaches it. Arguments are fixed strings, not user input.
  • dsh-run-in-terminal's committed browser bundle exceeds the scanner's 256 KiB per-file limit, because it inlines xterm. The store reports the scan surface as incomplete for that reason. The bundle cannot simply be shrunk — inlining is deliberate, since the shell does not seed xterm in its module table, and a plugin may not build at install time.

License

MIT. See LICENSE.


dsh-run-in-terminal

A DeepSeek Harness web plugin that puts a Run button on every code block in the chat and gives you a real terminal to run it in.

A fenced block in a reply grows a Run button next to the Copy button DSH already draws. Clicking it opens an integrated terminal in the right sidebar, pastes the snippet into it, and presses Enter. Right-click inside the terminal for Attach selection as context (plus Copy / Paste / Select all): the selected output is appended to the conversation draft as a fenced block, ready to send.

Install

cd <this directory>
npm install
npm run install:profile          # builds, packs, and installs into the web profile

Then restart the DSH server for that profile (dsh web) and reload the page. A restart is required, not optional: the profile's bundle stack and the browser's client-module graph are both composed at boot, so a new plugin cannot appear in a running server.

npm run install:profile is the whole update loop — run it again after any source change and restart. It takes a profile name as its first argument (node scripts/install-profile.mjs myprofile, default web).

Why a tarball and not a local link

dsh plugin --profile web add <directory> is the usual way to install an out-of-tree plugin, and on this machine it does not work for a plugin that lives on a different drive than the profile: pnpm creates the node_modules junction with the wrong target (<profile>\\D:\\projects\\dshpluginsdev, which resolves to nothing). The launcher then cannot read the package manifest, never sees dsh.bundle.patch, and reports declares no dsh.bundle — installed as a plain dependency, not a profile layer. scripts/install-profile.mjs works around it by installing from an npm tarball, which pnpm materialises as a real directory; the bundle then reconciles correctly (verified: dsh-run-in-terminal is appended to dsh.profile.bundles).

What each half does

FileRole
src/index.tsHost half: one persistent pty per session, served over GET /runterm/pty (WebSocket), behind a browser-trust fence.
src/client/index.tsxRegisters the runterminal right-Sidebar page type and the code-block button pass.
src/client/code-run.tsWatches the transcript for .md-code-block nodes and attaches the Run button.
src/client/terminal-view.tsxThe xterm pane, its socket, and the right-click menu.
src/client/draft.tsAppends a terminal selection to the composer draft through the conversation service.
scripts/build.mjsesbuild: the node bundle, and the browser bundle wrapped in the window.__ModuleLoader__.load boilerplate.

How the Run button reaches the shell

openTab('runterminal', { params: { run } }) acts on the session whose conversation is on screen and deduplicates by kind, so the click either creates the terminal or re-navigates the one already open. The tab body watches navigation.revision, writes the snippet to the pty as {t:'run', code}, and the host turns a snippet into shell input:

  • line endings become CR (a terminal sends Enter as CR) with one final CR to submit, so a backslash-continued command — the shape long commands take in chat code blocks — runs exactly as written;
  • trailing blank lines are dropped, so a snippet that already ends in a newline does not submit an extra empty command.

Framing lives on the host deliberately: the bytes the shell reads have one authority, and that is the part covered by npm test.

The code text itself is read back as textContent of the block's content node. DSH draws line numbers with a CSS counter, never as DOM text, so this is the exact snippet and not a numbered copy of it.

Security

The route spawns processes, so every request passes a browser-trust fence before it can reach one — the same fence the shipped /api gateway applies to its own routes:

  • the Host header must name a loopback authority (a name that merely resolves here from elsewhere is a DNS-rebinding attempt);
  • a request a browser marks Sec-Fetch-Site: cross-site is refused;
  • an Origin, when present, must name the same hostname.

This is a DNS-rebinding / cross-site defense, not authentication. It does not distinguish one loopback page from another: a page served from the same hostname on a different port shares the hostname and passes. If you bind DSH to a non-loopback address, this route is exposed with everything else.

The pty starts in the session's workspace root when the client knows it, and in the server's own working directory otherwise; a requested directory that is not an existing directory is ignored.

Configuration

Add config.shell to the plugin row to choose the shell:

- id: run-in-terminal
  name: 'dsh-run-in-terminal'
  config:
    shell: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe'

The default is pwsh.exe on Windows when it is on PATH (powershell.exe otherwise), and $SHELL — else /bin/bash — on POSIX, started as a login shell.

Known limitations

  • One terminal per conversation session, keyed by session id. Closing the tab ends the process; hiding or switching away from it does not.
  • A multi-line snippet is submitted line by line, so a shell control block (for … do … done, if … { }) run from a chat code block needs its continuation characters — the same as pasting into a terminal that lacks bracketed-paste support.
  • The pane lives in DSH's native right Sidebar under its own kind (runterminal). It does not reuse and does not collide with the terminal kind that other sidebar plugins register.
  • Strings are English-only; the plugin registers no locale namespace.

Development

npm run build          # esbuild: lib/index.js + the wrapped lib/client.js
npm run typecheck      # tsc --noEmit
npm test               # node --test test/host.test.mjs   (hermetic)
npm run install:profile

The hermetic suite covers the byte framing, the transcript bound, shell resolution, and the trust fence.

test/live-probe.mjs is the non-hermetic companion: point it at a running server that has this plugin loaded and it asserts a same-origin handshake is accepted, a Run frame round-trips through a real shell, and a foreign Origin is refused.

node test/live-probe.mjs http://127.0.0.1:3080 probe

Browser bundle details: react and @deepseek-ai/* stay external (the shell seeds them in its frozen module table), while xterm and its fit addon are inlined, so the bundle needs no dsh.client.external entry.