DeepSeek Harness plugin

dsh-plugin-mobile-shell

Narrow-viewport drawer, swipe gestures and document title for the DeepSeek Harness web shell

Jump to install

Source facts

Repository
ghbhiee/dsh-plugin-mobile-shell
Latest update
Aug 18, 2026
Category
Tools & Capabilities
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/ghbhiee/dsh-plugin-mobile-shell
Plugin: dsh-plugin-mobile-shell
Author: ghbhiee

Check the source files

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

File explorer3 files
README.mdSource · read only

dsh-plugin-mobile-shell

Narrow-viewport affordances for the DeepSeek Harness web UI: a drawer sidebar with a hamburger and scrim, swipe gestures, and a deployment-labelled browser tab title.

It replaces a set of hand-applied patches to @deepseek-ai/dsh-client-ui-layout's compiled bundle — the kind that has to be re-applied after every npm i -g and that breaks silently when the upstream build changes a hashed class name.

Install

Not on npm yet. The built lib/ is committed, so it installs straight from GitHub — no download, no build step:

dsh plugin --profile web add github:ghbhiee/dsh-plugin-mobile-shell

Or from a local clone (a link:, so a local rebuild is picked up):

git clone https://github.com/ghbhiee/dsh-plugin-mobile-shell.git
dsh plugin --profile web add ./dsh-plugin-mobile-shell

Sibling plugins install the same way: dsh-plugin-workbench and dsh-plugin-cli-session.

Develop

pnpm install
pnpm run check   # typecheck → vitest → tsdown build

Because lib/ is versioned (it is what a git install serves), rebuild and commit it with every source change. The build is byte-reproducible for unchanged sources within one checkout, so a diff under lib/ always means a real change — note that CSS-Module hashes derive from the build path, so build it from this clone rather than a worktree.

Configure

- id: mobile-shell
  config:
    narrowMaxWidth: 1440        # frame width at or below which the drawer takes over
    documentTitle: 'WB · {host}' # '' leaves the shell's own session title alone

A client entry never sees its row's config, so the browser half asks for these over a small host route and falls back to the defaults (1023 / DSH · {host}) if it cannot.

What it does

Below the configured frame width (1023px by default — the threshold the shell itself uses to auto-collapse the sidebar):

  • Drawer sidebar. The grid collapses to one column and the sidebar floats over the conversation instead of squeezing it, with a hamburger at the top left and a scrim behind it.
  • Direction-aware swipe. Swipe right to open, left to close. (The patch this replaces toggled on either direction, so a left swipe on a closed drawer opened it.)
  • Tapping a group keeps the drawer open. An expandable row carries aria-expanded; a leaf does not, and picking a leaf closes the drawer as you would expect after navigating.

At any width:

  • The tab title reads DSH · <hostname>, so several deployments are distinguishable in a row of tabs. It is pinned with a MutationObserver on <title>, so it survives the shell's own session-title projection.

How it hooks in

Everything is plugin-space:

  • The controls are one shell.overlay registration — the frame-wide layer that exists for exactly this.
  • Behaviour drives ctx.layout.toggleSidebar(), the cross-plugin panel face.
  • The drawer geometry is a global stylesheet keyed on stable DOM contract only: the [data-shell-overlay] layer (used to identify the frame via :has()) and the frame's data-sidebar-collapsed attribute. No compiled CSS-Module hash class is referenced anywhere, and colors come from --dsw-alias-* tokens.

Two things worth knowing if you extend this:

  • data-sidebar-collapsed is absent when open, not "false" — React drops a false-valued data-* prop. Match :not([data-sidebar-collapsed='true']).
  • One threshold, not two. The drawer's CSS keys on a data-mobile-shell-narrow mark the component sets from its measurement, not on a @media query — a media query would be a second copy of the threshold that silently diverges the moment it is configured.
  • Narrow-ness is measured from the frame box with a ResizeObserver, not from matchMedia. That mirrors how the shell decides, and a media-query listener can miss viewport changes that never fire change (devtools emulation, pane resizes), which strands the hamburger on a wide layout.

Tests

pnpm test (26 tests) covers the two contracts that broke during development — the absent-when-open attribute and frame-measured narrowness — plus the drawer controls, leaf-vs-group closing, swipe direction, and the reproducibility of the client bundle. The net is measured, not assumed: reverting the absent-when-open fix turns 6 red, reverting frame measurement turns 10, and un-sorting the CSS class map turns 2.

Known limitations

  • The "reclaim vertical padding" tweak was dropped. The patch it came from targeted compiled CSS-Module class names (.wSkVaW_header), of which the current build has five variants — it would fail silently on the next upstream release. The center column instead gets top padding so the hamburger does not cover content.
  • Swipe listens on the whole document, so a horizontal drag inside a scrollable area can still move the drawer.