dsh-any-background 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <a href="https://www.npmjs.com/package/dsh-any-background"><img alt="npm version" src="https://img.shields.io/npm/v/dsh-any-background?color=4d6bfe"></a>
5
5
  <a href="https://www.npmjs.com/package/dsh-any-background"><img alt="npm monthly downloads" src="https://img.shields.io/npm/dm/dsh-any-background?color=4d6bfe"></a>
6
6
  <a href="https://github.com/Tkingxiao/dsh-any-background/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/npm/l/dsh-any-background?color=4d6bfe"></a>
7
- <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="Supported DSH versions: 0.2.0-rc.1 ~ 0.2.1-rc.3 and above" src="https://img.shields.io/badge/DSH-0.2.0--rc.1%20~%200.2.1--rc.3%2B-4d6bfe" /></a>
7
+ <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="Supported DSH versions: 0.2.0-rc.1 ~ 0.2.2-alpha.2 and above" src="https://img.shields.io/badge/DSH-0.2.0--rc.1%20~%200.2.2--alpha.2%2B-4d6bfe" /></a>
8
8
  <a href="https://github.com/topics/dsh-better-sidebar"><img alt="Plugin ecosystem: GitHub topic dsh-better-sidebar" src="https://img.shields.io/badge/plugin%20ecosystem-topic%20dsh--better--sidebar-4d6bfe" /></a><br /><br />
9
9
  <a href="https://github.com/Tkingxiao/dsh-any-background"><img src="https://img.shields.io/github/stars/Tkingxiao/dsh-any-background?style=social" alt="GitHub stars"></a>
10
10
  <a href="https://dsh.directory/plugins/tkingxiao/dsh-any-background"><img src="https://dsh.directory/badges/listed.svg" alt="dsh.directory listed"></a>
@@ -12,86 +12,73 @@
12
12
 
13
13
  English | [中文](README.zh.md)
14
14
 
