
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-mobile-ui
Advanced tools
Mobile UI for the DeepSeek Harness Web GUI: responsive layout, overlay session drawer, 44px touch targets, safe-area support, reading enhancements (≤768px, zero desktop impact)
Mobile UI enhancements for the DeepSeek Harness Web GUI — turns dsh into a real mobile experience on phones (≤768px viewport):
env(safe-area-inset-*) support for notched displaysmax-width: 768px media query# from the plugin source directory
bash install.sh # install (idempotent)
bash install.sh --restart # install + restart dsh web (headless smoke test; aborts on plugin problems)
bash install.sh --uninstall # remove completely
Or via npm:
dsh plugin --profile web add dsh-mobile-ui
What the installer does:
~/.dsh/plugins/dsh-mobile-ui/~/.dsh/profiles/node_modules/dsh-mobile-ui/cordis.patch.yml insert)bash scripts/build.sh # syntax + contract preflight (incl. classic-script check)
bash scripts/package.sh # build dist/dsh-mobile-ui-install.tar.gz
Fast local iteration: copy to ~/.dsh/profiles/node_modules/dsh-mobile-ui/ and refresh the page (client plugins have an HMR channel — client.js edits apply on refresh).
style[data-plugin-css=dsh-mobile-ui], all rules wrapped in @media (max-width:768px) — desktop loads none of itmatchMedia-driven; on narrow screens the main grid goes single-column, the sidebar is hidden and becomes a fixed overlay drawer with scrimask_user_question, Mbwy4a component): JS detects the card and turns its composer seat into a full-height floating panel — no :has() dependency (works in WeChat/X5-style engines). The card's own max-height is lifted and its body stays the single scroll container, so long option lists scroll with a finger on every device; the footer button row wraps when narrow, so the submit button is always visible+ / attach / access mode) then the context ring and send pushed to its right edge; line 2 is the model trigger alone, spanning the full width. ⚠️ The first two-line attempt (tools alone on line 1, model + context + send on line 2) was wrong: it left 183px of dead space at the end of line 1 (measured at 412px) and the user immediately spotted it as "an empty patch up there". Lifting the context ring and send onto line 1 fills it (183px → 8px). Implemented with display:contents on the trailing group so its children become direct flex items of the row, then order for visual sequence and margin-left:auto to push the last two right — pure CSS, no DOM moves (relocating React nodes throws removeChild on re-render). Two lines are required, not cosmetic: the full model name (commandcode/deepseek/deepseek-v4.1-flash = 40 chars ≈ 225px) physically cannot fit on one line inside a 390px viewport — the row has 332px of content width and the tools need 120px, leaving the model trigger ~61px (10/40 chars, measured). Wrapping lets it take 218px at the same viewport (38/40 chars) and the full name from 400px up, at the cost of row height 52 → 90px. The access-mode button always shows its shield icon plus its text (@container (min-width: 170px), judged on the row's real width); a clipped model name always uses a real ellipsis.+/attach/access were only 36px), the primary button's upstream translateY(-2px) is cancelled (a single-line-era optical compensation that pushed its centre 2px below its row), and the access-mode button gets the same round solid background as +/attach (upstream renders it as a background-less compact trigger, which looked like a missing piece between two round buttons). Invariants: exactly two lines; within a row every button is the same height, the same font size, and their vertical centres spread ≤1.5px; and no line may end in more than 60px of dead space (the quantitative guard for that "empty patch"). ⚠️ One more subtlevty: the UA default for <button> is text-align:center — once the model name spans a full line, centring makes the text start at x=69px instead of aligning with the + button above, so text-align:left must be explicit (the old layout never exposed this because the label's width exactly equalled its text width). ⚠️ This surfaced a fourth word-root leak: the message flow contains no [class*=tools] at all (only xzv4MW_actions / TS9iAW_actions), so the old [class*=scrollBody] [class*=tools] button{min-height:36px} was really hitting the composer's uV2eYG_tools and crushing +/attach/access to 36px — the actual cause of "row 1 is 36px while row 2 is 40/44px". It is now scoped to [class*=flowItem], so message-flow buttons stay 36px and composer controls 44px. Never fake a single line with "no-wrap + shrink": upstream group buttons carry a non-compressible min-width: 44px, so a narrow row cannot resolve by shrinking and simply overlaps (the original bug: at 390px the model trigger covered the context ring by 4.3px and the access-mode button covered it by 5.7px).python3 tests/mobile-layout-probe.py drives a real headless Chromium (upstream CSS + real DOM nesting + the actual plugin bundle) across viewports, asserting two families of invariants: for the QA card — "option list scrolls / last option reachable after a real touch swipe / submit always visible / the fixed top-right menu button does not overlap the card"; for the composer row — "no two controls overlap / nothing spills past the card's right edge / every control is hit-testable / the access-mode icon and its text are always visible / the model name keeps at least 120px so it never degrades back into a sliver / a clipped model name uses a real ellipsis / icon, text and chevron are vertically centred". Exit code 1 on regression._7KE1Ra_triggerLabel / triggerIcon / triggerEffort all contain "trigger", so a bare [class*=trigger] hits them too: with display:flex the text-overflow:ellipsis is ignored (flex containers ignore it) and the model name is cut mid-character; with min-height:40px the label is stretched to full row height and its text hugs the top, so the chevron looks like it dropped to another line. Always narrow to button[class*=trigger], and keep ellipsis on display:block. Likewise button[aria-label*=访问模式] span { display:none } hides the shield icon as well (it is a span too), leaving a completely blank button — hide only [class*=triggerLabel] and keep the icon permanently visible. Two more rules it guards: never override the card body's overflow (that is exactly what broke scrolling before), and hide the floating menu button whenever the question card is open (it sits at top:48px; right:12px, right on top of the card title). Related: a min-width floor on the trailing group's content is harmful — flex:1 1 0 + min-width:0 + justify-content:flex-end spills children leftward over the tools group once the box is narrower than its content minimum (measured: 9px at 365px viewport with min-width:96px), so express "the model name should stay readable" some other way.body.dsh-mobile-ui and #dsh-mobile-menu-btn exist in the console[class*=frame] etc.) — adjust CSS/JS to the new prefixbash install.sh after fixingaria-label — this tolerates class-name driftinsertBefore/appendChild on pXSMma_root etc.): React's fiber tree still records the old parent, so a re-render throws removeChild NotFoundError and the whole conversation view unmounts (blank page). Express every layout need in CSS (flex / order / :has) — the hero title pinning and the QA card are pure CSS for this reason.bash install.sh --uninstall + restart dsh removes everything (no residual styles/DOM).
MIT. Chinese documentation: README.zh.md
Part of dsh-plugins — a small monorepo of DSH plugins: dsh-lan-gateway, dsh-vision-tool, dsh-mobile-ui.
FAQs
Mobile UI for the DeepSeek Harness Web GUI: responsive layout, overlay session drawer, 44px touch targets, safe-area support, reading enhancements (≤768px, zero desktop impact)
The npm package dsh-mobile-ui receives a total of 48 weekly downloads. As such, dsh-mobile-ui popularity was classified as not popular.
We found that dsh-mobile-ui 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.