
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-webview-wrapper
Advanced tools
A naive native desktop shell for the DeepSeek Harness web surface: hosts the dsh Web app in an OS window via WebviewJS, as a pure everything-is-a-plugin composition.
dsh-webview-wrapperEnglish | 中文
A naive native desktop shell for the DeepSeek Harness Web surface. dsh-webview-wrapper is an out-of-tree deepseek-harness plugin that hosts the already-running Web app in an OS-native window through WebviewJS — the platform's own webview engine (WebView2 on Windows, WebKit on macOS, WebKitGTK on Linux), never a bundled browser. No Electron, no fork, no patch to the harness.
In keeping with the everything-is-a-plugin philosophy, the integration is pure composition. The package installs into a profile like any out-of-tree plugin, its bundle patch layer inserts one plugin row, and the plugin mounts itself once the Web composition provides the webServer / webRuntime services. The harness itself stays a stock installation.
dsh web serves.Show / Quit) and tray double-click.dsh-webview-wrapper/invariant) registered with the InvariantRegistry.Prerequisites:
dsh web). The wrapper injects webServer and webRuntime, so the target profile must be Web-based — the shipped web profile is the natural target.libxdo.pnpm (the plugin manager forwards its arguments to pnpm).dsh plugin --profile web add dsh-webview-wrapper
dsh --profile web
The shipped web profile already lists the Web layers (@deepseek-ai/dsh-base, @deepseek-ai/dsh-web-app) in its dsh.profile.bundles. To use a custom profile, copy it and add only the wrapper:
cp -r ~/.dsh/profiles/web ~/.dsh/profiles/ww
dsh plugin --profile ww add dsh-webview-wrapper
dsh --profile ww
add does, step by stepdsh plugin initializes the profile on first use, then runs pnpm add in the profile directory.dsh-webview-wrapper declares dsh.bundle.patch in its manifest, the plugin manager automatically appends it to the profile's dsh.profile.bundles layer stack.cordis.patch.yml) pins the web-runtime row's browser handoff off (the wrapper owns the window) and inserts the webview plugin row into the composition.webServer / webRuntime, then owns the native window lifecycle.add the in-box bundlesdsh plugin add is only for out-of-tree plugins. The Web bundles (@deepseek-ai/dsh-base, @deepseek-ai/dsh-web-app) are in-box: they load from the harness installation and belong in dsh.profile.bundles — never in the profile's dependencies. adding an in-box bundle makes pnpm materialize the whole harness tree inside the profile's node_modules:
autoInstallPeers: false, so the tree is missing its peers (e.g. @deepseek-ai/cordis); pnpm peers check inside the profile reports them.$DSH_HOME/profiles/node_modules junctions) and fail to load — tool calls error.@deepseek-ai/dsh-web-app pulls in the harness's native directory picker, whose koffi dependency has an unapproved build script; pnpm 11 (default strict-dep-builds: true) exits non-zero (ERR_PNPM_IGNORED_BUILDS), dsh plugin skips the dsh.profile.bundles reconcile, and the profile boots without the Web layers.To get out of that state, drop the in-box bundle from dependencies (keep it in dsh.profile.bundles — it resolves from the installation), run pnpm install in the profile directory to prune the harness tree, and boot again.
Build the checkout first, then install from the folder:
pnpm run build
dsh plugin --profile web add file:/absolute/path/to/dsh-webview-wrapper
Show to open the 1024×768 window hosting http://127.0.0.1:<port> (the live Web surface).Quit in the tray menu exits the application.| File | Role |
|---|---|
src/index.ts | The plugin: creates the WebviewJS Application, the tray, and the main window; routes custom-menu-click, window-close-requested, and application-close-requested; calls app.exit() on disposal. |
cordis.patch.yml | The bundle patch layer: pins the web-runtime row's openBrowser off (the webview owns the window) and inserts { id: webview, name: 'dsh-webview-wrapper' } into the composition. |
src/invariant.ts | The invariant companion, registering the package with the InvariantRegistry. |
assets/icon.svg | Taskbar / tray icon source, rasterized with sharp. |
Lifecycle sketch:
apply(ctx)
├─ readIcon(icon.svg, 16) # one shared async rasterization
└─ ctx.effect(() => # plugin lifetime == native app lifetime
├─ new Application()
├─ whenReady() → 1×1 keep-alive window + tray (Show/Quit)
├─ tray double-click / Show → createOrShowMainWindow()
│ └─ BrowserWindow(1024×768) + webview → http://127.0.0.1:<ctx.webServer.port>
├─ window-close-requested → hide (close-to-tray)
└─ disposer → app.exit()
The wrapper is deliberately naive; the rough edges below are the roadmap:
Notification.http://127.0.0.1:<port>, the same browser HTTP carrier any tab uses. Roadmap: replace it with WebviewJS IPC (webview.expose() / window.ipc.postMessage) and/or a custom protocol, dropping the loopback-HTTP dependency.app.setMenu() with File/Edit roles and accelerators.Quit and profile shutdown. Roadmap: package as a GUI-subsystem executable (the WebviewJS CLI / Node SEA) so no console appears, and add an in-page quit affordance.Other current rough edges: default fixed 1024×768 window with a hardcoded title (no config surface yet), and the main window is not opened at startup (the app starts in the tray).
git clone https://github.com/no1xsyzy/dsh-webview-wrapper.git
cd dsh-webview-wrapper
pnpm install
pnpm run build # re-run after every change
dsh plugin --profile web add file:/absolute/path/to/dsh-webview-wrapper
For a private dev profile, copy web first as in Custom profile — add only out-of-tree plugins, never the in-box @deepseek-ai/dsh-web-app.
Notes:
webServer / webRuntime), so this checkout has no dev server and no standalone entrypoint — and its dependency chain ships prebuilt platform binaries, so there are no native addon builds either. Use the dsh plugin ... add file:<path> flow to test.lib/ and node_modules are gitignored; lib/ is build output.package.json name, the plugin name in src/index.ts, the bundle row in cordis.patch.yml, and the invariant registration in src/invariant.ts. The plugin manager resolves bundles and the InvariantRegistry keys registrations by npm name, so renaming means updating all four places.README.md and README.zh.md in sync.FAQs
A naive native desktop shell for the DeepSeek Harness web surface: hosts the dsh Web app in an OS window via WebviewJS, as a pure everything-is-a-plugin composition.
The npm package dsh-webview-wrapper receives a total of 13 weekly downloads. As such, dsh-webview-wrapper popularity was classified as not popular.
We found that dsh-webview-wrapper demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.