
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-any-background
Advanced tools
Appearance plugin for DeepSeek Harness: custom theme color (PS-style color wheel), background wallpaper with opacity/blur controls, and separate main/settings interface opacity.
English | 中文
A DeepSeek Harness appearance plugin: custom theme color, background wallpaper (image / video / algorithmically generated), and fine-grained per-surface opacity & blur controls. Compatible with DSH 0.2.0-rc.1 through 0.2.1-alpha.2 — and every host release above it (official-Sidebar UI such as the "Theme" card enables itself where the host exposes the Sidebar registry extension point, and is skipped silently where it does not).
Custom homepage · wallpaper + theme color applied
Theme color picker · PS-style wheel + precise HSL/RGB inputs
Per-part opacity and blur · main background, sidebar, cards, settings
Background editor · image/video wallpapers support drag-to-pan and scroll-to-zoom
Generated dynamic background · mesh gradient / Shader / geometric presets
Generated dynamic background · geometric low-poly mode preview
Export and import configs to share
backdrop-filter blur (0–60 px) per surface, including a real backdrop on the composer, the Cordis panel and popover surfaces via stable host selectors. A slider at 0 leaves the surface's OWN host frost in place rather than clearing it: the host frosts its menus by default (--dsw-menu-backdrop-filter: blur(40px) saturate(150%)), and a plugin value only takes over once the slider moves — the same "compete for nothing at 0" rule the composer capsule follows.--dsh-windows-sidebar-width), so the left part carries the sidebar's material and frost and the rest stays the 「标题栏」 card's. Drag the sidebar wider, or collapse it to 0px, and the cut moves with it.code highlight chips and produced chips share one opacity + blur slider. The opacity is the alpha of each surface's own background color (no second color stacked on top of the original), and the blur frosts that same layer so the wallpaper shows through the content.panelOpacity / blurs.panel), two identities: without dsh-better-sidebar it reads "右方侧边栏" (Right sidebar) and drives the official right Sidebar's surface tokens and frosted blur (works on 0.1.5-rc.2 through 0.1.7); with dsh-better-sidebar installed it reads "bettersidebar" and takes over that plugin's bottom workbench panel (the official sidebar keeps responding too). The row is always visible.conversation.session.header* slot anchors and tags the open popover at runtime instead of relying on class shapes.backdrop-filter, and because that filter turns the row into a stacking context the row also carries a compensating z-index:10 — the overlays it hosts (the background-job list through 0.2.1-alpha.1, the schedule task menu on every release) hang out of it with z-index:100 and would otherwise be confined under the conversation. 10 clears the in-column chrome it overlaps (seat 9, back-to-bottom 8) and stays under every page-level surface (100 / 1000 / 1100), so nothing about the part's look changes when a menu opens. No position is written — the row is a flex item, where z-index applies on its own. See v0.3.7. The anchor is expressed in CSS (the row is the conversation.session.header slot's direct parent) instead of guessing a hashed class or tagging a host element at runtime; before 0.1.7-alpha.1 the host mounts that slot bare with no such element, so there the rule matches nothing and the part is simply inert. On the Windows desktop shell the same slider pair also drives the window caption band — except for the segment that sits above the left sidebar, which belongs to that sidebar's own pair (see Left sidebar + the caption band above it) — and the native minimize/maximize/close block is handed transparent so Windows paints no background of its own, leaving the band itself showing through. A blank session marks the row headerBlank (a placeholder left with only its padding) and the plugin skips claiming it.sidebarRightTabs + the sidebar.right.pane.tab keyed seat); with dsh-better-sidebar installed, the page registers in that plugin's sidebar instead and the official guide card withdraws itself, so the two never duplicate. Settings panel, official sidebar and better-sidebar all share one page implementation and one state store — a change in any of them shows up everywhere. The shell adapts to the panel width, and a narrow panel tightens padding and falls back to a single column. On a host without the right Sidebar the registration silently never happens.dsh-any-theme.json (config + wallpaper, video embedded as a data URL) and import to restore it anywhere.@font-face; toggle it off or remove it at any time. Fonts stream as raw bytes and persist in the plugin data dir; code blocks keep their monospace stack.-webkit-text-stroke: width 0–4 px (0 = off) and a color of auto-contrast / gray / black / white / accent / custom. Code blocks, inline code, icons and the host's background-clip: text shimmer chrome (the "深度求索中" turn-status line and the turn-process rows) are exempted automatically, so multi-color syntax never smears and gradient text is never flattened into a stroke-coloured blob.Auto both the surface and font directions follow the accent's lightness (dark pick → light fonts, light pick → dark fonts), falling back to the wallpaper's perceived brightness when no color is picked.~/.dsh/.dsh-any-background-data/, not localStorage.The reported "the background-job list is under the conversation" was caused by the 「标题栏」 card's own frost, and the fix is a stacking order, not a state switch. The session header row is not an empty strip: the host mounts its header chrome INTO it (conversation.session.header.actions|.utilities), and that chrome raises its overlays from inside the row. ui-jobs/JobListAction hangs .menu{position:absolute; top:calc(100% + 5px); z-index:100} off a .root{position:relative} on every release through 0.2.1-alpha.1 — the captured DOM's style="left: 0px" with no top and no role IS that in-place shape, and the 0.2.1-alpha.2 portal is what hid the symptom on the newest tag, not what fixed it. ui-schedule/TaskMenu (role="menu", position:absolute; z-index:100 whenever the primitive is not in portal mode) sits in the same row on every release in range. Putting backdrop-filter on the row makes the row a STACKING CONTEXT, so those z-index:100 values stop being page-level and only order the overlays WITHIN the row; the row then paints at its own level — under the conversation body, the composer seat and .root's background. The menu was never demoted by the host: it was confined by us. The row now carries a compensating z-index:10 — above the in-column chrome the menu hangs over (.seat 9, back-to-bottom 8, footer 7, .tabs 1) and far below every page-level surface (portaled menus 100, modals 1000, stat / context panels 1100) — so the frost, the tint and the drag region never change state, and a portaled list still covers the title row exactly as the host intends. No position is written: the row is a flex item of ConversationRoot .root{display:flex}, where z-index applies on its own, which keeps the plugin out of deciding a host box's positioning (issue #24). The first attempt at this in the same release was a :has() valve that dropped the frost while a header overlay was open — it cleared the occlusion but re-tinted the whole title bar every time anyone opened a menu, which reads as the part's two sliders moving themselves. That attempt is gone.
A menu's blur slider at 0 no longer deletes the host's frost. The host frosts every menu by itself — --dsw-menu-backdrop-filter: blur(40px) saturate(150%), declared on body — and both paint shapes read that inherited value: a self-painting list through its own backdrop-filter, a MenuSurface card through its .material layer. The plugin re-declared that token on the menu with a none fallback, and an element's own declaration always beats what it inherits, so at slider 0 the frost was not "left alone", it was REMOVED — a faded menu with nothing frosted behind it lets the conversation show straight through it. (A second and separate defect made the same popup get buried outright — see the first bullet of this release.) Both menu groups' frost now rides a :where() gate on <html> (dab-card-frost / dab-header-frost) that switches on only while the slider is non-zero — the idiom the composer capsule already uses. :where() is what keeps the gate free: this plugin's menu cascade is ordered at equal specificity (card group → header group → exemptions), and a plain class prefix would have lifted the card group over the exemption it must lose to. The exemption's own none stays, because applyExemptDefaults pins those surfaces at alpha 1 beside it — opaque by design, not broken.
The background-job list is where the bug became visible. 0.2.1-alpha.2 portaled it out of the header row to document.body as position:fixed; z-index:100, a bare <ul> with no role — so the missing-frost defect below finally had something to be seen on — a list facing the whole page instead of hanging inside the column. The occlusion reported alongside it had the different cause spelled out in the first bullet. MenuSurface's own data-menu-material marker joins the card group for the same reason: ModelSelect renders its model pane as role="group", so keyed on [role="menu"] alone that card faded with the slider and never frosted with it.
The left sidebar and the caption band above it are one surface now. AppFrame's band is a single full-width box (.frame::before) whose left segment sits directly above the sidebar column, and the host publishes that column's width on the frame itself (--dsh-windows-sidebar-width, inline, Windows builds only). The plugin cuts the band at exactly that width: ::before is clipped to everything right of it — keeping the 「标题栏」 card's material, frost and drag region — and a new ::after paints the left segment from --dsh-any-op-sidebar, the very literal the sidebar column is painted with, frosted from a root-level mirror of the sidebar blur. One opacity + blur pair drives the column and the strip above it, and the cut follows a dragged or collapsed sidebar with no observer of ours (0px returns the whole band to the 标题栏 card).
The custom font now wins the cascade it was silently losing on 0.2.1-alpha.2. That tag moved the user font list into --dsh-font-family-text and made the host compose body{--dsw-font-family:var(--dsh-font-family-text,…)} in its own base.css — the same token, the same body selector and the same specificity as the rule this plugin's custom font writes, so which one applied became a question of which stylesheet landed last. The font rule now carries !important, the way the token sheet already does; code typography is left alone, as always.
The release table now speaks only for 0.2.x. The 0.1.5-rc, 0.1.6-alpha, 0.1.7-alpha and 0.1.7-rc folders, channels and rows are gone: nothing in the plugin still asserts a fact checked against them, and a table nobody verifies is worse than no table. engines.dsh, the gated peers and dsh.compatibility now start at 0.2.0-rc.1, which means an older host is refused at profile composition instead of being quietly styled with the wrong adapter — the DSHA launcher's bundled 0.1.5-rc.2 among them. 0.2.1-alpha.2 was verified by diffing its tag against the folder's facts (design-platform.css, MenuSurface, MenuGroup, the --dsw-menu-backdrop-filter consumers, AppFrame, the header slot keys and the right-sidebar panel — all unchanged) and joins that folder, renamed v0-2-1-alpha-1-2, so its verdict reads exact.
AppFrame.module.css's .frame::before — full width, exactly --dsh-windows-titlebar-height tall — and it filled from the host's sidebar token, outside the plugin's reach, so moving the sidebar slider turned the window's caption clear and dropped the title and the Application / Edit menubar onto the raw wallpaper (issue #23, symptom 1). The band now paints from this card's material at this card's opacity and frosts with the same blur variable, so one slider pair drives the session title row and the window caption and the two can never disagree.--dsw-specific-sidebar-fill, shipped over dsh-desktop:windows-appearance to setTitleBarOverlay). v0.3.5 pinned that probe to the material's opaque colour, which then disagreed with a band that had started following its sliders — a washed-out pale rectangle in light mode. The probe now reports transparent, so Windows paints no background there: the band already covers exactly those 40 px, so the block IS the band — one continuous surface, matching at every opacity. (Feeding the probe the card's paint along with its alpha was tried first: Windows then gives each button its own background patch, and the three stack into a lighter, visibly segmented block.) The glyphs are still measured separately off the same probe (--dsw-alias-label-primary), so they stay opaque and readable.AppFrame rounds .centerCol's top-left by 16 px and clips its overflow; once the frame is cleared to show the wallpaper, that notch let the wallpaper through under the conversation header's first pixels. The plugin now zeroes that corner (dab-center-flat).headerBlank (min-height:0, no bottom rule), leaving only its padding and the corner control — deliberately a row that paints nothing. The plugin claimed it anyway and tinted it, so a box appeared exactly where there was meant to be no header bar. Claiming now skips that marker, and only one element can hold the class: a row that goes blank, or one the host replaces, has the class removed.# published on the npm registry
dsh plugin --profile web add dsh-any-background
# or straight from the GitHub repository
dsh plugin --profile web add github:Tkingxiao/dsh-any-background
Then launch:
dsh web
The plugin appears as a "Theme" section in Settings.
npx @deepseek-ai/dsh plugin --profile web add dsh-any-background
npx @deepseek-ai/dsh web
The lib/ directory is committed, so installs need no build step. To rebuild after editing src/:
git clone https://github.com/Tkingxiao/dsh-any-background.git
cd dsh-any-background
pnpm install
pnpm run bundle
pnpm dsh plugin --profile web add "dsh-any-background"
pnpm dsh web
dsh web 0.2.0-rc.1 ~ 0.2.1-alpha.2, and everything above it with it — engines.dsh, the gated @deepseek-ai/dsh-* peerDependencies and dsh.compatibility.dsh name the builds this plugin was checked against one by one (0.2.0-rc.1, 0.2.0-rc.2, 0.2.1-alpha.1, 0.2.1-alpha.2) and close with an uncapped >=0.2.0-rc.1, so every later release loads. The uncapped umbrella is the deliberate choice: the host enforces exactly this peer list — a release it does not name is disabled before a single module is imported — so a range that runs out is a wall in front of a plugin that would have gone on working. An unseen release gets the closest verified adapter plus a log line saying how far from exact that is, and the worst a stale guess can cost is one slider no longer fading a surface the host has since moved; a version check that failed closed would have cost the whole plugin. dsh.compatibility.dshReleases records which builds were checked and how: every release in the list was checked by diffing its tag against the adapter folder that answers for it. That enforcement still means a dsh web restart when the plugin is installed or updated — the check runs while the profile is composed, not when the plugin is updated — but the uncapped umbrella is what spares a machine that has already moved to a newer host from needing a plugin release or a manual exact-version exemption (dsh plugin allow-version) first. The host release is resolved on the Node half at runtime, and features that depend on a specific host release channel (the right Sidebar's panel blur, the official Sidebar's "Theme" card) enable themselves only where the corresponding host structure exists; everything else behaves identically across the range. THE 0.1.5 / 0.1.6 / 0.1.7 ERA IS OUT OF THE SUPPORTED RANGE: those adapter folders asserted facts nothing re-checks any more, and the range above now starts at 0.2.0-rc.1, so an older host is refused at composition rather than quietly styled with the wrong adapter.ctx.profileContext.installAnchor, with the launcher's on-disk layout behind it — the client context exposes no version) and, once handed down through the read RPC, is routed only by the front-layer adapter — src/host-compat/ detects and buckets channels, while src/client/host-compat/versions/ holds one folder per set of verified facts (v0-2-0-rc-1 / v0-2-0-rc-2 / v0-2-1-alpha-1-2 / unknown), each describing that version's panel mechanics, header slot keys, plugin-page shape and where a menu's paint lives. A folder is keyed to what its facts cover, not to the shape of the version number: 0.2.0-rc.1 and 0.2.0-rc.2 are one prerelease channel, but rc.2 renamed the token a sticky menu group heading paints from, so the line carries two folders and the newer one is named for the build that opened it. A newer build whose facts did NOT move joins the folder that held instead of opening one of its own — 0.2.1-alpha.2 sits in v0-2-1-alpha-1-2 for exactly that reason, and gains a SUPPORTED_RELEASES row so its verdict reads exact rather than line. Base code just asks the adapter questions (who owns the guide surface, which layer carries the blur, which token fades a menu) and never compares version strings. Another build on a verified patch line (0.2.1-alpha.3 against a table checked through alpha.2) keeps that line's adapter, and a patch line nothing was checked against clamps to the nearest one with a log line saying so — which is the arm that now serves every release above 0.2.1-alpha.2. Only a release that will not parse at all falls into unknown and probes the DOM shape instead of guessing (:has() dual arms); supporting a new host means adding one folder and registering it.dsh is 0.1.5-rc.2, BELOW this plugin's supported floor since v0.3.7: the peer gate refuses it at composition, so the plugin never loads there rather than restyling that shell with 0.2.x facts.package.json declares dsh.bundle.patch: ./cordis.patch.yml (a loader insert layer), the repository ships prebuilt runtime artifacts ready to use (lib/index.js, lib/client.js), and there are no install scripts, no postinstall, no native binaries, and no build step at install time.<dsh home>/.dsh-any-background-data/ (config JSON, wallpaper, rotation pool, video, font) and touches nothing outside it; config writes are atomic (temp file + rename). These files live on the real disk, so they are outside generation restore — it neither captures nor rolls them back; deleting the directory is a full plugin reset.child_process, no native modules, no dynamically downloaded executables./dsh-any-background/{video,wallpaper,font} (GET/HEAD streaming) with matching */upload POST routes (100 MB cap) and the dedicated RPC channel /dsh-any-background under the local dsh web server; no extra listening ports.dsh web to load the client bundle; settings changes afterwards apply live and persist automatically. Updating the plugin requires a restart to pick up the new lib/client.js.pnpm run typecheck (full tsc check) and pnpm run bundle (tsdown emits lib/); no automated unit tests — behavior is verified manually.[data-sidebar-right-panel], [data-dsh-bottom-panel], …) and CSS token names; a host restyle of those layers can leave a slider ineffective for its surface (cosmetic only — nothing breaks). The version-specific half of those selectors lives inside its own version folder, so a host revision normally means editing that one file. -webkit-text-stroke may clip about 1px at the edge of some single-line ellipsis containers.MIT
FAQs
Appearance plugin for DeepSeek Harness: custom theme color (PS-style color wheel), background wallpaper with opacity/blur controls, and separate main/settings interface opacity.
The npm package dsh-any-background receives a total of 0 weekly downloads. As such, dsh-any-background popularity was classified as not popular.
We found that dsh-any-background 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.