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.

Preview Plugin — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
P

dsh-preview-plugin

Preview Plugin

Live preview tab for DSH — embed any dev server in an iframe with SPA proxy and multi-app monorepo support

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

npx -y @deepseek-ai/dsh plugin --profile web add github:RaulLazaro/dsh-preview-plugin#4c0e42dab69dc18d0ee798f42df9bac6171d8c0d
READMECompatibilityVersions

Compatibility and provenance

Preview Plugin is published as dsh-preview-plugin and currently resolves to version 1.3.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/18/2026

Versions

1.3.0stable
9/18/2026
1.2.1stable
9/18/2026
1.1.0stable
9/14/2026
Show 1 more versionCollapse versions
1.0.0stable
9/1/2026

Related plugins

Loading related plugins…

Latest
1.3.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 1
Weekly downloads
0
Last push
9/18/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

DSH Preview Plugin

Live preview tab for DeepSeek Harness — embed any dev server in an iframe with transparent SPA proxying.

Features

  • Path-based SPA proxy: /preview/:port/* rewrites all routes so the embedded app works as if served from the DSH host
  • Editable URL bar: type a port, a path, a proxy path or a dev-server URL to move the preview wherever you need; the bar follows links clicked inside the page
  • Multi-app monorepo support: Configure backend ports to proxy API calls through the same iframe (e.g. Astro frontend + Payload CMS backend)
  • Smart routing: Static assets (JS, CSS, images) are proxied directly; SPA navigation serves root HTML so the client-side router handles routing
  • Fragment-link safe: #section links jump inside the page instead of reloading the site root, and anchors rendered after load are still reached
  • Root-relative resources work: /assets/photo.png, srcset and poster are rewritten too, so images and lazy-loaded stylesheets load instead of 404ing against the DSH host
  • Absolute URL rewriting: Intercepts fetch() and XMLHttpRequest.open() to rewrite both relative and absolute URLs (e.g. http://localhost:3001/api/... → /preview/3001/api/...)
  • Real API traffic: Method, body, cookies and Set-Cookie are forwarded, so the embedded app can log in, submit forms and use PUT/PATCH/DELETE — not just serve pages
  • Navigation stays inside the preview: forms, history.pushState, window.open and links that open a new tab keep the proxy prefix; an app that assigns location.href (which no script can intercept) is brought back instead of leaving you on the DSH app
  • Port config survives restarts: what you set is written to $DSH_HOME/preview-plugin.json and restored when DSH starts again
  • Agent tool: set_preview_port tool lets the agent configure ports programmatically when starting dev servers
  • Global or per-session ports: Set ports globally or per conversation session via the API
  • Auto-sync: The preview tab polls the host for agent-set port changes
  • Sandboxed iframe: allow-scripts allow-same-origin allow-forms allow-popups for secure embedding

Installation

1. Add as a dependency

In your DSH web profile's package.json:

{
  "dependencies": {
    "dsh-preview-plugin": "file:~/workspace/dsh-preview-plugin"
  }
}

2. Add to bundles

In your profile's package.json, add dsh-preview-plugin to the dsh.profile.bundles array:

{
  "dsh": {
    "profile": {
      "bundles": [
        "...",
        "dsh-preview-plugin"
      ]
    }
  }
}

3. Restart DSH

systemctl restart dsh

Usage

Basic (single server)

  1. Start your dev server on the VPS (e.g. npm run dev -- --host 0.0.0.0 --port 3000)
  2. Open the Preview tab in DSH Web GUI
  3. Type the port (e.g. 3000) in the URL field and click Go

The field then switches to the page being shown (e.g. /preview/3000/laptops?page=2#specs), so you can edit it at any time and press Enter to load something else.

Navigating

The URL field accepts all of these:

You typeIt loads
4321port 4321, root page
4321/laptopsport 4321, /laptops
/laptops?page=2that path on the port already in use
laptopssame as /laptops
?page=2 / #specsthe current page with that query/fragment
/preview/4321/laptopsa proxy path, as-is
http://localhost:4321/laptopsthe dev-server URL

Non-local URLs are rejected (the proxy only reaches 127.0.0.1). ↻ reloads the page currently shown, ↗ opens it in a browser tab of its own.

Multi-app monorepo

  1. Start both servers:

    # Backend (e.g. Payload CMS)
    cd apps/backend && pnpm dev  # port 3001
    
    # Frontend (e.g. Astro)
    cd apps/web && pnpm dev      # port 4321
    
  2. Open the Preview tab

  3. Type 4321 in URL and 3001 in Backend (comma-separated for multiple)

  4. Click Go — API calls to http://localhost:3001/api/... are automatically proxied through /preview/3001/api/...

Agent tool

The agent can configure ports programmatically using the set_preview_port tool:

set_preview_port(port: 4321, backendPorts: [3001])

This updates the interceptor script and client UI automatically.

API

MethodEndpointDescription
GET/api/preview-portGet the current global port and backend ports
GET/api/preview-port?sessionId=<id>Get ports for a session (falls back to global)
POST/api/preview-portSet global ports ({ "port": 4321, "backendPorts": [3001] })
POST/api/preview-port?sessionId=<id>Set ports for a session

How It Works

  1. The host registers three routes on the DSH web server:
    • /api/preview-port — port management
    • /preview/:port/* — transparent proxy
  2. Static assets (files with extensions like .js, .css, .png) are proxied directly from the requested path
  3. SPA navigation (all other paths) serves the root HTML from the dev server, so the client-side router handles routing
  4. For HTML responses, it injects:
    • <base href="/preview/:port/"> for relative URL resolution
    • An interceptor script that:
      • Handles fragment links (#section) itself: with a <base> tag they would otherwise resolve to /preview/:port/#section, a different path, and reload the site root instead of jumping inside the page. Targets that appear later (SPA sections) are retried for a few seconds.
      • Rewrites fetch() and XMLHttpRequest.open() URLs (relative, absolute frontend, and absolute backend)
      • Rewrites root-relative resource URLs (src, srcset, poster, data-src, and resource <link href>) on nodes added by JS — a <base> tag only affects truly relative URLs, so "/assets/x.png" would otherwise be fetched from the DSH host
  5. Resource URLs in the initial HTML are rewritten server-side, before the page is sent
  6. Requests keep their method, headers and body, and Set-Cookie comes back, so sessions and writes work inside the preview
  7. For non-HTML responses, it streams the response directly

Persistence

The preview config (frontend port + backend ports) is stored in ${DSH_HOME:-~/.dsh}/preview-plugin.json, so it survives a DSH restart and is shared by every session. Deleting the file simply resets it; a corrupt file is ignored.

Known limit

location.href = "/…", location.assign() and location.replace() cannot be intercepted: browsers install them as non-configurable own properties of the location object ([LegacyUnforgeable]). The preview tab notices the escape and reloads that path under the proxy, but an app that wants a clean URL should build it from its own base (e.g. Astro's import.meta.env.BASE_URL) or use a relative path.

Testing

pnpm install
pnpm test

node --test runs three suites:

SuiteWhat it covers
test/client-helpers.test.mjsURL/port parsing (resolveTarget) and proxy-path helpers
test/preview-view.test.mjsThe Preview tab component with real React and happy-dom
test/preview-proxy.test.mjsThe proxy end-to-end against a fixture site with Playwright (skipped when Chromium is unavailable)

Security Notes

  • The proxy only targets 127.0.0.1 — no external SSRF possible
  • The iframe is sandboxed with allow-scripts allow-same-origin allow-forms allow-popups
  • Port validation enforces 1–5 digit numbers only
  • Backend ports are validated and stored per frontend port
  • CORS headers are set for local development convenience

License

MIT