dsh-any-background 0.3.2 → 0.3.4

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.1.5-rc.2 ~ &lt;0.2.0" src="https://img.shields.io/badge/DSH-0.1.5--rc.2%20~%20%3C0.2.0-4d6bfe" /></a>
7
+ <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="Supported DSH versions: 0.1.5-rc.2 ~ 0.2.1-alpha.1 and above" src="https://img.shields.io/badge/DSH-0.1.5--rc.2%20~%200.2.1--alpha.1%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,7 +12,7 @@
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.1.5-rc.2 through the whole 0.1.7 line below 0.2.0** (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 fine-grained per-surface opacity & blur controls. Compatible with **DSH 0.1.5-rc.2 through `0.2.1-alpha.1` — 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).
16
16
 
17
17
  ---
18
18
 
@@ -91,44 +91,23 @@ A **DeepSeek Harness** appearance plugin: custom theme color, background wallpap
91
91
 
92
92
  ## Changelog (latest two releases)
93
93
 
94
- ### v0.3.2 (Produced artifacts fully bound, 0.1.7-rc.2 loads again)
95
-
96
- - **The produced slider now covers every artifact 0.1.7 renders**: the tool-details card (`[data-inspect]`, `ToolDetails.module.css`), the turn-event rows (`[data-turn-trigger]`, including their hover fill), the diff block (`[data-diff]`), the changed-files card (`[data-changed-files]` — root, header button and the file-count tile each paint their own token) and inline `code` frost were all driven by the host at full alpha with no binding on our side, so the "产出物/高亮内容" sliders did nothing to them. Each now re-emits its own host token through `color-mix(… var(--dsh-any-prod-pct))` and joins the shared frost (inline `code` excepted under the compact markdown variant, where a frost on hint-sized text only smudges). The outline group lists the same surfaces, so their text no longer keeps inheriting the conversation-frame outline.
97
- - **Code-card banners are themed again instead of a pale slab**: 0.1.7 moved ReadBlock / DiffBlock / CodeBlock onto one shared CodeCard whose header fills from `--dsl-code-block-background` → `--dsw-alias-markdown-code-block`, while `--dsl-code-block-banner-background-color` exists only inside a markdown block. Our banner arm still read the old `--dsw-alias-markdown-code-block-banner` first, which is why a read/diff header stayed an opaque near-white bar that ignored the slider. The arm now follows the host's own chain, and the pre-0.1.7 arm is guarded with `:not([data-code-block-banner])` so the two cannot both claim one element (verified live on an injected 0.1.7 card: at 20% the banner blends with the card, and where the host really does use the banner token — the diff header — the two colors stay distinct).
98
- - **The dsh-better-sidebar workbench belongs to the produced slider now**: `[data-dsh-bottom-panel]` opens the artifact a conversation row points at, so it fades and frosts with the produced surfaces rather than with the panel row, which is now the host's own right Sidebar only. Its alpha cannot ride the in-place re-emit trick — every surface inside it (pane chrome, tab bar, cards) reads a layer token — so the produced slider writes four root variables that re-scope those tokens, the same way the panel row drives the native panel. Both settings pages' labels and icons follow that split.
99
- - **The composer frost no longer leaves a stacking context behind at 0**: the input rule was gated by a `dab-input-frost` class on `<html>` that is dropped when the blur slider returns to 0, so a composer that is not frosted is no longer isolated. Measured live: `isolation` goes `isolate → auto`. The host's own card rule keeps `position: relative` there regardless (`.uV2eYG_card`), and the per-part frost patches position only while its blur is non-zero, so the remaining case where a frosted surface paints above another plugin's in-flow notice is the frost itself, not a leftover — that one needs the specific notice to be exempted by name.
100
- - **The changed-files card answers to one slider now**: its root paints from `--dsw-alias-bg-layer-1`, which is precisely the token the interface "card" (option-panel) opacity re-emits globally on `body`, so the produced `color-mix` was multiplying the produced alpha onto the card alpha and one artifact card obeyed two sliders. The root now reads a produced-slider variable carrying the RAW token (`--dsh-any-prod-layer-1`, written by `applyProduced` from the same source the panel row uses) — verified live: dropping the card alpha to 0.3 leaves the card untouched while the produced alpha still takes it to 0.2.
101
- - **The hover preview window is bound**: hovering a produced artifact opens `ui-primitives/HoverCard`, which portals its card to `document.body` — outside every in-tree re-scope and owned by no slider at all. It joins the produced group's frost, alpha and outline, anchored by the one stable marker that card has: the inline `--dsh-hover-preview-fade` property it always sets. That marker is 0.1.7-only (the card carries no distinguishing attribute on 0.1.5 / 0.1.6), so older hosts simply leave it alone rather than being caught by a `[class$="_card"]` that would also match the composer. Two surfaces sit under that one attribute and they are faded from their own source: the plain card keeps the host's component literal `--dsw-hovercard-bg: #2C2C2E` (dark in both themes by the host's choice), while the `preview` variant repaints from the theme surface `--dsw-alias-bg-layer-1` and so reads the produced slider's raw layer variable — mixing both on the literal turned a light themed preview dark (measured: `rgb(44,44,46)` over a light theme).
102
- - **antd confirm dialogs are no longer claimed as the settings panel**: `SETTINGS_PANEL_SEL` identified the settings modal as "the only `aria-modal` dialog that labels itself with `aria-labelledby`", but the host's antd `Modal` — the 「删除会话」 confirm among others — emits those same three attributes, so the dialog inherited the settings surface color, the settings blur, the whole `--dsw-alias-bg-layer-*` re-scope the panel row writes, and the settings outline group. The selector now additionally requires the hashed `css.panel` class that `ui-settings-general/SettingsRoot.tsx` puts on its own dialog element, which it does identically from `0.1.5-rc.2` through `0.1.7-rc.1`; antd renders `ant-modal-*` hyphenated names that can never contain it. Measured live on the host: the real settings dialog still matches the tightened selector, while a full antd modal subtree (container, close, header, body, footer, both buttons) scores 0 hits across every `dsh-any*` stylesheet — where it matched the loose selector before. Any residual offset of the confirm button is therefore outside this plugin in the current build.
103
- - **`0.1.7-rc.2` loads again, and future 0.1.7 builds load with it**: from rc.1 the host's peer check turns a missing release name into a plugin that never starts, and rc.2 was not in the list (issue #20). All seven `@deepseek-ai/dsh-*` peers, `engines.dsh` and `dsh.compatibility.dsh` now end in `|| 0.1.7-rc.2 || >=0.1.7-alpha.1 <0.2.0-alpha.0`, so the whole 0.1.7 line — and any later 0.1.x — is admitted without another manifest edit. That umbrella has to be written exactly like that: `>=0.1.7` alone matches **no** prerelease build at all (semver only lets a prerelease compete with a comparator that carries the same `[major,minor,patch]` tuple), and the cap must be `<0.2.0-alpha.0` rather than `<0.2.0` for the same reason — the looser cap would let `0.2.0-alpha.1` in. Every verdict was replayed against the host's own `semver` (the 7.8.5 copy inside the rc.1 runtime) with the gate's `{includePrerelease: true}`, and nothing before that tail is left implicit: earlier lines (`0.1.5-rc`, `0.1.6-alpha`) stay enumerated build by build, because an umbrella over a line this plugin has not looked at would declare compatibility it has not checked. Loading is all the manifest decides, though — the adapter table is untouched, so an rc.2 host still resolves through the patch-line rule to the existing 0.1.7 folder (`line`, not `exact`), and the surface drift rc.2's own diff shows (menu fills moving to `--dsw-menu-surface-fill`, the single-file variant of the changed-files card) is a styling follow-up that needs a machine running rc.2 to measure against.
104
-
105
- ### v0.3.1 (Isolated per-version adaptation: one folder per host release)
106
-
107
- - **Front-loaded release detection**: resolving the host release and bucketing its channel now lives in `src/host-compat/` (the Node half reads the release out of the very `@deepseek-ai/dsh/package.json` the process was composed from — `ctx.profileContext.installAnchor` — falling back to the manifest beside the launcher's `homes/<ver>` and then to the directory name; the verdict travels in the `read` RPC payload), with `src/client/host-compat/` receiving it on the client, broadcasting changes, and re-cutting the static stylesheet the moment the verdict lands. Version logic that used to be spread across `src/client/host.ts` and its call sites is consolidated there; that module is gone.
108
- - **One folder per release**: under `src/client/host-compat/versions/`, the `v0-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `unknown` folders each describe that version's panel mechanics (which layer carries the promotion and the blur) and its header slot keys, and `versions/registry.ts` is the plugin's only release → code mapping. Base code only asks the adapter questions (who owns the guide surface, which slot selectors apply) and never compares version strings — supporting a new host means adding a folder and registering it, leaving base code untouched.
109
- - **Release identity is named down to the channel**: an adapter key is no longer a bare patch number like `0.1.5` but "patch line + prerelease channel" — `0.1.5-rc`, `0.1.6-alpha`, `0.1.7-alpha`. Each folder's mechanics were checked tag by tag against a specific channel, so recording `0.1.5-rc.3` and a hypothetical `0.1.5-beta.1` under one key would let an unverified shape inherit a verified conclusion. Folders and adapter ids now name the exact tags behind them (`v0-1-6-alpha-1-2` reporting `0.1.6-alpha.1/alpha.2`), so how far a table reaches is readable without opening it — and where two builds on one line genuinely differ (`leading` header slot and the plugin-manager page only exist from `0.1.6-alpha.2`), the folder carries that prerelease gate itself.
110
- - **Releases outside the verified table take the nearest adapter**: the `SUPPORTED_RELEASES` table in `src/host-compat/channel.ts` (`0.1.5-rc.2` / `0.1.6-alpha.2` / `0.1.7-alpha.2` / `0.1.7-rc.1`, oldest first — one row per build whose facts were checked, so one line may carry two) is matched by PATCH LINE first: a machine on `0.1.6-alpha.4` gets the `0.1.6-alpha` adapter even though verification stopped at `alpha.2`, because the number after the channel is only a build counter on that line — and `0.1.6-beta.1` or a future channel-less `0.1.6` count as the same line too. Only when no verified line covers the patch number does it clamp: newer than the newest → that newest adapter, older than the oldest → the oldest, strictly between two → the LOWER one, since an adapter may only claim what it was verified for. A clamped verdict logs one line saying the host is outside the verified range and which adapter is standing in, so a report against a new host build starts from that fact. Falling into `unknown` — where the DOM arbitrates — is left for the case where no release parses at all (a plain `~/.dsh` install, for instance).
111
- - **`0.1.7-rc.1` joins the verified range without an adapter change**: diffed against `0.1.7-alpha.2`, every anchor this plugin matches is still emitted where it was, so the 0.1.7 folder only gained that build in its name (`v0-1-7-alpha-1-2-rc-1`) plus a `SUPPORTED_RELEASES` row — which turns an rc.1 host's verdict from `line` into `exact`. What did change is how the host reads the manifest: from rc.1 the profile composition checks each plugin's `@deepseek-ai/dsh*` `peerDependencies` against the running release and **disables its row before importing a single module** when a declared range does not match, the only way past that being an exact-version exemption the plugin manager stores in the profile's own `compatibility.json`. `engines.dsh` remains declarative, so the peer list is what decides whether the plugin runs — hence `|| 0.1.7-rc.1` on all seven `@deepseek-ai/dsh-*` peers.
112
- - **No `:has()` dependency once the host is known**: a resolved release emits its own targeted branches, ungated. That also fixes a latent problem: on an engine without `:has()` the previous gate dropped the panel promotion entirely on 0.1.5 / 0.1.6. An unresolvable release still falls into `unknown` and lets the DOM shape arbitrate (`:has()` dual arms) instead of guessing a version.
113
- - **Header popover selectors spelled once**: the top-bar surface list was duplicated three times inside `wallpaper.ts`; it is now composed once and shared by the opacity rule and the outline rule (the latter deliberately keeps the bare tag without `[role]`, with the reason documented in place). Slot keys come from the adapter, so the `leading` slot unique to `0.1.6-alpha.2` no longer leaks into base code.
114
- - **The plugin page's card list is framed**: `Settings → Plugins` renders each group's plugins in a `ul` that has no surface of its own, so with the settings surfaces faded the whole table floated straight on the wallpaper. Each group's list now gets what the composer capsule gets — a rounded frosted block on an `::before` underlay, painted from the settings-interface opacity and frosted by the settings blur (the page is a sibling of the settings dialog on 0.1.7, so reading the dialog's own token re-scope would have left it on the homepage alpha). It is contributed only by the adapters whose release ships that page, so the selector never rides a host that cannot match it.
115
- - **Fixed the wallpaper disappearing while the right Sidebar animates**: the AppFrame's own translucent background was cleared with an inline `background: transparent`, and the host's `style` rewrite during the sidebar open/close animation dropped it — the frame snapped back to an opaque layer, hiding the wallpaper and flattening every frost above it, because a `backdrop-filter` with nothing behind it has nothing to blur. The clear is a class rule with `!important` now, which the host's style writes cannot reach (measured on the live frame: `rgb(200,207,218)` opaque → `rgba(0,0,0,0)` with the class, opaque again without it).
116
- - **Fixed the chat card landing on a settings page at startup**: while no conversation view is mounted (starting the host with the settings panel open, for instance), the marker-less chat-card fallback picked "the largest scrollable element" by geometry — so the settings page got card chrome plus a frost underlay (`<div class="dab-part-underlay">`) spread over the whole window. The fallback can now only refine a conversation that already exists: with none of `[data-chat-flow]` / `[data-conversation-scroll]` / `[data-composer-seat]` / `[data-conversation-composer-overlay]` present in the center column it no longer guesses, and candidates inside the settings dialog are still rejected.
117
- - **Fixed the covered area of the per-part frosted blur**: the class rule for the hosting element was missing its leading dot (`dab-part-blur{isolation:isolate}`), so that layer never created a stacking context and the `z-index:-1` frost underlay fell into the page-level one — its sampling region and its painted position both stopped matching the surface (measured live: the host element's computed `isolation` was `auto`). With the dot restored, the frost stays inside its own surface. This defect predates v0.3.0.
118
- - Corrected several wrong assumptions about the host: the native right Sidebar and `ctx.sidebarRightTabs` are not a new-host feature (`0.1.5-rc.2` already ships them), and dockkit itself predates 0.1.7 — only its `host` / `empty` attributes are 0.1.7 markers.
119
- - README: the Compatibility section gains a "Isolated per-version adaptation" entry and Known limitations names the layer where version-specific selectors live; the intro no longer implies the official-Sidebar UI exists only on newer hosts.
120
-
121
- ### v0.3.0 (DSH 0.1.7 adaptation, compatible with 0.1.5-rc.2 ~ 0.1.7-alpha.1)
122
-
123
- - **0.1.7 right Sidebar**: the host reworked that panel — it is now a *stationary* frame whose docked children (`[data-dockkit-host="dock"]` / `[data-dockkit-empty]`) carry the slide transform, and the panel no longer paints its own background. The plugin follows the new shape: the blur rides the sliding children so it travels with the sidebar instead of staying pinned, and the surface tokens are re-scoped where the panel actually renders. The previous unconditional `position:fixed` promotion was removed — on 0.1.7 it detached the panel from the animated track.
124
- - **0.1.6 right Sidebar blur restored**: `[data-dockkit-host]` only exists from 0.1.7, so the child-based blur selector matched nothing on 0.1.6 (which slides the panel itself). A second, `:has()`-gated arm now frosts the panel wrapper there, and the pre-0.1.7 promotion is re-applied only where it is needed.
125
- - **Gradient "shimmer" text is no longer flattened by the outline feature**: `-webkit-text-stroke` is inherited, so the conversation-frame rule reached the `background-clip: text` activity chrome — the "深度求索中" turn-status line (0.1.5/0.1.6) and the turn-process/shimmer rows (0.1.7) turned into a flat stroke-coloured blob. They are now explicitly exempt, matched by `[role="status"]`, `[data-turn-process]` and the TextShimmer marker.
126
- - **New "Header popovers" surface**: the Agent Team panel, background-job list, open-in-app / session-log menus and the subagent lineage tree get their own opacity + blur sliders, plus a matching outline group. Because these popovers are portalled to `<body>` (severed from the header) and 0.1.7 moved open-in-app to a portal and made the session-row menu a dynamic slot, a runtime tagger watches the stable `conversation.session.header*` slot anchors and marks the open popover. The exempt confirm dialogs and session-row menu are pinned opaque with real color literals — no self-referencing `var()` fallback, which is a CSS cycle that would render them fully transparent.
127
- - **Host release detection**: the client context exposes no host version (`window.__DSH_BOOT__.version` is a module-table tag, not a release), so the release plus a generation bucket is resolved on the Node half from the launcher's on-disk layout and handed to the client through the `read` RPC payload. Feature gates use it; when it cannot be determined they fall back to capability probing rather than guessing.
128
- - **Native support for the official right Sidebar**: a "Theme" card is contributed to the official Sidebar's guide page through its public extension points (a page type in `ctx.sidebarRightTabs` plus the keyed `sidebar.right.pane.tab` body seat), opening the same five pages as the settings panel. Active without dsh-better-sidebar; when that plugin is present, its own "Theme" page takes over and the official guide card withdraws itself. Registration waits on the service at runtime — hosts without the Sidebar registry API skip it silently, so older hosts are unaffected.
129
- - **The right-sidebar slider row follows the environment**: the Interface page's panel group (`panelOpacity` / `blurs.panel`) reads "右方侧边栏" (Right sidebar) without better-sidebar — driving the official right Sidebar's surface tokens and frosted blur on 0.1.5-rc.2 through 0.1.7 — and "bettersidebar" with it. The row is now always visible instead of hiding when better-sidebar is absent.
130
- - The better-sidebar presence probe no longer counts `[data-sidebar-right-panel]`: on every host generation that is the official right Sidebar's stable marker (present whenever a session is open), so counting it pinned the "bettersidebar" verdict to true forever.
131
- - Compatibility declarations now cover `0.1.5-rc.2`, `0.1.5-rc.3`, `0.1.6-alpha.1`, `0.1.6-alpha.2` and `0.1.7-alpha.1`; peerDependencies widened to span every generation of the client packages; `@deepseek-ai/dsh-home-paths` stays at the lockfile-consistent `^0.1.0-rc.6` (build-time only — the host injects its own copy at runtime).
94
+ ### v0.3.4 (Two new host lines: `0.2.0-rc.2` and `0.2.1-alpha.1`)
95
+
96
+ - **A sticky menu group heading got its own token on `0.2.0-rc.2`** (`--dsw-alias-menu-group-header-fill`, replacing `ModelSelect`'s `.groupTitle{background:var(--dsw-specific-menu)}`), so the model list's heading follows the card / header opacity slider and the picked theme color again instead of sitting on the faded menu as an untinted, near-opaque band. This is the first patch line that needed two folders — rc.1 and rc.2 are the same prerelease channel with different facts — so its folder is named for the build.
97
+ - **The turn-event row now fades in its own color**: since rc.2 it fills from `--dsw-alias-turn-trigger-bg` (dark mode points that at the interactive-hover fill, not the code-block one). The plugin reads the same chain the host writes, fallback included, so a newer host takes its new color, an older one takes the code-block color, and no release test enters the styling code.
98
+ - **DSH `0.2.1-alpha.1` is supported**: `design-platform.css`, `MenuGroup` and `MenuSurface` are byte-identical to rc.2, and the new `shell.bottom` strip paints `--dsw-alias-bg-base` — the main-background token — so the existing slider already owns it.
99
+ - **Small host releases no longer need a plugin release**: `engines.dsh`, the six gated `@deepseek-ai/dsh-*` peers and `dsh.compatibility` now close with `|| 0.2.1-alpha.1 || >=0.1.7-alpha.1` — the umbrella has no upper bound. From `0.1.7-rc.1` the host disables any plugin whose peer ranges do not name the running release, and a range that runs out is a wall in front of a plugin that would have kept working: an uncapped range hands a future 0.2.x or 0.3.x build the closest verified adapter plus a log line saying how far from `exact` that is, and the worst a wrong guess can cost is one slider not fading a surface it no longer recognizes. Installing on a new host still needs a `dsh web` restart — the peer check runs while the profile is composed.
100
+ - **The cards that take the composer seat now frost with the input blur.** Approval, plan review and the question composer render *beside* `[data-composer-card]` and fill from the same `--dsw-specific-input-major`, so they faded with the input slider while the blur slider had nothing to act on — the card you are meant to read went straight onto the wallpaper. They now get the capsule's `::before` underlay, gated on a non-zero blur so the plugin still adds no stacking context for free, and the answer field joins the input group's stroke and placeholder bindings. The anchors (`[data-approval-key]`, `[data-plan-review-key]`, `[data-question-key]`) are unchanged from `0.1.5-rc.2` through `0.2.1-alpha.1`, so this is a range-wide binding in shared host facts, not a per-version one.
101
+ - **The `invariant` companion is gone** (`lib/invariant.js`, its `exports` entry, its `@deepseek-ai/dsh-invariants` peer): nothing ever loaded it, and `0.2.1-alpha.1` deletes that package.
102
+ - **The settings page's stylesheet now carries the plugin tag the other sheets have.** Through rc.2 the host's module system claimed *any* untagged `<style>` present while a plugin materialized and deleted it if that plugin failed; `0.2.1-alpha.1` narrowed the claim to the tags a factory added itself. Tagged, the sheet is safe on both.
103
+
104
+ ### v0.3.3 (Menu paint per release, DSH 0.2.0-rc.1 supported)
105
+
106
+ - **The card and header sliders drive menus on `0.1.7-rc.2` again.** That build moved a menu's fill and frost onto a child layer and turned `--dsw-specific-menu` into an alias, so the token the plugin had always been writing was no longer read by anything on a menu. Which tokens a menu paints from, and which layer does the frosting, is now a fact each version folder supplies instead of an assumption baked into shared code.
107
+ - **DSH `0.2.0-rc.1` is supported** — checked at the tag, then given its own folder and channel. The manifest names that one build rather than opening the whole 0.2.0 line: a release nobody diffed is a different host.
108
+ - **Shimmer text survives the 0.2.0 rewrite**: the outline exemption gained `[data-shimmer]`, so the activity line is no longer drawn as two stacked copies.
109
+ - **The plugin page's loading skeleton** gets the same frosted card as the list it stands in for.
110
+ - Installing on a 0.2.0 host needs a `dsh web` restart: since `0.1.7-rc.1` the host decides whether a plugin loads from its peer ranges, and a release it does not name is disabled before a single module is imported.
132
111
 
133
112
  ## Installation
134
113
 
@@ -172,14 +151,14 @@ pnpm dsh web
172
151
 
173
152
  ## Compatibility
174
153
 
175
- - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) 0.1.5-rc.2 ~ <0.2.0** — `engines.dsh`, the seven `@deepseek-ai/dsh-*` `peerDependencies` and `dsh.compatibility.dsh` list the `0.1.5-rc` and `0.1.6-alpha` builds this plugin has been checked against one by one, then close the range with `>=0.1.7-alpha.1 <0.2.0-alpha.0`, so every 0.1.7-and-later release up to 0.2.0 loads (`0.1.7-rc.1` / `0.1.7-rc.2` were checked by diffing their tags, the builds before them hands-on). From `0.1.7-rc.1` the host itself enforces that peer list — a release the ranges do not name is disabled before its modules are imported — so naming it is what makes the plugin load, not documentation; the declarations in `dsh.compatibility.dshReleases` record which builds were checked. 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.
176
- - **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 release** (`v0-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `unknown`), each describing that version's panel mechanics and header slot keys. Base code just asks the adapter questions (who owns the guide surface, which layer carries the blur) and never compares version strings. Another build on a verified patch line (`0.1.6-alpha.4` against a table checked at `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. 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.
154
+ - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) 0.1.5-rc.2 ~ `0.2.1-alpha.1`, and everything above it with it** — `engines.dsh`, the six gated `@deepseek-ai/dsh-*` `peerDependencies` and `dsh.compatibility.dsh` name the `0.1.5-rc` / `0.1.6-alpha` builds this plugin was checked against one by one — those have to be listed, since the umbrella starts above them — keep naming every build it has since diffed (`0.1.7-rc.1`, `0.1.7-rc.2`, `0.2.0-rc.1`, `0.2.0-rc.2`, `0.2.1-alpha.1`) for the record, and close with an uncapped `>=0.1.7-alpha.1`, so every 0.1.7, 0.2 and later release loads. The uncapped umbrella is the deliberate choice: from `0.1.7-rc.1` 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: `0.1.7-rc.1` / `0.1.7-rc.2`, `0.2.0-rc.1` / `0.2.0-rc.2` and `0.2.1-alpha.1` were checked by diffing their tags, the builds before them hands-on. 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.
155
+ - **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-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `v0-1-7-rc-2` / `v0-2-0-rc-1` / `v0-2-0-rc-2` / `v0-2-1-alpha-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. 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.1.6-alpha.4` against a table checked at `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.1`. 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.
177
156
  - **[DSHA](https://github.com/DSH-APP/DSHA)** — DeepSeek Harness Android launcher (ROOT-free, Termux-free). Its bundled `dsh` is `0.1.5-rc.2`, inside the supported range; the mobile UI shell is provided by `dsh-web-mobile`.
178
157
  - **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — Supported
179
158
 
180
159
  ## Permissions, side effects & boundaries
181
160
 
182
- - **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/invariant.js`, `lib/client.js`), and there are no install scripts, no `postinstall`, no native binaries, and no build step at install time.
161
+ - **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.
183
162
  - **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.
184
163
  - **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.
185
164
  - **Shell / native**: none. No `child_process`, no native modules, no dynamically downloaded executables.
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.1.5-rc.2 ~ <0.2.0" src="https://img.shields.io/badge/DSH-0.1.5--rc.2%20~%20%3C0.2.0-4d6bfe" /></a>
7
+ <a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本:0.1.5-rc.2 ~ 0.2.1-alpha.1 及其上" src="https://img.shields.io/badge/DSH-0.1.5--rc.2%20~%200.2.1--alpha.1%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,7 +12,7 @@
12
12
 
13
13
  [English](README.md) | 中文
14
14
 
15
- 一个 **DeepSeek Harness** 外观插件:自定义主题色、背景壁纸(图片 / 视频 / 算法动态生成),以及逐表面的透明度与模糊度控制。兼容 **DSH 0.1.5-rc.2 起、0.2.0 之前的整条 0.1.7 线**(官方右侧栏「主题」卡片等界面按宿主是否提供右侧栏注册表扩展点自动启用,缺失时静默跳过)。
15
+ 一个 **DeepSeek Harness** 外观插件:自定义主题色、背景壁纸(图片 / 视频 / 算法动态生成),以及逐表面的透明度与模糊度控制。兼容 **DSH 0.1.5-rc.2 直至 `0.2.1-alpha.1`,其上所有版本一并放行**(官方右侧栏「主题」卡片等界面按宿主是否提供右侧栏注册表扩展点自动启用,缺失时静默跳过)。
16
16
 
17
17
  ---
18
18
 
@@ -89,46 +89,25 @@
89
89
  - **中英双语** — 完整的中英文界面,自动跟随语言设置。
90
90
  - **主题守护** — 宿主重置主题后自动重新激活自定义主题。
91
91
 
92
- ## 更新日志(只保留最新两个版本)
93
-
94
- ### v0.3.2(产出物表面全量绑定,0.1.7-rc.2 恢复加载)
95
-
96
- - **产出物滑块现在覆盖 0.1.7 渲染的每一件产物**:工具调用详情卡片(`[data-inspect]`,见 `ToolDetails.module.css`)、事件行(`[data-turn-trigger]`,含 hover 底色)、diff 块(`[data-diff]`)、变更文件卡片(`[data-changed-files]` —— 根、标题按钮、文件计数瓷片各自取色)以及内联 `code` 的磨砂,此前全部由宿主按不透明绘制、我们这边没有任何绑定,所以「产出物/高亮内容」那对滑块对它们无效。现在每件都按自己的宿主 token 用 `color-mix(… var(--dsh-any-prod-pct))` 重新发色并共享同一层磨砂(compact 变体下的内联 `code` 除外——提示字号的文字上蒙一层磨砂只会糊);描边组列出同一批表面,它们的文字不再继续继承对话框描边。
97
- - **代码卡片横幅恢复跟随主题而不是一块白斑**:0.1.7 把 ReadBlock / DiffBlock / CodeBlock 合到同一个 CodeCard,其头部取色链是 `--dsl-code-block-background` → `--dsw-alias-markdown-code-block`,而 `--dsl-code-block-banner-background-color` 只在 markdown 块的作用域里存在。我们的横幅那条分支仍先读旧的 `--dsw-alias-markdown-code-block-banner`,于是读取/diff 的头一直是一块忽略滑块的近白不透明条。现在这条分支照宿主自己的链发色,旧版那条用 `:not([data-code-block-banner])` 守住,两者不会同时认领同一个元素(现场用注入的 0.1.7 卡片实测:20% 时横幅与卡片融合;宿主确实使用该 token 的地方——diff 头部——两种颜色依然分明)。
98
- - **dsh-better-sidebar 的工作台面板改由产出物滑块接管**:`[data-dsh-bottom-panel]` 打开的就是对话行指向的产物,所以它随产出物表面一起淡化、磨砂,不再跟面板行走——面板行现在只代表宿主自己的右侧栏。它的不透明度用不了原地重发那招:面板内部每件表面(栏壳、标签条、卡片)各读一个层级 token,因此由产出物滑块写四个根变量去重定义这些 token,与面板行驱动原生面板的方式一致。两个设置页的标签与图标按这个划分改正。
99
- - **输入框磨砂归零后不再留下层叠上下文**:输入规则改由 `<html>` 上的 `dab-input-frost` class 把关,模糊滑块回到 0 时该 class 摘掉,没有被磨砂的输入框不再被 isolate(现场实测 `isolation`:`isolate → auto`)。宿主自己的卡片规则始终保留 `position: relative`(`.uV2eYG_card`),而分部位磨砂只在模糊非 0 时才补 position——因此「磨砂中的表面盖住其他插件的普通流内通知」这一种情况是磨砂本身带来的,不是残留,需要点名豁免那个通知。
100
- - **变更文件卡片只听一个滑块**:它的根节点取自 `--dsw-alias-bg-layer-1`,而这正是界面「卡片(选项面板)」不透明度在 `body` 上全局重映射的那个 token,于是产出物的 `color-mix` 把两层 alpha 乘在了一起——一张产物卡片同时听两个滑块。根节点现在改读由 `applyProduced` 写入、与面板行同源取自原始调色板的产出物专属变量 `--dsh-any-prod-layer-1`(现场实测:把卡片 alpha 压到 0.3 时卡片纹丝不动,产出物 alpha 依然能把它带到 0.2)。
101
- - **鼠标悬浮产生的预览窗补上了绑定**:悬浮一件产物会打开宿主 `ui-primitives/HoverCard`,它把卡片 portal 到 `document.body`,底色是组件级的字面量(`--dsw-hovercard-bg: #2C2C2E`,深浅主题同值)——既躲在任何树内重定义之外,也不归任何滑块管。它据此加入产出物组的磨砂/透明度/描边,锚点用这张卡片一定会写的行内属性 `--dsh-hover-preview-fade`;该标记只有 0.1.7 有(0.1.5 / 0.1.6 的这张卡片没有任何可区分属性),所以旧宿主只是不匹配,而不是用 `[class$="_card"]` 去捞——那会连输入框一起命中。同一个标记下其实有两种表面,各自按自己的取色淡出:普通卡片沿用宿主的组件级字面量 `--dsw-hovercard-bg: #2C2C2E`(宿主刻意让深浅主题都用它),而 `preview` 变体改从主题表面 `--dsw-alias-bg-layer-1` 取色,因此读产出物滑块的原始层级变量——两者都去 mix 那个字面量会把一张浅色预览窗染成深色(实测:浅色主题下变成 `rgb(44,44,46)`)。
102
- - **antd 的确认弹窗不再被当成设置面板**:`SETTINGS_PANEL_SEL` 原先认定「带 `aria-labelledby` 的 `aria-modal` 对话框」只有设置面板一个,但宿主的 antd `Modal`——「删除会话」确认框等——同样带齐这三个属性,于是它继承了设置表面色、设置磨砂、面板行写入的整组 `--dsw-alias-bg-layer-*` 重定义,以及设置描边分组。选择器现在额外要求 `ui-settings-general/SettingsRoot.tsx` 加在自己对话框元素上的哈希类 `css.panel`,这一点从 `0.1.5-rc.2` 到 `0.1.7-rc.1` 完全一致;antd 渲染的是 `ant-modal-*` 连字符类名,不可能含它。现场实测:收紧后真设置面板仍然命中,而完整的 antd 弹窗子树(container、close、header、body、footer、两个按钮)在所有 `dsh-any*` 样式表上命中数为 0——收紧前它是命中的。所以当前构建里确认按钮若仍有位移,来源已经不在本插件。
103
- - **`0.1.7-rc.2` 重新可加载,其后的 0.1.7 构建也一并放行**:从 rc.1 起,peer 检查里少列一个版本号的代价就是插件在宿主上根本不启动,而 rc.2 恰好没在表里(issue #20)。七个 `@deepseek-ai/dsh-*` peer、`engines.dsh` 与 `dsh.compatibility.dsh` 现在都以 `|| 0.1.7-rc.2 || >=0.1.7-alpha.1 <0.2.0-alpha.0` 收尾,整条 0.1.7 线以及之后的 0.1.x 不必每出一个构建就回来改一次清单。这条统括范围必须这样写:单写 `>=0.1.7` 一个预发布构建都匹配不到(semver 只允许比较符自带同一个 `[major,minor,patch]` 元组时去和预发布版比较),上界也只能写 `<0.2.0-alpha.0` 而不是 `<0.2.0`,否则 `0.2.0-alpha.1` 会漏进来。每个判定都拿宿主自带的那份 `semver`(rc.1 运行时里的 7.8.5)按门禁同款的 `{includePrerelease: true}` 复跑过;统括只往后放,更早的 `0.1.5-rc` / `0.1.6-alpha` 依旧逐构建枚举,对没核对过的版本线放开范围等于声明一份没核对过的兼容。但清单决定的只是「加载」:适配表未动,rc.2 宿主仍按补丁行规则落进现有的 0.1.7 目录(判定是 `line` 而非 `exact`),而 rc.2 自己那份 diff 里的表面漂移(菜单底色改由 `--dsw-menu-surface-fill` 提供、变更文件卡片的单文件变体)属于还需要一台真跑 rc.2 的机器来度量的后续项。
104
-
105
- ### v0.3.1(版本适配隔离:每个宿主版本一个目录)
106
-
107
- - **前置版本检测层**:宿主 release 的探测与渠道归类收进 `src/host-compat/`(Node 半侧读取进程所由以启动的那份 `@deepseek-ai/dsh/package.json`,即 `ctx.profileContext.installAnchor`,拿不到时再退回启动器 `homes/<ver>` 旁边 `versions/<ver>` 里的同名清单与目录名,经 `read` RPC 下发),客户端侧由 `src/client/host-compat/` 承接判定、广播变更,并在判定到达时重切静态样式表。原本散落在 `src/client/host.ts` 与各消费方里的版本判定统一到这一层,该模块已删除。
108
- - **每个版本一个独立目录**:`src/client/host-compat/versions/` 下 `v0-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `unknown` 各自描述本版本的面板力学(提升与模糊挂在哪一层)与头部槽位键,`versions/registry.ts` 是全插件唯一的「release → 代码」映射。底码只向适配层提问(引导页表面归谁、用哪些槽位选择器),不再出现版本字符串比较——适配新宿主等于新增一个目录并登记,底码不用动。
109
- - **版本标识细化到发布渠道**:适配键不再是 `0.1.5` 这种补丁号,而是「补丁行 + 预发布渠道」的 `0.1.5-rc` / `0.1.6-alpha` / `0.1.7-alpha`。理由是每个目录的力学都是照着某个具体渠道的 tag 逐条核对出来的,把 `0.1.5-rc.3` 与假想中的 `0.1.5-beta.1` 记成同一个键,等于让未核对过的形状继承已核对过的结论。目录名与适配器 id 现在也直接写出核对过的具体 tag(`v0-1-6-alpha-1-2`,id 报 `0.1.6-alpha.1/alpha.2`),不打开目录就知道这张表覆盖到哪一步;同一条补丁行内两个构建确有差别的地方(`leading` 槽位与插件管理页都只在 `0.1.6-alpha.2` 起存在)由该目录自己带预发布门控。
110
- - **落在已核对范围外的宿主按就近原则取档**:`src/host-compat/channel.ts` 里那张 `SUPPORTED_RELEASES` 表(`0.1.5-rc.2` / `0.1.6-alpha.2` / `0.1.7-alpha.2` / `0.1.7-rc.1`,从旧到新——一行记一个核对过事实的构建,所以同一条补丁行可以有两行)先按**补丁行**匹配:本机是 `0.1.6-alpha.4` 而表上只核对到 `0.1.6-alpha.2` 时,用的仍是 `0.1.6-alpha` 这一档(渠道序号只是同一条线里的构建计数,`0.1.6-alpha.1` 比核对基准更早的情况另有适配器就近处理);`0.1.6-beta.1`、乃至假想中不带渠道的 `0.1.6` 也算同一条线,落回该线。整条补丁行都不在表上时才收边:高于最新一档取最新,低于最低一档取最低,夹在两档中间取**较低**的那一档(适配层只声明它核对过的东西)。这类收边判定会打一条日志说明「本宿主不在核对范围内,按 X 档处理」,新宿主报问题时应先看这行。只有**完全解析不到 release**(例如 `~/.dsh` 这种没有启动器布局的安装)才归入 `unknown`,交给 DOM 形状仲裁。
111
- - **`0.1.7-rc.1` 进入已核对范围,且不需要新的适配目录**:把它与 `0.1.7-alpha.2` 逐包比对后,本插件匹配的每个锚点都还在原处,所以 0.1.7 目录只是在名字里多记了这个构建(`v0-1-7-alpha-1-2-rc-1`),并在 `SUPPORTED_RELEASES` 里多一行——rc.1 宿主的判定因此从 `line` 变成 `exact`。真正变了的是宿主读清单的方式:从 rc.1 起,profile 组装阶段会把插件声明的 `@deepseek-ai/dsh*` `peerDependencies` 与运行版本比对,范围不匹配就**在导入任何模块之前把该插件整行禁用**,唯一放行办法是在插件管理器里授予「精确版本豁免」(写进 profile 自己的 `compatibility.json`)。`engines.dsh` 仍然只是声明,决定插件能不能加载的是 peer 列表——七个 `@deepseek-ai/dsh-*` peer 因此都补上 `|| 0.1.7-rc.1`。
112
- - **确定宿主版本时不再依赖 `:has()`**:解析到 release 的宿主直接发本版本的定位分支,不带 `:has()` 门。这顺带修掉一个潜在问题:在不支持 `:has()` 的引擎上,原来的门控会让 0.1.5 / 0.1.6 的面板提升整条失效。解析不到 release 时仍归入 `unknown`,由 DOM 形状(`:has()` 双臂)仲裁,而不是猜一个版本。
113
- - **头部浮层选择器单一来源**:顶栏表面的选择器此前在 `wallpaper.ts` 里重复了三份,现在拼一次、由透明度与描边两条规则共用(描边那条刻意用不加 `[role]` 的原始标记,原因就近写明)。槽位键改由适配器提供,`0.1.6-alpha.2` 独有的 `leading` 槽位不再散落在底码里。
114
- - **插件页的卡片列表加上块级底板**:`设置 → 插件` 里每组插件的 `ul` 自身没有表面,设置界面淡出后整张表直接浮在壁纸上。现在每个分组列表拿到与对话输入框同一套处理——`::before` 底板撑出圆角磨砂块,底色由「设置界面」这一组驱动、模糊由「设置模糊」驱动(0.1.7 上该页是 centerCol 的子节点而不是设置对话框的后代,只跟着对话框的令牌重挂就会读错滑块)。这条规则只由确实带该页的版本适配器发出,没有插件管理页的宿主不会背上匹配不到的选择器。
115
- - **修复展开右侧栏动画期间壁纸消失**:AppFrame 自身的半透明底色此前是用内联 `background: transparent` 抹掉的,而宿主在侧栏开合动画里重写 `style` 时把它丢了——框架回到不透明,壁纸被盖住,其上每一层磨砂同时被压平(`backdrop-filter` 背后没有内容就无从模糊)。现在改为带 `!important` 的 class 规则,宿主的 style 写入碰不到它(同一个 frame 现场实测:不透明 `rgb(200,207,218)` → 挂上 class 后 `rgba(0,0,0,0)`,去掉又回到不透明)。
116
- - **修复启动时「对话卡片」套到设置页上**:聊天视图尚未挂载时(例如开着设置面板启动),对话卡片的无标记回退会按几何挑「最大的可滚动元素」,于是设置里的页面被穿上卡片外壳、并挂上一层磨砂垫(`<div class="dab-part-underlay">`)覆盖整个窗口。现在回退只能细化**已经存在**的对话:中心列里找不到任何对话标记(`[data-chat-flow]` / `[data-conversation-scroll]` / `[data-composer-seat]` / `[data-conversation-composer-overlay]`)时不再靠几何猜;属于设置对话框表面的候选也一并拒绝。
117
- - **修复分部位毛玻璃的覆盖区域**:承载磨砂的元素那条类名规则漏写了开头的点(`dab-part-blur{isolation:isolate}`),所以该层从来没建立自己的层叠上下文,`z-index:-1` 的磨砂垫跑进了页面级的层叠上下文——模糊取样的范围和落位的位置都不再对应那个表面(现场实测宿主元素的 `isolation` 计算值为 `auto`)。补上点号后磨砂回到表面自身之内。这个缺陷早于 v0.3.0 就存在。
118
- - 更正了几条对宿主的错误假设:原生右侧栏与 `ctx.sidebarRightTabs` 并非新宿主特性(`0.1.5-rc.2` 即已提供),dockkit 本身也存在得更早——只有 `host` / `empty` 两个属性才是 0.1.7 的标记。
119
- - README:兼容性一节新增「版本适配隔离」条目,已知限制补充版本相关选择器的所在层;引言不再暗示官方右侧栏特性只出现在新宿主上。
120
-
121
- ### v0.3.0(DSH 0.1.7 适配,兼容 0.1.5-rc.2 ~ 0.1.7-alpha.1)
122
-
123
- - **适配 0.1.7 官方右侧栏**:宿主重做了该面板——它现在是一个**静止外框**,滑动位移落在内部的 dockkit 子元素(`[data-dockkit-host="dock"]` / `[data-dockkit-empty]`)上,且面板本身不再绘制背景。插件随之调整:模糊改挂在真正滑动的子元素上,因此会跟随侧边栏一起移动而不是卡在原地;表面令牌也改为在面板实际渲染处重新作用域。原先无条件的 `position:fixed` 提升已移除——在 0.1.7 上它会让面板脱离动画轨道。
124
- - **修复 0.1.6 右方侧边栏模糊失效**:`[data-dockkit-host]` 从 0.1.7 才存在,所以基于子元素的选择器在 0.1.6 上匹配空集(0.1.6 的滑动打在面板自身)。现在新增一条用 `:has()` 门控的分支为面板包装元素加磨砂,且 pre-0.1.7 的提升只在真正需要处重新生效。
125
- - **修复流光文字被描边压成纯色**:`-webkit-text-stroke` 是继承属性,对话文本框的规则会一路继承到 `background-clip: text` 的活动状态文字上——「深度求索中」状态行(0.1.5/0.1.6)与轮次过程 / 流光行(0.1.7)会被糊成一块描边色。现在这些表面按 `[role="status"]`、`[data-turn-process]` 与 TextShimmer 标记被显式豁免。
126
- - **新增「顶栏选项」表面**:Agent Team 面板、后台任务列表、「用其它应用打开」/「会话日志」菜单与子代理血缘树拥有独立的透明度 + 模糊滑块,以及对应的描边分组。这些浮层被 portal 到 `<body>`(与头部断开),且 0.1.7 把「用其它应用打开」改为 portal、把会话行菜单改为动态槽位,因此插件新增一个运行时标记器,监听稳定的 `conversation.session.header*` 槽位锚点来标记展开的浮层。豁免的确认对话框与会话行菜单用真实颜色字面量钉死——不再使用自引用的 `var()` 回退,那是 CSS 循环,会让表面彻底透明。
127
- - **宿主版本探测**:客户端上下文不暴露宿主版本(`window.__DSH_BOOT__.version` 是模块表格式标记,不是 release),因此改由 Node 半侧从启动器的磁盘布局解析出 release 与渠道(`0.1.7-alpha` 这一级),再经 `read` RPC 下发。功能开关据此判定;无法确定时回退到能力探测,而不是猜一个版本。
128
- - **原生适配官方右侧栏**:通过官方公开扩展点(`ctx.sidebarRightTabs` 注册页面类型 + `sidebar.right.pane.tab` 键控槽位挂载页面本体)在官方侧边栏的引导页挂上「主题」卡片,点开就是和设置面板一样的五页。未安装 dsh-better-sidebar 时生效;装了 better-sidebar 则让位给它自己的「主题」页(官方引导页卡片自动撤下,不重复占位)。注册走运行时动态等待:宿主没有右侧栏注册表 API 时静默跳过,旧宿主不受影响。
129
- - **右方侧边栏栏位随环境改名**:界面页的面板分组(`panelOpacity` / `blurs.panel`)未安装 better-sidebar 时显示为「右方侧边栏」,直接驱动官方右侧栏的表面令牌与毛玻璃模糊(0.1.5-rc.2 至 0.1.7 均适用,该行现在始终显示);安装了 better-sidebar 时改名为「bettersidebar」,语义不变。
130
- - better-sidebar 存在性探测摘除了 `[data-sidebar-right-panel]` 标记——各代宿主中它都是官方右侧栏的稳定标记(随会话始终存在),继续计数会让「bettersidebar」判定永远为真。
131
- - 兼容性声明现已覆盖 `0.1.5-rc.2`、`0.1.5-rc.3`、`0.1.6-alpha.1`、`0.1.6-alpha.2`、`0.1.7-alpha.1`;peerDependencies 放宽为同时覆盖各代客户端包版本;`@deepseek-ai/dsh-home-paths` 维持与 lockfile 一致的 `^0.1.0-rc.6`(仅构建期使用,运行时由宿主注入自身版本)。
92
+ ## 更新日志(只保留最近两个版本)
93
+
94
+ ### v0.3.4(新增两条宿主线:`0.2.0-rc.2` 与 `0.2.1-alpha.1`)
95
+
96
+ - **`0.2.0-rc.2` 给吸顶的菜单分组标题另发了令牌**(`--dsw-alias-menu-group-header-fill`,取代 `ModelSelect` 自己的 `.groupTitle{background:var(--dsw-specific-menu)}`):模型列表的分组标题重新跟着「卡片」「顶栏选项」两组滑块与所选主题色走,不再以一条不套色、近乎不透明的白带压在淡出的菜单上。这是第一条需要两个目录的补丁行——rc.1 与 rc.2 同属一个预发布渠道却交出不同的事实——所以新目录按构建命名。
97
+ - **事件行改用他自己的颜色淡出**:rc.2 起该行从 `--dsw-alias-turn-trigger-bg` 取底(深色模式下这个别名指向交互态底色,不再是代码块那一层)。插件按宿主写下的链条去读,连带回退值一起,于是新构建拿新颜色、旧构建拿代码块颜色,样式代码里不引入任何版本判断。
98
+ - **支持 DSH `0.2.1-alpha.1`**:`design-platform.css`、`MenuGroup`、`MenuSurface` 与 rc.2 逐字节相同;新增的 `shell.bottom` 条带画的是 `--dsw-alias-bg-base`——主背景令牌——背景透明度滑块本来就管着它。
99
+ - **宿主小版本更新不再需要插件跟着发版**:`engines.dsh`、六个受门禁的 `@deepseek-ai/dsh-*` peer 与 `dsh.compatibility` 现在以 `|| 0.2.1-alpha.1 || >=0.1.7-alpha.1` 收尾——总括不设上界。从 `0.1.7-rc.1` 起,peer 范围没点名当前 release 的插件会被整个禁用,而一条写到头的范围等于在一款还能继续工作的插件前面砌墙:不设上界的范围会把未来的 0.2.x、0.3.x 构建交给最近的一份已核对事实,并在日志里写清它离 `exact` 有多远;猜错的最坏代价是某个滑块不再淡出它已认不出的表面。装到新宿主仍要重启 `dsh web`——peer 检查发生在 profile 组装时。
100
+ - **接管输入位的那几张卡片现在跟着「输入模糊」磨砂了**:审批、计划回顾与问题卡渲染在 `[data-composer-card]` 的*旁边*,却填的是同一个 `--dsw-specific-input-major`——于是它们会随输入透明度淡出,模糊滑块却对它们无事可做,正是最该看清的那张卡直接压在壁纸上。现在它们拿到输入胶囊同款 `::before` 衬底,并且和胶囊一样只在模糊值非零时挂上,零值时插件不额外制造层叠上下文;答案输入框一并接进输入组的描边与占位符绑定。三张卡的锚点(`[data-approval-key]` / `[data-plan-review-key]` / `[data-question-key]`)从 `0.1.5-rc.2` 到 `0.2.1-alpha.1` 没有变过,所以这条绑定是全范围的事实,放在共享层而不是某个版本目录里。
101
+ - **删掉 `invariant` 伴生入口**(`lib/invariant.js`、它的 `exports` 条目、它的 `@deepseek-ai/dsh-invariants` peer):从来没有任何一行装载它,而 `0.2.1-alpha.1` 已把这个包从宿主里移除。
102
+ - **设置页那份样式表补上了其它表都有的插件标记**:到 rc.2 为止,宿主的模块系统会把当时*所有*未打标的 `<style>` 判给正在装配的那个插件,并在该插件失败时把它们删掉;`0.2.1-alpha.1` 把认领范围收窄到工厂自己新增的那些。打上标记后,两种宿主都动不了它。
103
+
104
+ ### v0.3.3(菜单按版本交出绘制事实,支持 DSH 0.2.0-rc.1)
105
+
106
+ - **`0.1.7-rc.2` 上「卡片」「顶栏选项」两组滑块对菜单又有效了**:那个构建把菜单的底色与磨砂移到子层,并把 `--dsw-specific-menu` 改成别名,插件一直在写的令牌在菜单上再没有别的读者。「菜单从哪些令牌取色、磨砂由哪一层承担」现在由每个版本目录各自交出,公共代码里不再留假设。
107
+ - **支持 DSH `0.2.0-rc.1`**:逐 tag 核对后给它自己的目录与渠道。清单只点名这一个构建,不放开整条 0.2.0 线——没人比对过的版本就是另一个宿主。
108
+ - **流光文字跟上 0.2.0 的重写**:描边豁免补入 `[data-shimmer]`,进度文字不再被勾成叠放的两份。
109
+ - **插件页首屏的加载骨架屏**拿到与它所代替的那张卡片列表相同的磨砂底。
110
+ - 装到 0.2.0 宿主上要重启 `dsh web`:从 `0.1.7-rc.1` 起宿主按 peer 范围决定插件能不能加载,没被点名的版本在导入任何模块之前就被整行禁用。
132
111
 
133
112
  ## 安装
134
113
 
@@ -172,14 +151,14 @@ pnpm dsh web
172
151
 
173
152
  ## 兼容性
174
153
 
175
- - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) 0.1.5-rc.2 ~ <0.2.0** — `engines.dsh`、七个 `@deepseek-ai/dsh-*` 的 `peerDependencies` 与 `dsh.compatibility.dsh` 先逐一列出本插件核对过的 `0.1.5-rc` 与 `0.1.6-alpha` 各构建,再以 `>=0.1.7-alpha.1 <0.2.0-alpha.0` 收尾,因此 0.1.7 起到 0.2.0 之前的每个版本都会加载(`0.1.7-rc.1`、`0.1.7-rc.2` 以逐包比对 tag 核对,它们之前的构建是实测过的)。从 `0.1.7-rc.1` 起宿主自己强制这份 peer 列表——范围没写到的版本会在模块被导入之前整个禁用——所以列不列决定插件能不能跑,它不是写给人看的说明;`dsh.compatibility.dshReleases` 里则记录哪些构建真的核对过。宿主版本在运行时由 Node 半侧解析,依赖特定宿主版本渠道的功能(右侧栏面板模糊、官方侧栏「主题」卡片)只在对应宿主结构存在时启用,其余功能在整个范围内表现一致。
176
- - **版本适配隔离**:release 由 Node 半侧从进程自身那份 `@deepseek-ai/dsh/package.json` 读出(客户端上下文不暴露版本;`ctx.profileContext.installAnchor` 指不到时退回启动器的磁盘布局),经 `read` RPC 下发后只由前置适配层路由——`src/host-compat/` 负责探测与渠道归类,`src/client/host-compat/versions/` 下**每个版本一个目录**(`v0-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `unknown`),各自描述该版本的面板力学与头部槽位键。底码只向适配层提问(引导页表面归谁、模糊挂在哪一层),不比较版本字符串。同一补丁行内的其它构建(`0.1.6-alpha.4` 之于核对基准 `0.1.6-alpha.2`)用该行的档位;整条补丁行都不在已核对范围内才收边取最近的一档并写日志。只有解析不到 release 时归入 `unknown`,回退到按 DOM 形状探测(`:has()` 双臂)而不是猜一个版本;适配新宿主 = 新增一个版本目录并在注册表登记。
154
+ - **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness) 0.1.5-rc.2 ~ `0.2.1-alpha.1`,其上所有版本一并放行** — `engines.dsh`、六个受门禁的 `@deepseek-ai/dsh-*` 的 `peerDependencies` 与 `dsh.compatibility.dsh` 先逐一列出本插件核对过的 `0.1.5-rc` 与 `0.1.6-alpha` 各构建——总括从它们之上开始,所以这些必须写全——继续点名此后逐个 diff 过的版本(`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2`、`0.2.1-alpha.1`)作为记录,最后以不设上界的 `>=0.1.7-alpha.1` 收尾,让 0.1.7、0.2 及其后的每一个 release 都能加载。不设上界是有意选的:从 `0.1.7-rc.1` 起宿主强制的正是这份 peer 列表——范围没写到的版本会在导入任何模块之前被整行禁用——一条写到头的范围等于在一款还能正常工作的插件前面砌墙。没见过的 release 会取最近的一份事实,并在日志里写清它离 `exact` 有多远;一份过期事实最坏的代价是某个滑块不再淡出宿主已经搬走的那个表面,而一道失败关闭的版本检查代价是整个插件。`dsh.compatibility.dshReleases` 记录哪些构建核对过、怎么核对的:`0.1.7-rc.1` / `0.1.7-rc.2`、`0.2.0-rc.1` / `0.2.0-rc.2` 与 `0.2.1-alpha.1` 以逐包比对 tag 核对,它们之前的构建是实测过的。这道门禁也意味着安装或更新插件后仍需重启 `dsh web`——检查发生在 profile 组装时,而不是插件更新时——但不设上界的总括,正让已经升到更新宿主的机器不再需要先等插件发版(或手工授予精确版本豁免 `dsh plugin allow-version`)。宿主版本在运行时由 Node 半侧解析,依赖特定宿主版本渠道的功能(右侧栏面板模糊、官方侧栏「主题」卡片)只在对应宿主结构存在时启用,其余功能在整个范围内表现一致。
155
+ - **版本适配隔离**:release 由 Node 半侧从进程自身那份 `@deepseek-ai/dsh/package.json` 读出(客户端上下文不暴露版本;`ctx.profileContext.installAnchor` 指不到时退回启动器的磁盘布局),经 `read` RPC 下发后只由前置适配层路由——`src/host-compat/` 负责探测与渠道归类,`src/client/host-compat/versions/` 下**每个事实集合一个目录**(`v0-1-5-rc-2-3` / `v0-1-6-alpha-1-2` / `v0-1-7-alpha-1-2-rc-1` / `v0-1-7-rc-2` / `v0-2-0-rc-1` / `v0-2-0-rc-2` / `v0-2-1-alpha-1` / `unknown`),各自描述该版本的面板力学、头部槽位键、插件页形状,以及菜单的底色与磨砂落在哪一层。目录按它覆盖的事实命名,不按版本号的形状:`0.2.0-rc.1` 与 `0.2.0-rc.2` 同属一个预发布渠道,但 rc.2 改了吸顶菜单分组标题取色的令牌,于是这条补丁行上并着两个目录,较新的那个按开启它的那个构建命名。底码只向适配层提问(引导页表面归谁、模糊挂在哪一层、菜单该重写哪些令牌),不比较版本字符串。同一补丁行内的其它构建(`0.1.6-alpha.4` 之于核对基准 `0.1.6-alpha.2`)用该行的档位;整条补丁行都不在已核对范围内才收边取最近的一档并写日志——`0.2.1-alpha.1` 之上的每一个 release 如今就是靠这一档加载的。只有解析不到 release 时归入 `unknown`,回退到按 DOM 形状探测(`:has()` 双臂)而不是猜一个版本;适配新宿主 = 新增一个版本目录并在注册表登记。
177
156
  - **[DSHA](https://github.com/DSH-APP/DSHA)** — DeepSeek Harness 安卓启动器(免 ROOT、免 Termux)。其包内 dsh 为 `0.1.5-rc.2`,落在兼容范围内;移动端界面由 `dsh-web-mobile` 提供。
178
157
  - **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — 支持
179
158
 
180
159
  ## 权限、副作用与边界
181
160
 
182
- - **接入形态**:官方 Profile Bundle——`package.json` 声明 `dsh.bundle.patch: ./cordis.patch.yml`(loader 插入层),仓库提交可直接使用的预构建运行时制品(`lib/index.js`、`lib/invariant.js`、`lib/client.js`),无安装脚本、无 postinstall、无 native 二进制、安装时不执行任何构建。
161
+ - **接入形态**:官方 Profile Bundle——`package.json` 声明 `dsh.bundle.patch: ./cordis.patch.yml`(loader 插入层),仓库提交可直接使用的预构建运行时制品(`lib/index.js`、`lib/client.js`),无安装脚本、无 postinstall、无 native 二进制、安装时不执行任何构建。
183
162
  - **文件系统**:服务端仅在 `<dsh 主目录>/.dsh-any-background-data/` 内读写(配置 JSON、壁纸、轮换池、视频、字体),不触碰该目录之外的任何路径;配置写入为原子写(临时文件 + rename)。这些文件落在真实磁盘上,**不受 generation 恢复影响,也不会被其回滚**——清除它们即彻底重置插件。
184
163
  - **网络**:仅在用户主动粘贴 http/https 图片或视频网址并点击「应用」时发起一次出站请求下载该资源;除此之外无遥测、无外部服务调用。
185
164
  - **Shell / native**:无。不使用 `child_process`、不加载 native 模块、不运行动态下载的二进制。