15
- 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-rc.3` — 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).
15
+ A **DeepSeek Harness** appearance plugin: custom theme color, background wallpaper (image / video / algorithmically generated), and per-surface opacity & blur control. Compatible with **DSH `0.2.0-rc.1` through `0.2.2-alpha.2` — and every host release above it**.
16
16
 
17
17
  ---
18
18
 
19
19
  ## Screenshots
20
20
 
21
- <p align="center">
22
- <img src="example_img/image.png" alt="Custom homepage" width="720">
23
- <br/>
24
- <em>Custom homepage · wallpaper + theme color applied</em>
25
- </p>
21
+ <table>
22
+ <tr>
23
+ <td align="center"><img src="example_img/image.png" width="440" alt="Custom homepage"><br/><em>Custom homepage · wallpaper + theme color applied</em></td>
24
+ <td align="center"><img src="example_img/image-2.png" width="440" alt="Theme color picker"><br/><em>Theme color picker · PS-style wheel + HSL/RGB inputs</em></td>
25
+ </tr>
26
+ <tr>
27
+ <td align="center"><img src="example_img/image-3.png" width="440" alt="Per-surface opacity and blur"><br/><em>Per-surface opacity and blur</em></td>
28
+ <td align="center"><img src="example_img/image-4.png" width="440" alt="Background editor"><br/><em>Background editor · pan and zoom</em></td>
29
+ </tr>
30
+ <tr>
31
+ <td align="center"><img src="example_img/image-6.png" width="440" alt="Generated dynamic background"><br/><em>Generated background · mesh gradient / Shader / geometric</em></td>
32
+ <td align="center"><img src="example_img/image-9.png" width="440" alt="Geometric background, low-poly mode"><br/><em>Generated background · geometric low-poly</em></td>
33
+ </tr>
34
+ <tr>
35
+ <td align="center" colspan="2"><img src="example_img/image-10.png" width="440" alt="Config export and import"><br/><em>Export and import configs to share them</em></td>
36
+ </tr>
37
+ </table>
26
38
 
27
- <p align="center">
28
- <img src="example_img/image-2.png" alt="Theme color picker" width="720">
29
- <br/>
30
- <em>Theme color picker · PS-style wheel + precise HSL/RGB inputs</em>
31
- </p>
39
+ ## Features
32
40
 
33
- <p align="center">
34
- <img src="example_img/image-3.png" alt="Per-part opacity and blur" width="720">
35
- <br/>
36
- <em>Per-part opacity and blur · main background, sidebar, cards, settings</em>
37
- </p>
41
+ ### Color & theme
38
42
 
39
- <p align="center">
40
- <img src="example_img/image-4.png" alt="Background editor" width="720">
41
- <br/>
42
- <em>Background editor · image/video wallpapers support drag-to-pan and scroll-to-zoom</em>
43
- </p>
43
+ - **PS-style color wheel** — Hue on the ring, saturation and lightness in the inscribed square; generates 30+ CSS design tokens live.
44
+ - **Precise HSL / RGB input** — Numeric entry, bidirectionally synced with the wheel.
45
+ - **Smart extraction / eyedropper** — One click derives a theme color from the wallpaper (sampling the visible area and discarding gray, near-black and near-white), or hover any pixel to pick it. Video wallpapers contribute an auto-captured frame. All client-side.
46
+ - **Forced light / dark scheme** — Light, dark or auto. In auto the surface and font direction follow the accent color's lightness (dark pick → light text), falling back to the wallpaper's brightness when no accent is set.
47
+ - **Theme export / import** — A self-contained `dsh-any-theme.json` (config + wallpaper + the whole rotation pool) that restores anywhere.
48
+ - **Presets & profiles** — Six one-click presets plus named profiles that can be renamed and duplicated; deleting asks for confirmation twice.
44
49
 
45
- <p align="center">
46
- <img src="example_img/image-6.png" alt="Generated dynamic background" width="720">
47
- <br/>
48
- <em>Generated dynamic background · mesh gradient / Shader / geometric presets</em>
49
- </p>
50
+ ### Background & wallpaper
50
51
 
51
- <p align="center">
52
- <img src="example_img/image-9.png" alt="Geometric background, low-poly mode" width="720">
53
- <br/>
54
- <em>Generated dynamic background · geometric low-poly mode preview</em>
55
- </p>
52
+ - **Image wallpaper** — Upload any image as the background.
53
+ - **Video wallpaper** — Muted, looping, survives refreshes (persisted on disk + HTTP Range streaming), with one frame captured for the preview, color extraction and position editing.
54
+ - **Position editor & layout modes** — Drag to pan, scroll or pinch to zoom, one-click reset; Fit / Fill / Stretch / Tile / Center. Image and video placements are stored separately and never overwrite each other.
55
+ - **Generated backgrounds** — Mesh gradient, Shader or geometric patterns, with adjustable spread and intensity and a lockable seed.
56
+ - **Wallpaper rotation** — Build a pool with the thumbnail picker and rotate by shuffle or order, on every refresh / hourly / daily / weekly; the cadence advances while the page stays open, not only on reload.
57
+ - **Day / night switch** — A day profile and a night profile, switched on a fixed schedule or by following the OS dark mode.
56
58
 
57
- <p align="center">
58
- <img src="example_img/image-10.png" alt="Config export and import" width="720">
59
- <br/>
60
- <em>Export and import configs to share</em>
61
- </p>
59
+ ### Per-surface opacity & blur
62
60
 
63
- ## Features
61
+ - **Eleven parts, each with its own slider pair** — main background, sidebar, card panels, input & controls, settings panel, conversation frame, trajectory view, right sidebar (or bettersidebar), produced / highlighted content, header popovers, and the header bar.
62
+ - **The slider IS the frost amount, and 0 means no frost** — including over the host's own default menu frost. Every part still **defaults to 30px**, so a stock install keeps the frosted look.
63
+ - **Opacity re-scopes the host's own token** — it never stacks a second color over the original, so the wallpaper shows through the content.
64
+ - **Produced / highlighted content shares one slider** — code blocks (with their language banner), inline `code` chips and produced chips move together.
65
+ - **Right sidebar / bettersidebar: one pair, two identities** — without dsh-better-sidebar it drives the official right sidebar; with it installed the same pair takes over that plugin's bottom workbench panel (the official sidebar keeps responding too).
66
+ - **On the Windows desktop shell it also drives the caption band** — the sidebar pair paints the segment directly above the sidebar, and the cut follows the sidebar's width as it is dragged or collapsed (at width 0 the band returns to the header card). The 「标题栏」 card drives the rest of the band and the native window controls, with a four-state 「标题条带文字」 choice (auto / follow theme / always white / always black) for when a light strip fights the theme.
64
67
 
65
- - **PS-style Color Wheel** — Pick hue on the ring, adjust saturation & lightness in the inscribed square. Generates 30+ CSS design tokens in real time.
66
- - **Precise HSL / RGB Input** — Enter exact color values numerically with instant bidirectional sync to the wheel.
67
- - **Smart Color Extraction** — One click derives a theme color from your wallpaper by sampling the visible region, quantizing, and filtering out gray / near-black / near-white pixels. Video wallpapers contribute via an auto-captured frame. Fully client-side.
68
- - **Eyedropper** — Hover the wallpaper to preview a color and click to pick it as the theme color.
69
- - **Background Wallpaper** — Upload any image as your wallpaper. Drag to pan and scroll to zoom inside a viewport-proportional editor (one finger to pan, two to pinch-zoom on touchscreens).
70
- - **Video Wallpaper** — Use a video as a live wallpaper: muted looping playback that survives refreshes (file persistence + HTTP streaming with Range seek), with an auto-captured frame powering the preview, theme-color extraction, and the position editor.
71
- - **Position Editor** — One shared editor for images and videos: drag to pan, scroll or pinch to zoom, one-click reset. Image and video placements are stored separately and never overwrite each other.
72
- - **Layout Modes** — Fit / Fill / Stretch / Tile / Center for both images and videos; in Fit mode the editor-committed framing stays consistent across window resizes and cross-monitor moves.
73
- - **Generated Dynamic Backgrounds** — Choose mesh gradient, Shader, or geometric patterns with adjustable spread, intensity, and seed locking.
74
- - **Per-surface Interface Opacity** — Independent sliders for the main background, sidebar, cards & panels (including the dropdowns and menus around the dialog), the input & controls (composer box, Cordis panel), the settings panel, the conversation text frame, the trajectory view, the right sidebar (or bettersidebar), produced / highlighted content, the header popovers (Agent Team panel, background-job list and the session-header dropdowns), and the header bar (the conversation's title / view-tab row).
75
- - **Per-surface Interface Blur** — Frosted-glass `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. The slider IS the frost amount, and **0 means no frost** — including over the host's own default (`--dsw-menu-backdrop-filter: blur(40px) saturate(150%)`). Through 0.3.7 a 0 meant "leave the host alone", which made the bottom of the slider the blurriest setting it could produce (0 = the host's 40 px, 1 = 1 px) and left "turn the blur off" unreachable; now 0 is 0, and because every part still DEFAULTS to 30 px a stock install keeps the frosted look unless someone drags it down.
76
- - **Left sidebar + the caption band above it** — On the Windows desktop shell the sidebar's opacity + blur pair drives the sidebar column AND the segment of the window caption strip that sits directly above it. The host paints that strip as one full-width box; the plugin cuts it at the sidebar's own published width (`--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. The split is deliberate (issue #29, item 3): the left strip IS the sidebar column's own surface, so the header-bar sliders are not meant to reach it.
77
- - **Produced / Highlights** — Code blocks in conversation content (with their language banner), inline `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.
78
- - **Right sidebar / bettersidebar surface** — One slider pair (`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.
79
- - **Header popovers** — The session-header dropdowns get their own opacity + blur pair: the Agent Team panel, the background-job list, the open-in-app / session-log menus and the subagent lineage tree. On 0.1.7 the open-in-app picker moved to a portal and the session-row menu became a dynamic slot, so the plugin observes the stable `conversation.session.header*` slot anchors and tags the open popover at runtime instead of relying on class shapes. A popover counts as the header's when it is portaled to `<body>` **or** mounted inside one of those anchors — the session-log `…` menu is the second kind (`session-log-export/HeaderAction.tsx` renders its `Menu` without `portal`), and until 0.3.9 only a fragile `_denseList`-class arm reached it.
80
- - **Header bar (the session title row)** — The row carrying the session title, its actions and the view tabs gets a slider pair of its own. The host paints nothing there (the centre column's background shows straight through), so once a wallpaper is up the title and tabs sat on the raw picture while every masked surface around them did not. It now paints as a region tint, the same recipe as the chat column's card: the material is the plugin's main-background surface at this part's own opacity, so the bar reads as one band over the column rather than a second colour stacked on it. The frost rides a `::before` underlay behind an `isolation:isolate` on the row — a stacking context that is NOT a backdrop root, which is what lets the overlays hanging off the row frost the wallpaper at all (through 0.3.8 the filter sat on the row itself, and a filtered row is a backdrop root: exactly those panels were left blurring a flat tint). Because that context still localizes the row's paint order, the row carries a compensating `z-index:10` — the overlays it hosts (the background-job list through `0.2.1-alpha.1`, the schedule task menu and the session-log `…` 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. `z-index` needs no `position` — the row is a flex item, where it applies on its own — and the underlay's `position:relative` is written inline only while a blur exists and only when the host left the row `static`. See v0.3.7 / v0.3.9. On the Windows desktop shell the band it drives is split with the sidebar (previous bullet), dims itself while a modal is open (the host mask deliberately stops below the caption), and its generated segment is paint-only — `pointer-events:none` and no `app-region` declaration — so it can never swallow clicks meant for the native caption menubar (issue #29). It also paints below the
81
- controls (`z-index:-1`) and carries its own ink (`--dsh-any-caption-ink`), so the sidebar toggle and the
82
- 应用 / 编辑 menubar stay readable even when a low sidebar opacity makes the strip light — and 「标题条带文字」 says who wins when the strip's brightness and the theme's direction disagree (自动 derives it from the strip, 跟随主题 leaves the host's own label ink alone, 始终白色 / 始终黑色 pins it; see issue #30). 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.
83
- - **Sidebar "Theme" page (dual mode)** — The same five pages (Color / Interface / Font / Background / Profiles) register into two surfaces: without dsh-better-sidebar, a "Theme" card is contributed to the **official right Sidebar's guide page** through its public extension points (`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.
84
- - **Conversation View Cards** — The message list is wrapped in a translucent card automatically, and the trajectory page gets whole-page opacity & blur controls, letting the wallpaper shine through the content.
85
- - **Theme Export / Import** — One-click export to a self-contained `dsh-any-theme.json` (config + wallpaper, video embedded as a data URL, and — from v0.4.0 — the whole rotation pool's image bytes) and import to restore it anywhere.
86
- - **Appearance Presets & Profiles** — Six one-click presets (Default / Frosted glass / Minimal / Midnight / Cyber / Warm daylight) plus named profiles: save the current look and re-apply it anytime; profiles can be renamed and duplicated, and a two-step confirm guards deletion.
87
- - **Wallpaper Rotation** — Add images to a rotation pool (thumbnail picker included) and let the wallpaper change by shuffle or order on every refresh, hourly, daily, or weekly — the cadence advances while the page stays open, not only on reload. Advancing copies the chosen image into the active wallpaper slot, so export/import and color extraction keep working unchanged.
88
- - **Day/Night Auto Switch** — Assign a day profile and a night profile; the plugin switches automatically at fixed clock times or by following the OS dark mode.
89
- - **Custom Font** — Upload a ttf / otf / woff / woff2 file (up to 100 MB) and apply it to the whole interface through `@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.
90
- - **Per-part Text Outline** — The same surface groups as the interface page (now eleven, including the header popovers and the header bar), each with its own `-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.
91
- - **Forced Interface Scheme** — Force light or dark token palettes regardless of the accent color's lightness; in `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.
92
- - **File-based Persistence** — All settings are stored on the filesystem under `~/.dsh/.dsh-any-background-data/`, not `localStorage`.
93
- - **Bilingual** — Full Chinese / English UI with automatic locale detection.
94
- - **Theme Watchdog** — Re-asserts the custom theme if the host resets it.
68
+ ### Interface parts
69
+
70
+ - **Sidebar "Theme" page (dual mode)** — The same five pages (Color / Interface / Font / Background / Profiles) register into the official right sidebar's guide page or into dsh-better-sidebar's sidebar, sharing one state with the settings panel, so a change anywhere shows everywhere. On a host without that extension point nothing is registered, silently.
71
+ - **Conversation view cards** — The message list is wrapped in a translucent card automatically, and the trajectory page adjusts as a whole page.
72
+ - **Header popovers and the header bar are separately adjustable** — the Agent Team panel, the background-job list, the session-header dropdowns, and the title / view-tab row at the top of a session each have their own opacity + blur pair.
73
+ - **Custom font** — Upload a ttf / otf / woff / woff2 (up to 100 MB) and apply it across the interface; code blocks stay monospace. Can be disabled or removed at any time.
74
+ - **Per-part text outline** — The same surface groups as the interface page, each with its own `-webkit-text-stroke` (0–4px, 0 = off) in auto-contrast / gray / black / white / accent / custom. Code blocks, inline `code`, icons and the host's gradient-shimmer text are exempt automatically.
75
+ - **Third-party compatibility** — When [dsh-better-display](https://github.com/aa2246740/dsh-better-display) is detected, its sticky summary band is pinned at a 20% plate + 30px frost outside the sliders. Any other plugin whose surface reads a token this plugin owns is named in the console, and the whole accommodation can be switched off in Settings.
76
+
77
+ ### General
78
+
79
+ - **File-based persistence** — Everything is stored under `~/.dsh/.dsh-any-background-data/`, not in `localStorage`.
80
+ - **Bilingual UI** — Full Chinese / English interface following the host's locale.
81
+ - **Theme watchdog** — Re-asserts the custom theme if the host resets it.
95
82
 
96
83
  ## Changelog (latest two releases)
97
84
 
@@ -102,9 +89,14 @@ controls (`z-index:-1`) and carries its own ink (`--dsh-any-caption-ink`), so th
102
89
  - **Issue #32 fixed.** The frosted sidebar column is lifted to `z-index:1`, so a tooltip overhanging the sidebar's right edge stays crisp; the modal exemption now resets `z-index` and `isolation` together.
103
90
  - After installing or updating, **restart the host once** — the compatibility gate runs when the profile is assembled.
104
91
 
105
- ### v0.4.1 (fixes the "Every refresh" cadence flipping the wallpaper every 30 seconds)
92
+ ### v0.4.3 (follows dsh `0.2.1-rc.5` and the newly opened `0.2.2` line)
106
93
 
107
- - Only the time-based cadences (hourly / daily / weekly) advance on the schedule tick; "Every refresh" keeps its original meaning: one fresh pick per page load, plus the manual next button.
94
+ - **Newly checked host builds**: `0.2.1-rc.4`, `0.2.1-rc.5`, `0.2.2-alpha.2`.
95
+ - **`rc.4` / `rc.5` change nothing.** Every shipped file of the 296 `@deepseek-ai/dsh-*` packages in a `0.2.1-rc.3` install was hashed through `rc.5`: 30 files moved in total, and not one of them is a stylesheet this plugin reads. Three are inlined version-string literals; the rest are the host's settings-tab tooltip becoming conditional and the reasoning-body slot gaining a `rawText`. No token, no `[class*="…"]` class shape, no `z-index` and no `data-slot` key moved, so both builds join the `v0-2-1` row and their verdict rises from `line` to `exact`.
96
+ - **`0.2.2` is a new patch line, so `v0-2-2` opens its own facts folder.** That release is big (1151 files changed, 1709 added), but every fact this plugin claims was re-read and still holds: `_handle{z-index:11}` / `_leadingSeat{z-index:15}` / `_overlayLayer{z-index:20}` are byte-identical (so the sidebar column's ceiling of 1 and the header row's 10 are argued exactly as before), the four menu-frost tokens and the 8 `--dsw-menu-backdrop-filter` consumers are unchanged, the host still composes `--dsw-font-family` on `body` (the font rule's `!important` still has to win), the five session-header slot keys stand, and all 75 host selectors this plugin writes still match. The host's peer gate is byte-identical too.
97
+ - **Two host changes on `0.2.2` worth recording**: `--dsw-specific-sidebar-nav-item-hover` is deleted host-side, together with its only consumer — the plugin still writes the token, which now writes something nobody reads, and since the host stopped painting that hover at all there is no regression against the host default; and `ui-plugin-manager` gained a new consumer of the token the main-interface slider takes over (a `pointer-events:none` underlay behind the page header), which paints nothing at the default value but is a new row on the "who reads this token" list.
98
+ - **The version gate now has its own check**: `npm test` verifies that `engines.dsh`, the six peer ranges and `dsh.compatibility.dsh` each name every verified build and all keep their uncapped tail, and that `lib/` really carries those builds and their channels — so editing `src/` without re-bundling is now caught outright.
99
+ - After installing or updating, **restart the host once** — the compatibility gate runs when the profile is composed.
108
100
 
109
101
  ## Installation
110
102
 
@@ -148,21 +140,37 @@ pnpm dsh web
148
140
 
149
141
  ## Compatibility
150
142
 
151
- - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) `0.2.0-rc.1` ~ `0.2.1-rc.3`, 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-rc.3`) 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.
152
- - **Isolated per-version adaptation**: the release is resolved on the Node half from the app manifest the process was composed from (`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` / `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 — the whole `0.2.1` line (`alpha.1` … `rc.3`) sits in `v0-2-1` for exactly that reason, with one `SUPPORTED_RELEASES` row per checked build so each 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 (a future `0.2.1-rc.4` against a table checked through `rc.3`) 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-rc.3`. 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.
153
- - **[DSHA](https://github.com/DSH-APP/DSHA)** — DeepSeek Harness Android launcher (ROOT-free, Termux-free). Its bundled `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.
154
- - **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — Supported
143
+ - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness): `0.2.0-rc.1` ~ `0.2.2-alpha.2`, and everything above it.** The gate names each build that was checked and then closes with an uncapped `>=0.2.0-rc.1`. That umbrella is deliberate: 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 kept working. (More precisely: the host's `app-boot` `unmetRequirements` reads `engines.dsh` alone when that field is present and ignores peerDependencies, so all four places must say the same thing but `engines.dsh` is what actually decides whether the plugin loads.)
144
+ - **How an unseen build runs**: it gets the closest verified set of facts plus a log line saying how far from `exact` that is. The worst a stale fact can cost is one slider no longer fading a surface the host has since moved; a version check that failed closed would cost the whole plugin.
145
+ - **Verified builds** (`dsh.compatibility.dshReleases`):
146
+
147
+ | Host build | Facts folder | Notes |
148
+ |---|---|---|
149
+ | `0.2.0-rc.1` | `v0-2-0-rc-1` | verified by diffing its tag, package by package |
150
+ | `0.2.0-rc.2` | `v0-2-0-rc-2` | same; this rc renamed the token a sticky menu group heading paints from, so it opened its own facts |
151
+ | `0.2.1-alpha.1` ~ `0.2.1-rc.5` | `v0-2-1` | facts unchanged, folded into one folder; every checked build gets its own row with an `exact` verdict. `rc.4` and `rc.5` ship artifacts byte-identical to `rc.3`, file by file |
152
+ | `0.2.2-alpha.2` | `v0-2-2` | a new patch line, so its own facts folder; every claim re-read and still true (z-index ladder, menu frost tokens, font token composition, header slot keys, 75 host selectors matching) |
153
+ | above `0.2.2-alpha.2` | reuses the closest row | an unverified build takes that line's adapter, stated in the log |
154
+
155
+ - **Facts are isolated per release**: the host release is resolved on the Node half and handed down through the `read` RPC; styling and logic only ask the adapter questions (who owns this surface, which layer carries the frost, which token fades a menu) and never compare version strings. Supporting a new host means adding one version folder and registering it.
156
+ - **A restart is still needed after installing or updating the plugin**: the compatibility check runs while the profile is composed, not when the plugin is updated. Features that depend on a specific host structure (the right sidebar's panel blur, the official sidebar's "Theme" card) enable themselves only where that structure exists; everything else behaves identically across the range.
157
+ - **The `0.1.5` / `0.1.6` / `0.1.7` era is out of the supported range**: those fact folders assert things nothing re-checks any more, and a table nobody verifies is worse than no table. An older host is now refused at composition rather than quietly restyled by the wrong adapter.
158
+ - **[DSHA](https://github.com/DSH-APP/DSHA)** — the DeepSeek Harness Android launcher (ROOT-free, Termux-free). Its bundled `dsh` is `0.1.5-rc.2`, below this plugin's supported floor: the peer gate refuses it at composition, so the plugin never loads there.
159
+ - **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — supported. Windows-only behavior (the caption band, the native window controls) applies on the desktop shell only.
155
160
 
156
161
  ## Permissions, side effects & boundaries
157
162
 
158
- - **Integration form**: official Profile Bundle — `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.
159
- - **Filesystem**: the server half reads and writes only inside `<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.
160
- - **Network**: one outbound fetch happens only when the user pastes an http/https image or video URL and presses Apply; no telemetry, no other external calls.
161
- - **Shell / native**: none. No `child_process`, no native modules, no dynamically downloaded executables.
162
- - **HTTP surface**: registers only `/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.
163
- - **Restart requirements**: the first install needs a (re)start of `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`.
164
- - **Tests & verification**: `pnpm run typecheck` (full tsc check) and `pnpm run bundle` (tsdown emits `lib/`); no automated unit tests — behavior is verified manually.
165
- - **Known limitations**: the styling relies on stable host DOM markers (`[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. One rule is a deliberate cross-plugin accommodation: dsh-better-display paints its sticky reading lanes from the token our 「主界面」 opacity owns, so when that plugin is detected its lanes are pinned at 20% plate + 30px frost outside the sliders — if it ever renames those markers the rule stops matching and its lanes simply go back to being painted the way it paints them.
163
+ - **Integration form**: an official Profile Bundle — `package.json` declares `dsh.bundle.patch: ./cordis.patch.yml` (a loader insert layer) and the repository ships ready-to-use prebuilt artifacts (`lib/index.js`, `lib/client.js`). No install scripts, no postinstall, no native binaries, no build step at install time.
164
+ - **Filesystem**: the server half reads and writes only inside `<dsh home>/.dsh-any-background-data/` (config, 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.
165
+ - **Network**: exactly one outbound fetch, and only when the user pastes an http/https image or video URL and presses Apply. No telemetry, no other external calls.
166
+ - **Shell / native**: none. No `child_process`, no native modules, no dynamically downloaded binaries.
167
+ - **HTTP surface**: only `/dsh-any-background/{video,wallpaper,font}` (GET/HEAD streaming) with the matching `*/upload` POST routes (100 MB cap), plus the dedicated RPC channel `/dsh-any-background`, all under the local dsh web server. No extra listening ports.
168
+ - **Restart required**: the first install needs a (re)start of `dsh web` to load the client bundle; settings changes afterwards apply live and persist automatically. Changing plugin version requires a restart to pick up the new `lib/client.js`.
169
+ - **Tests & verification**: `pnpm run typecheck` (full tsc check), `pnpm run bundle` (tsdown emits `lib/`), and `npm test`, which starts the real host half and round-trips config writes, reads and profiles plus the upload fence. Visual changes go through two further paths: a local mock page that measures computed values, and real `dsh web` testing slider by slider.
170
+ - **Known limitations**:
171
+ - The styling relies on stable host DOM markers (such as `[data-sidebar-right-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.
172
+ - `-webkit-text-stroke` may clip about 1px at the edge of some single-line ellipsis containers.
173
+ - One rule is a deliberate cross-plugin accommodation: dsh-better-display paints its sticky reading lanes from the token our 「主界面」 opacity owns, so when that plugin is detected its lanes are pinned at a 20% plate + 30px frost outside the sliders. If it ever renames those markers the rule stops matching and its lanes go back to being painted its own way.
166
174
 
167
175
  ## Star History
168
176
 
package/README.zh.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <a href="https://www.npmjs.com/package/dsh-any-background"><img alt="npm 版本" src="https://img.shields.io/npm/v/dsh-any-background?color=4d6bfe"></a>
5
5
  <a href="https://www.npmjs.com/package/dsh-any-background"><img alt="npm 月下载量" src="https://img.shields.io/npm/dm/dsh-any-background?color=4d6bfe"></a>
6
6
  <a href="https://github.com/Tkingxiao/dsh-any-background/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/npm/l/dsh-any-background?color=4d6bfe"></a>
7
- <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本:0.2.0-rc.1 ~ 0.2.1-rc.3 及其上" src="https://img.shields.io/badge/DSH-0.2.0--rc.1%20~%200.2.1--rc.3%2B-4d6bfe" /></a>
7
+ <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本:0.2.0-rc.1 ~ 0.2.2-alpha.2 及其上" src="https://img.shields.io/badge/DSH-0.2.0--rc.1%20~%200.2.2--alpha.2%2B-4d6bfe" /></a>
8
8
  <a href="https://github.com/topics/dsh-better-sidebar"><img alt="插件生态:GitHub topic dsh-better-sidebar" src="https://img.shields.io/badge/%E6%8F%92%E4%BB%B6%E7%94%9F%E6%80%81-topic%20dsh--better--sidebar-4d6bfe" /></a><br /><br />
9
9
  <a href="https://github.com/Tkingxiao/dsh-any-background"><img src="https://img.shields.io/github/stars/Tkingxiao/dsh-any-background?style=social" alt="GitHub stars"></a>
10
10
  <a href="https://dsh.directory/plugins/tkingxiao/dsh-any-background"><img src="https://dsh.directory/badges/listed.svg" alt="dsh.directory listed"></a>
@@ -12,83 +12,72 @@
12
12
 
13
13
  [English](README.md) | 中文
14
14
 
15
- 一个 **DeepSeek Harness** 外观插件:自定义主题色、背景壁纸(图片 / 视频 / 算法动态生成),以及逐表面的透明度与模糊度控制。兼容 **DSH `0.2.0-rc.1` 直至 `0.2.1-rc.3`,其上所有版本一并放行**(官方右侧栏「主题」卡片等界面按宿主是否提供右侧栏注册表扩展点自动启用,缺失时静默跳过)。
15
+ 一个 **DeepSeek Harness** 外观插件:自定义主题色、背景壁纸(图片 / 视频 / 算法生成),以及逐表面的透明度与模糊度控制。兼容 **DSH `0.2.0-rc.1` 直至 `0.2.1-rc.3`,其上所有版本一并放行**。
16
16
 
17
17
  ---
18
18
 
19
19
  ## 截图
20
20
 
21
- <p align="center">
22
- <img src="example_img/image.png" alt="自定义主页" width="720">
23
- <br/>
24
- <em>自定义主页 · 壁纸与主题色同时生效</em>
25
- </p>
21
+ <table>
22
+ <tr>
23
+ <td align="center"><img src="example_img/image.png" width="440" alt="自定义主页"><br/><em>自定义主页 · 壁纸与主题色同时生效</em></td>
24
+ <td align="center"><img src="example_img/image-2.png" width="440" alt="主题色选择器"><br/><em>主题色选择器 · PS 风格色轮 + HSL/RGB 输入</em></td>
25
+ </tr>
26
+ <tr>
27
+ <td align="center"><img src="example_img/image-3.png" width="440" alt="分部位透明度与模糊度"><br/><em>分部位透明度与模糊度</em></td>
28
+ <td align="center"><img src="example_img/image-4.png" width="440" alt="背景编辑器"><br/><em>背景编辑器 · 平移与缩放</em></td>
29
+ </tr>
30
+ <tr>
31
+ <td align="center"><img src="example_img/image-6.png" width="440" alt="动态生成背景"><br/><em>动态生成背景 · 网格渐变 / Shader / 几何</em></td>
32
+ <td align="center"><img src="example_img/image-9.png" width="440" alt="几何背景低多边形模式"><br/><em>动态生成背景 · 几何低多边形</em></td>
33
+ </tr>
34
+ <tr>
35
+ <td align="center" colspan="2"><img src="example_img/image-10.png" width="440" alt="配置导出导入"><br/><em>配置的导出与导入,方便分享</em></td>
36
+ </tr>
37
+ </table>
26
38
 
27
- <p align="center">
28
- <img src="example_img/image-2.png" alt="主题色选择器" width="720">
29
- <br/>
30
- <em>主题色选择器 · PS 风格色轮 + 精确 HSL/RGB 输入</em>
31
- </p>
39
+ ## 功能特性
32
40
 
33
- <p align="center">
34
- <img src="example_img/image-3.png" alt="分部位透明度与模糊度" width="720">
35
- <br/>
36
- <em>分部位透明度与模糊度 · 主背景、侧边栏、卡片、设置面板</em>
37
- </p>
41
+ ### 色彩与主题
38
42
 
39
- <p align="center">
40
- <img src="example_img/image-4.png" alt="背景编辑器" width="720">
41
- <br/>
42
- <em>背景编辑器 · 图片/视频壁纸支持拖动平移与滚轮缩放</em>
43
- </p>
43
+ - **PS 风格色轮** — 色环取色相、内嵌方形调饱和度与明度,实时生成 30+ 个 CSS 设计令牌。
44
+ - **精确 HSL / RGB 输入** — 数值输入,与色轮双向同步。
45
+ - **智能取色 / 吸管取色** — 一键从壁纸提取主题色(采样可见区域、剔除灰色与近黑近白),或在壁纸上悬停取任意一点;视频壁纸自动截帧参与。全程在客户端完成。
46
+ - **强制界面明暗** — 亮 / 暗 / 自动。「自动」下表面与字体方向由主题色明度决定(深色 → 浅字,浅色 → 深字),未选主题色时按壁纸亮度判断。
47
+ - **主题导出 / 导入** — 一键导出自包含的 `dsh-any-theme.json`(配置 + 壁纸 + 整个轮换池),随时导入还原。
48
+ - **外观预设与档案** — 六套一键预设,外加可重命名、可复制的自定义档案;删除有二次确认。
44
49
 
45
- <p align="center">
46
- <img src="example_img/image-6.png" alt="动态生成背景" width="720">
47
- <br/>
48
- <em>动态生成背景 · 网格渐变 / Shader / 几何图案预设</em>
49
- </p>
50
+ ### 背景与壁纸
50
51
 
51
- <p align="center">
52
- <img src="example_img/image-9.png" alt="几何背景 低多边形模式" width="720">
53
- <br/>
54
- <em>动态生成背景 · 几何 低多边形模式预览</em>
55
- </p>
52
+ - **图片壁纸** — 上传任意图片作为背景。
53
+ - **视频壁纸** — 静音循环播放,刷新不丢失(落盘持久化 + HTTP Range 流式播放),并自动截取一帧用于预览、取色与位置编辑。
54
+ - **位置编辑器与布局模式** — 拖动平移、滚轮或双指缩放、一键重置;适应 / 填充 / 拉伸 / 平铺 / 居中,图片与视频的位置各存各的,互不覆盖。
55
+ - **动态生成背景** — 网格渐变 / Shader / 几何图案,可调扩散范围与色彩强度、锁定种子。
56
+ - **壁纸轮换** — 缩略图选择器组池,按随机或顺序、每次刷新 / 每小时 / 每天 / 每周更换;页面开着也会按时推进。
57
+ - **昼夜自动切换** — 指定日间与夜间两套配置,按固定时段或跟随系统深色模式自动切换。
56
58
 
57
- <p align="center">
58
- <img src="example_img/image-10.png" alt="配置导出导入" width="720">
59
- <br/>
60
- <em>配置的导出和导入进行分享</em>
61
- </p>
59
+ ### 逐表面的透明度与模糊
62
60
 
63
- ## 功能特性
61
+ - **十一个部件各自一对滑块** — 主背景、侧边栏、卡片面板、输入框与控件、设置面板、对话文本框、轨迹页、右方侧边栏(或 bettersidebar)、产出物 / 高亮内容、顶栏浮层、标题栏。
62
+ - **滑块就是磨砂量,0 就是没有磨砂** — 会盖掉宿主默认的菜单磨砂;每个部件的**默认值仍是 30px**,所以全新安装保持宿主的磨砂观感。
63
+ - **透明度改的是宿主令牌本身** — 不在原色上再叠一层新色,壁纸从内容后方透出来。
64
+ - **产出物 / 高亮内容共用一支滑块** — 代码块(含语言顶栏)、行内 `code` 芯片与产出物 chip 同步。
65
+ - **右方侧边栏 / bettersidebar 同一对滑块两种身份** — 未装 dsh-better-sidebar 时驱动官方右侧栏,装了之后接管它的底部工作台面板(官方侧栏同样生效)。
66
+ - **桌面壳(Windows)还管标题条带** — 「侧栏」那对滑块同时驱动侧栏正上方的条带分段,切口随侧栏宽度拖动与折叠跟进(宽度 0 时整条交还「标题栏」);「标题栏」卡片驱动其余分段与原生按钮区,并提供「标题条带文字」四态(自动 / 跟随主题 / 始终白 / 始终黑)供条带发浅时裁定文字颜色。
64
67
 
65
- - **PS 风格色轮** — 在色相环上选取色相,在内嵌方形中调整饱和度与明度,实时生成 30+ 个 CSS 设计令牌。
66
- - **精确 HSL / RGB 输入** — 通过数值精确输入颜色,与色轮实时双向同步。
67
- - **智能取色** — 一键从壁纸提取主题色:采样可见区域、量化像素、剔除灰色/近黑/近白,选出现量最大的鲜亮色。视频壁纸自动截帧参与取色。纯客户端完成。
68
- - **吸管取色** — 在壁纸上悬停预览颜色,点击即可选为主题色。
69
- - **背景壁纸** — 上传任意图片作为壁纸,在视口比例的编辑器中拖动平移、滚轮缩放(触屏上单指拖动、双指捏合缩放)。
70
- - **视频壁纸** — 上传视频作为动态壁纸:静音循环播放、刷新不丢失(落盘持久化 + HTTP 流式播放,支持 Range seek);自动截取一帧用于预览、主题色提取与位置编辑参考。
71
- - **位置编辑器** — 图片与视频共用同一套编辑器:拖动平移、滚轮或双指缩放、一键重置;图片与视频的位置状态各自独立保存,互不覆盖。
72
- - **布局模式** — 适应 / 填充 / 拉伸 / 平铺 / 居中五种排布,图片与视频通用;「适应」模式下编辑器提交的构图在窗口缩放、跨屏移动后保持一致。
73
- - **动态生成背景** — 支持网格渐变、Shader、几何图案,可调节扩散范围、色彩强度并锁定种子。
74
- - **分部位界面透明度** — 主背景、侧边栏、卡片面板(含对话框周围的选项框/菜单)、输入框与控件(发送框、Cordis 插件面板)、设置面板、对话文本框、轨迹页、右方侧边栏(或 bettersidebar)、产出物/高亮内容、顶栏选项(Agent Team 面板、后台任务列表与会话头部下拉菜单),以及标题栏(会话顶部那条标题行 + 视图页签)各自独立滑块。
75
- - **分部位界面模糊度** — 每个界面部位可独立调整毛玻璃 `backdrop-filter` 模糊(0–60 px),并通过宿主的稳定选择器为发送框、Cordis 面板与弹出层提供真实背景模糊。滑块就是该表面的磨砂量,**0 就是没有磨砂**——包括盖掉宿主默认的 `--dsw-menu-backdrop-filter: blur(40px) saturate(150%)`。0.3.7 曾把 0 解释成「保留宿主自己的磨砂」,结果滑块的下端反而是最糊的一端(0 = 宿主的 40px,1 = 1px),「把模糊关掉」根本够不着;现在 0 就是 0,而各部件的**默认值仍是 30px**,所以全新安装照旧是磨砂的,只有明确拖到 0 才会清掉。
76
- - **左侧栏 + 它上方的标题条带** — 桌面壳(Windows)上,「侧栏」这对滑块现在同时驱动侧栏列,以及那条压在侧栏正上方的窗口标题条带分段。宿主把整条条带画成一个全宽的盒子(`.frame::before`),而宿主自己就把侧栏列宽发在帧元素上(`--dsh-windows-sidebar-width`);插件就按这个宽度切开条带:`::before` 被裁到该宽度右侧(继续保留「标题栏」卡片的材质、模糊与拖拽区),新增的 `::after` 用 `--dsh-any-op-sidebar`——也就是侧栏列本身用的那份颜色——画出左侧那段,并按侧栏模糊的根级镜像上霜。于是一对滑块管住侧栏与它上方那一条,拖动或折叠侧栏时切口跟着移动(宽度 `0px` 时整条条带重新归「标题栏」)。这个切分是有意的(issue #29 第 3 条):左段本就是侧栏列自己的表面,标题栏滑块不该够到它。
77
- - **产出物 / 高亮内容** — 对话正文里的代码块(含语言顶栏)、行内 `code` 高亮芯片与产出物 chip 共用一支滑块:透明度只**调制这些表面原本的背景色**(不会在旧背景上再叠一层新色),模糊度给同一层表面加磨砂,壁纸从内容后方透出来。
78
- - **右方侧边栏 / bettersidebar 表面** — 同一对滑块(`panelOpacity` / `blurs.panel`)按宿主环境自动切换目标:未安装 dsh-better-sidebar 时叫「右方侧边栏」,驱动官方右侧栏的表面令牌与毛玻璃模糊(范围内每个 release 均适用);安装了 dsh-better-sidebar 时改叫「bettersidebar」,接管其底部工作台面板(官方右侧栏同样生效)。该行现在始终显示。
79
- - **顶栏选项** — 会话头部的下拉浮层获得了独立的透明度 + 模糊滑块:Agent Team 面板、后台任务列表、「用其它应用打开」与「会话日志」菜单、子代理血缘树。由于这些浮层被 portal 到 `<body>`(与头部 DOM 断开),且 0.1.7 把「用其它应用打开」改成 portal、把会话行菜单改成动态槽位,插件改为在运行时监听稳定的 `conversation.session.header*` 槽位锚点来标记当前展开的浮层,不再依赖类名形状。浮层算不算头部的判据是「portal 到了 `<body>`,**或者**就在这些锚点里面」——「会话日志」的 `…` 菜单属于后一种(`session-log-export/HeaderAction.tsx` 渲染它的 `Menu` 时不带 `portal`),而在 0.3.9 之前能碰到它的只有一条按 `_denseList` 类名匹配的脆弱分支。
80
- - **标题栏(会话标题行)** — 会话顶部那条标题 / 操作 / 视图页签行终于有了自己的一对滑块。宿主自身不给它任何底色(中心列的底色直接透上来),所以壁纸一起来,标题与页签就直接压在图上、和周围被蒙住的表面割裂。现在它按「区块淡色」作画,配方与对话文本框那张卡一致:材质取插件主背景面的颜色、按本部件自己的透明度上色,读起来是压在列上的一条带,而不是叠上去的第二层颜色;模糊落在行前的一块 `::before` 垫层上(配合 `isolation:isolate`——它是层叠上下文,但**不是** backdrop root;0.3.8 之前霜直接压在行身上,而行一旦带上 `backdrop-filter` 就成了 backdrop root,恰恰把挂在行里的那些浮层的磨砂压成一片平色);而这道霜仍然把行变成层叠上下文,所以行同时带上补偿性的 `z-index:10`——行内挂出的浮层(直到 `0.2.1-alpha.1` 的后台任务列表、每个 release 上都可能就地的日程任务菜单与「会话日志」`…` 菜单)本来用 `z-index:100`,否则会被关在行里、压到对话之下。10 高于它会重叠到的列内部件(输入位 9、回到底部 8),又远低于所有页面级表面(100 / 1000 / 1100),因此打开菜单时这一条的颜色和模糊都不会变;`z-index` 无需 `position`——该行本是 flex 子项,`z-index` 天然生效,而垫层要用的 `position:relative` 只在模糊非 0、且宿主把这一行留在 static 时才以内联方式写入。详见 v0.3.7 / v0.3.9。Windows 上它驱动的条带与侧栏分段(见上一条);模态打开时条带会跟着宿主蒙版自行变暗(宿主蒙版故意停在标题区下方);生成出来的那一段只负责绘制——`pointer-events:none` 且不声明 app-region——因此不会吞掉本该给原生标题栏菜单的点击(issue #29)。它还画在控件之下(`z-index:-1`),并自带墨色(`--dsh-any-caption-ink`):即使侧栏透明度很低、条带发浅,开合按钮与「应用 / 编辑」菜单也清楚可读;而当条带的明暗与主题方向冲突时,由「标题条带文字」裁定谁获胜——「自动」沿用条带推导,「跟随主题」完全不写覆盖(回到宿主的标签墨色,即 0.3.7 及之前),「始终白色 / 始终黑色」直接钉死(issue #30)。这一行是**运行时认领**的:插件从 `conversation.session.header*` 槽位锚点向上找到最近的那个 `<header>` 再打上自己的类(与卡片、帧同款做法),不猜哈希类名、也不依赖宿主把槽位摆在哪个层级;`0.1.7-alpha.1` 之前宿主把槽位裸挂在会话根上、没有这一行元素,那种宿主上插件什么都不会认领,部件自然无效果。桌面壳(Windows)上这一对滑块同时驱动窗口标题条带——**但左侧栏正上方的那一段除外**,那一段归「侧栏」这对滑块管(见下条);原生最小化/最大化/关闭那块改由取色探针报 `transparent`,让 Windows 不画自己的背景,露出的正是条带本身。空会话时宿主把该行标为 `headerBlank`(一条只留 padding 的占位),插件跳过认领。
81
- - **侧边栏「主题」页面(双模式)** — 同一套五页(色彩 / 界面 / 字体 / 背景 / 配置)注册到两处:未安装 dsh-better-sidebar 时,通过官方右侧栏的公开扩展点(`sidebarRightTabs` + `sidebar.right.pane.tab`)在**官方侧边栏**的引导页挂一张「主题」卡片,点开即五页;安装了 dsh-better-sidebar 时,改为在它的侧边栏注册同名页面,官方引导页上的卡片自动撤下,避免重复。两处(加设置面板共三处)共用同一套页面代码与同一份状态,改一处处处同步;外壳按面板宽度自适应,窄面板收紧内边距并回到单列。宿主没有右侧栏扩展点时静默不注册,不影响任何其它功能。
82
- - **对话视图卡片** — 消息列表自动包裹为半透明卡片,轨迹页可整页调节透明度与模糊,让壁纸从内容后方透出来。
83
- - **主题导出 / 导入** — 一键导出为自包含的 `dsh-any-theme.json`(配置 + 壁纸,视频以 data URL 内嵌,v0.4.0 起连同整个轮换池的图片字节),可随时导入还原。
84
- - **外观预设与配置档案** — 六套一键预设(默认 / 毛玻璃 / 极简白 / 暗夜紫 / 赛博 / 暖阳),外加自定义命名档案:随时保存当前观感、随时套回,支持重命名与复制,删除有二次确认保护。
85
- - **壁纸轮换** — 把多张图片加入轮换池(缩略图选择器),按随机或顺序、每次刷新 / 每小时 / 每天 / 每周的频率自动更换,页面开着也会按时推进(不再只在刷新时更换);切换时服务端把所选图片复制进当前壁纸槽,导出/导入与取色管线完全不用改。
86
- - **昼夜自动切换** — 指定日间与夜间两套配置,按固定时段或跟随系统深色模式自动切换。
87
- - **自定义字体** — 上传一个 ttf / otf / woff / woff2 字体文件(上限 100 MB),通过 `@font-face` 应用到整个界面的文字;可随时停用或移除。字体按原始字节流式上传并持久化到插件数据目录,代码块仍保持等宽字体。
88
- - **分组文字描边** — 沿用界面页的分组(现为十一组,含顶栏选项与标题栏),为每个分组单独加 `-webkit-text-stroke` 描边:粗细 0–4 px(0 = 关闭),颜色支持自动反色 / 灰 / 黑 / 白 / 主题色 / 自定义。代码块、`inline code`、图标,以及宿主那类 `background-clip: text` 的流光文字(「深度求索中」状态行与轮次过程行)自动豁免——多色语法不会糊成一团,渐变文字也不会被描边压成一坨纯色。
89
- - **强制界面明暗** — 无论主题色明暗如何,都能强制生成亮色/暗色整套令牌;「自动」下配色与字体方向由主题色明度驱动(深色 → 浅字,浅色 → 深字),未选主题色时按壁纸画面亮度判断。
90
- - **文件持久化** — 所有设置保存到文件系统 `~/.dsh/.dsh-any-background-data/`,不再依赖 `localStorage`。
91
- - **中英双语** — 完整的中英文界面,自动跟随语言设置。
68
+ ### 界面部件
69
+
70
+ - **侧边栏「主题」页面(双模式)** — 同一套五页(色彩 / 界面 / 字体 / 背景 / 配置)注册到官方右侧栏引导页或 dsh-better-sidebar 的侧栏,与设置面板三处共用一份状态,改一处处处同步;宿主没有该扩展点时静默不注册。
71
+ - **对话视图卡片** — 消息列表自动包成半透明卡片,轨迹页可整页调节。
72
+ - **顶栏浮层与标题栏各自可调** — Agent Team 面板、后台任务列表、会话头部下拉菜单,以及会话顶部那条标题 / 页签行,都有独立的透明度 + 模糊。
73
+ - **自定义字体** — 上传 ttf / otf / woff / woff2(上限 100 MB)应用到整个界面,代码块保持等宽;可随时停用或移除。
74
+ - **分组文字描边** — 与界面页同一套分组,每组独立 `-webkit-text-stroke`(0–4px,0 = 关闭),颜色可自动反色 / 灰 / 黑 / 白 / 主题色 / 自定义;代码块、`inline code`、图标与宿主的流光文字自动豁免。
75
+ - **第三方插件兼容** — 认出 [dsh-better-display](https://github.com/aa2246740/dsh-better-display) 时把它那条吸顶总结栏钉在 20% 底板 + 30px 磨砂、不随滑块;其它插件的表面若吃了本插件接管的令牌会在控制台点名,设置页可以整体关掉。
76
+
77
+ ### 其它
78
+
79
+ - **文件持久化** — 所有设置落盘在 `~/.dsh/.dsh-any-background-data/`,不依赖 `localStorage`。
80
+ - **中英双语界面** — 自动跟随宿主语言设置。
92
81
  - **主题守护** — 宿主重置主题后自动重新激活自定义主题。
93
82
 
94
83
  ## 更新日志(只保留最近两个版本)
@@ -100,9 +89,14 @@
100
89
  - **修掉 issue #32。** 被磨砂的侧栏列提到 `z-index:1`,提示条悬出侧栏右缘的那一段重新清晰;模态豁免里 `z-index` 与 `isolation` 同进同退。
101
90
  - 装完或更新后请**重启一次宿主**——兼容门禁在组装 profile 时才跑。
102
91
 
103
- ### v0.4.1(修掉「每次刷新」档位每 30 秒自动换图)
92
+ ### v0.4.3(跟到 dsh `0.2.1-rc.5` 与新开的 `0.2.2` 线)
104
93
 
105
- - 只有时间档位(每小时 / 每天 / 每周)参与定时推进;「每次刷新」回到原本语义:每次页面加载换一张,外加手动「换一张」按钮。
94
+ - **新增核对的宿主构建**:`0.2.1-rc.4`、`0.2.1-rc.5`、`0.2.2-alpha.2`。
95
+ - **`rc.4` / `rc.5` 不改动任何东西。** 把 rc.3 装机目录里 296 个 `@deepseek-ai/dsh-*` 包、5604 个产物文件逐个取哈希:跨到 rc.5 只有 30 个文件变过,且没有一个是本插件读的那张样式表——三处只是内联的版本号字符串,其余是宿主设置页标签的提示条改成按需弹出、以及思考过程正文插槽多传一个 `rawText`。令牌、`[class*="…"]` 类形状、`z-index`、`data-slot` 一个都没动,于是两个构建并入 `v0-2-1` 的档位,判定从 `line` 升为 `exact`。
96
+ - **`0.2.2` 是一条新补丁线,另开 `v0-2-2` 事实目录。** 这一版动静大(1151 个文件改动、1709 个新增),但本插件声称的每一项事实逐条重读后仍然成立:`_handle{z-index:11}` / `_leadingSeat{z-index:15}` / `_overlayLayer{z-index:20}` 逐字节一致(所以侧栏列 `z-index:1` 的上限和标题行 `z-10` 的论证照旧),菜单霜的四个令牌与 8 个 `--dsw-menu-backdrop-filter` 消费者不变,宿主仍在 `body` 上合成 `--dsw-font-family`(字体规则的 `!important` 仍须胜出),5 个会话头部插槽键不变;本插件写到的 75 个宿主选择器全部还能命中。宿主侧的 peer 门禁实现逐字节未变。
97
+ - **`0.2.2` 上两处值得记下的宿主改动**:`--dsw-specific-sidebar-nav-item-hover` 被宿主删掉了(连它唯一的消费者一起),本插件仍会写这个令牌——写了没人读,且宿主自己本来也不再画那个悬停底色,相对宿主默认观感没有退步;`ui-plugin-manager` 新增一处用「主界面」接管的那个令牌做底板(页面头部一条 `pointer-events:none` 的垫层),默认值下什么都不画,但这是「谁在读这个令牌」清单上新增的一行。
98
+ - **兼容门禁新增一致性自检**:`npm test` 现在会核对 `engines.dsh`、六条 peer、`dsh.compatibility.dsh` 四处是否点名了每一个已核对构建、是否都留着不设上界的尾巴,并核对 `lib/` 里确实带着这些构建与对应的渠道(改了 `src/` 忘了重新 bundle 会被直接抓住)。
99
+ - 装完或更新后请**重启一次宿主**——兼容门禁在组装 profile 时才跑。
106
100
 
107
101
  ## 安装
108
102
 
@@ -146,19 +140,37 @@ pnpm dsh web
146
140
 
147
141
  ## 兼容性
148
142
 
149
- - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) `0.2.0-rc.1` ~ `0.2.1-rc.3`,其上所有版本一并放行** — `engines.dsh`、受门禁的 `@deepseek-ai/dsh-*` `peerDependencies` 与 `dsh.compatibility.dsh` 先逐一列出本插件核对过的构建(`0.2.0-rc.1`、`0.2.0-rc.2`、`0.2.1-alpha.1` … `0.2.1-rc.3`),再以不设上界的 `>=0.2.0-rc.1` 收尾,让其后每一个 release 都能加载。不设上界是有意选的:宿主强制的正是这份 peer 列表——范围没写到的版本会在导入任何模块之前被整行禁用——一条写到头的范围等于在一款还能正常工作的插件前面砌墙。没见过的 release 会取最近的一份事实,并在日志里写清它离 `exact` 有多远;一份过期事实最坏的代价是某个滑块不再淡出宿主已经搬走的那个表面,而一道失败关闭的版本检查代价是整个插件。`dsh.compatibility.dshReleases` 记录哪些构建被核对过、怎么核对的:列表里的每个 release 都是按 tag 逐包比对其事实目录核实的。这道门禁也意味着安装或更新插件后仍需重启 `dsh web`——检查发生在 profile 组装时,而不是插件更新时——但不设上界的总括,正让已经升到更新宿主的机器不再需要先等插件发版(或手工授予精确版本豁免 `dsh plugin allow-version`)。宿主版本在运行时由 Node 半侧解析,依赖特定宿主版本渠道的功能(右侧栏面板模糊、官方侧栏「主题」卡片)只在对应宿主结构存在时启用,其余功能在整个范围内表现一致。**`0.1.5` / `0.1.6` / `0.1.7` 这一档已移出兼容范围**:那些事实目录断言的东西已经没有再被核对,而一张没人核对的表比没有表更糟;范围从 `0.2.0-rc.1` 起步,意味着更旧的宿主会在组装期被明确拒绝,而不是被一份错的适配事实悄悄改版式。
150
- - **版本适配隔离**:release 由 Node 半侧从进程自身那份 `@deepseek-ai/dsh/package.json` 读出(客户端上下文不暴露版本;`ctx.profileContext.installAnchor` 指不到时退回启动器的磁盘布局),经 `read` RPC 下发后只由前置适配层路由——`src/host-compat/` 负责探测与渠道归类,`src/client/host-compat/versions/` 下**每个事实集合一个目录**(`v0-2-0-rc-1` / `v0-2-0-rc-2` / `v0-2-1` / `unknown`),各自描述该版本的面板力学、头部槽位键、插件页形状,以及菜单的底色与磨砂落在哪一层。目录按它覆盖的事实命名,不按版本号的形状:`0.2.0-rc.1` 与 `0.2.0-rc.2` 同属一个预发布渠道,但 rc.2 改了吸顶菜单分组标题取色的令牌,于是这条补丁行上并着两个目录,较新的那个按开启它的那个构建命名。**事实没变的更新版本不新开目录,而是并入那份仍然成立的事实目录**——整条 `0.2.1` 线(`alpha.1` … `rc.3`)正因如此都坐在 `v0-2-1` 里,每个核对过的构建各占一条 `SUPPORTED_RELEASES` 行,判定都是 `exact` 而不是 `line`。底码只向适配层提问(引导页表面归谁、模糊挂在哪一层、菜单该重写哪些令牌),不比较版本字符串。同一补丁行内的其它构建(将来的 `0.2.1-rc.4` 之于核对基准 `rc.3`)用该行的档位;整条补丁行都不在已核对范围内才收边取最近的一档并写日志——`0.2.1-rc.3` 之上的每一个 release 如今就是靠这一档加载的。只有解析不到 release 时归入 `unknown`,回退到按 DOM 形状探测(`:has()` 双臂)而不是猜一个版本;适配新宿主 = 新增一个版本目录并在注册表登记。
151
- - **[DSHA](https://github.com/DSH-APP/DSHA)** — DeepSeek Harness 安卓启动器(免 ROOT、免 Termux)。其包内 dsh 为 `0.1.5-rc.2`,自 v0.3.7 起**低于本插件的兼容下界**:peer 门禁会在组装期拒绝它,所以插件在那上面根本不加载,而不是拿 0.2.x 的事实去改版那个壳。
143
+ - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness):`0.2.0-rc.1` ~ `0.2.2-alpha.2`,其上所有版本一并放行。** 门禁先逐一列出核对过的构建,再以不设上界的 `>=0.2.0-rc.1` 收尾。这是有意的:宿主强制的正是这份 peer 列表,范围没写到的版本会在导入任何模块之前被整行禁用——一条写到头的范围等于在一款还能工作的插件前面砌墙。(更准确地说:宿主 `app-boot` 的 `unmetRequirements` 在 `engines.dsh` 存在时只看它自己、忽略 peer,所以四处都要写、但真正决定加载的是 `engines.dsh`。)
144
+ - **没见过的构建怎么跑**:取最近的一份事实,并在日志里写清它离 `exact` 有多远。一份过期事实最坏的代价是某个滑块不再淡出宿主已经搬走的那个表面,而一道失败关闭的版本检查代价是整个插件。
145
+ - **核对过的构建**(`dsh.compatibility.dshReleases`):
146
+
147
+ | 宿主构建 | 事实目录 | 说明 |
148
+ |---|---|---|
149
+ | `0.2.0-rc.1` | `v0-2-0-rc-1` | 按 tag 逐包 diff 核实 |
150
+ | `0.2.0-rc.2` | `v0-2-0-rc-2` | 同上;这一版改了吸顶菜单分组标题取色的令牌,所以另开一份事实 |
151
+ | `0.2.1-alpha.1` ~ `0.2.1-rc.5` | `v0-2-1` | 事实未变,并入同一份;每个核对过的构建各占一行,判定为 `exact`。`rc.4` / `rc.5` 的产物与 `rc.3` 逐个文件哈希一致 |
152
+ | `0.2.2-alpha.2` | `v0-2-2` | 新开的补丁线,另开一份事实;逐条重读后答案与 `v0-2-1` 相同(层级阶梯、菜单霜令牌、字体令牌、头部插槽键、75 个宿主选择器命中) |
153
+ | `0.2.2-alpha.2` 之上 | 沿用该行最近的核对结果 | 未核对的新构建取档位并写日志 |
154
+
155
+ - **版本事实按 release 隔离**:宿主版本由 Node 半侧解析、随 `read` RPC 下发,样式与逻辑只向适配层提问(这块表面归谁、磨砂挂在哪一层、菜单该重写哪些令牌),不比较版本字符串;适配新宿主 = 新增一个版本目录并在注册表登记。
156
+ - **安装或更新插件后仍需重启宿主**:兼容检查发生在组装 profile 时,而不是插件更新时。依赖特定宿主结构的功能(右侧栏面板模糊、官方侧栏「主题」卡片)只在对应宿主上启用,其余功能在整个范围内表现一致。
157
+ - **`0.1.5` / `0.1.6` / `0.1.7` 已移出兼容范围**:那些事实目录断言的东西再没有核对过,而一张没人核对的表比没有表更糟;更旧的宿主会在组装期被明确拒绝,而不是被一份错的适配事实悄悄改版式。
158
+ - **[DSHA](https://github.com/DSH-APP/DSHA)** — DeepSeek Harness 安卓启动器(免 ROOT、免 Termux)。包内 dsh 为 `0.1.5-rc.2`,低于本插件的兼容下界:peer 门禁会在组装期拒绝它,插件在那上面根本不加载。
159
+ - **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — 支持。Windows 专属行为(标题条带、原生按钮区)只在桌面壳上生效。
160
+
152
161
  ## 权限、副作用与边界
153
162
 
154
- - **接入形态**:官方 Profile Bundle——`package.json` 声明 `dsh.bundle.patch: ./cordis.patch.yml`(loader 插入层),仓库提交可直接使用的预构建运行时制品(`lib/index.js`、`lib/client.js`),无安装脚本、无 postinstall、无 native 二进制、安装时不执行任何构建。
155
- - **文件系统**:服务端仅在 `<dsh 主目录>/.dsh-any-background-data/` 内读写(配置 JSON、壁纸、轮换池、视频、字体),不触碰该目录之外的任何路径;配置写入为原子写(临时文件 + rename)。这些文件落在真实磁盘上,**不受 generation 恢复影响,也不会被其回滚**——清除它们即彻底重置插件。
156
- - **网络**:仅在用户主动粘贴 http/https 图片或视频网址并点击「应用」时发起一次出站请求下载该资源;除此之外无遥测、无外部服务调用。
157
- - **Shell / native**:无。不使用 `child_process`、不加载 native 模块、不运行动态下载的二进制。
158
- - **HTTP 面**:仅在本机 dsh web 服务下注册 `/dsh-any-background/{video,wallpaper,font}`(GET/HEAD 流式服务)与对应 `*/upload`(POST,上限 100 MB)及专用 RPC 通道 `/dsh-any-background`;无新增对外监听端口。
159
- - **是否需要重启**:首次安装后需(重新)启动 `dsh web` 加载客户端 bundle;此后的设置变更实时生效、自动落盘。更换插件版本后需重启以加载新的 `lib/client.js`。
160
- - **测试与验证**:`pnpm run typecheck`(tsc 全量类型检查)与 `pnpm run bundle`(tsdown 产出 `lib/`);无自动化单测,接口行为以手动验证为准。
161
- - **已知限制**:依赖宿主 DOM 结构的稳定标记(如 `[data-sidebar-right-panel]`、`[data-dsh-bottom-panel]`)与 CSS 令牌名,宿主大版本重构样式层时选择器可能失效(表现为相关滑块不再作用于对应表面,不影响稳定性);版本相关的那部分选择器集中在对应的版本目录里,宿主改版通常只需改那一份;`-webkit-text-stroke` 在部分单行省略号容器边缘约有 1px 裁切。另有一条规则是对其它插件的有意让步:dsh-better-display 的吸顶车道用的正是「主界面」透明度接管的那个令牌,所以认出该插件后会把它的车道钉在 20% 底板 + 30px 磨砂上、不随滑块;它若改名,这条规则就匹配不到,车道回到它自己的画法。
163
+ - **接入形态**:官方 Profile Bundle——`package.json` 声明 `dsh.bundle.patch: ./cordis.patch.yml`(loader 插入层),仓库直接提交可用的预构建产物(`lib/index.js`、`lib/client.js`)。无安装脚本、无 postinstall、无 native 二进制,安装时不执行任何构建。
164
+ - **文件系统**:服务端只在 `<dsh 主目录>/.dsh-any-background-data/` 内读写(配置、壁纸、轮换池、视频、字体),不触碰该目录之外的任何路径;配置写入为原子写(临时文件 + rename)。这些文件落在真实磁盘上,**不受 generation 恢复影响、也不会被其回滚**——删除该目录即彻底重置插件。
165
+ - **网络**:只有当用户自己粘贴 http/https 图片或视频网址并点击「应用」时才发起一次出站下载;无遥测、无其它外部调用。
166
+ - **Shell / native**:无。不用 `child_process`、不加载 native 模块、不运行动态下载的二进制。
167
+ - **HTTP 面**:只在本机 dsh web 服务下注册 `/dsh-any-background/{video,wallpaper,font}`(GET/HEAD 流式)与对应 `*/upload`(POST,上限 100 MB),以及专用 RPC 通道 `/dsh-any-background`;不新增对外监听端口。
168
+ - **是否需要重启**:首次安装后需(重新)启动 `dsh web` 加载客户端 bundle;此后设置变更实时生效、自动落盘。更换插件版本需重启以加载新的 `lib/client.js`。
169
+ - **测试与验证**:`pnpm run typecheck`(tsc 全量类型检查)、`pnpm run bundle`(tsdown 产出 `lib/`)、`npm test`(起真实宿主半侧,跑「写盘 → 重读 → 档案」往返与上传围栏断言)。视觉类改动另有两条路径:本地 mock 页量 computed 值,以及在真实 `dsh web` 上逐个滑块实测。
170
+ - **已知限制**:
171
+ - 样式依赖宿主 DOM 的稳定标记(如 `[data-sidebar-right-panel]`)与 CSS 令牌名;宿主大版本重构样式层时选择器可能失效,表现为相关滑块不再作用于对应表面(只影响观感,不影响稳定性)。版本相关的那部分选择器集中在对应的版本目录里,宿主改版通常只需改那一份。
172
+ - `-webkit-text-stroke` 在部分单行省略号容器边缘约有 1px 裁切。
173
+ - 有一条规则是对其它插件的有意让步:dsh-better-display 的吸顶车道用的正是「主界面」透明度接管的那个令牌,所以认出该插件后会把它钉在 20% 底板 + 30px 磨砂上、不随滑块;对方若改名,这条规则就匹配不到,车道回到它自己的画法。
162
174
 
163
175
  ## Star History
164
176