dsh-dream-skin 0.2.0 → 0.2.2
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.en.md +15 -10
- package/README.md +14 -9
- package/lib/client.js +49 -24
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -24,6 +24,11 @@ Native skinning + wallpaper + theme packs — a romance-engineered project built
|
|
|
24
24
|
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
|
+
> 🚀 **Now on npm!** With DSH installed, add it in one command — no cloning needed:
|
|
28
|
+
> ```sh
|
|
29
|
+
> dsh plugin --profile web add dsh-dream-skin
|
|
30
|
+
> ```
|
|
31
|
+
|
|
27
32
|
> **Homage to [Codex-Dream-Skin](https://github.com/Fei-Away/Codex-Dream-Skin).** But the approach is different:
|
|
28
33
|
> Codex injects CSS into the desktop client's renderer via CDP, whereas DSH is a **token-driven Web GUI** that ships
|
|
29
34
|
> first-class "third-party plugins registering themes". So this plugin is **purely native** — no injection, no binary
|
|
@@ -74,13 +79,13 @@ Differentiation inspired by existing DSH skin projects plus Codex's skin UX:
|
|
|
74
79
|
|
|
75
80
|
```sh
|
|
76
81
|
# 1. install
|
|
77
|
-
dsh plugin --profile web add
|
|
82
|
+
dsh plugin --profile web add dsh-dream-skin
|
|
78
83
|
# 2. restart
|
|
79
84
|
dsh web
|
|
80
85
|
# 3. open Settings → General → Skins and pick one → done.
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
>
|
|
88
|
+
> Installs the published npm package — no cloning. If `dsh plugin add` reports a workspace error, append `-w`.
|
|
84
89
|
|
|
85
90
|
## 🧩 What kind of plugin is this
|
|
86
91
|
|
|
@@ -139,16 +144,12 @@ system.
|
|
|
139
144
|
|
|
140
145
|
## 📦 Install
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
### Option A: From source / a local directory
|
|
147
|
+
### Option A: From npm (published, **recommended**)
|
|
144
148
|
|
|
145
149
|
```sh
|
|
146
|
-
dsh plugin --profile web add
|
|
150
|
+
dsh plugin --profile web add dsh-dream-skin
|
|
147
151
|
```
|
|
148
152
|
|
|
149
|
-
> The `-w` flag is **required**: every profile ships a `pnpm-workspace.yaml`, so pnpm treats the profile directory
|
|
150
|
-
> as a workspace root and a bare `add` fails with `ERR_PNPM_ADDING_TO_ROOT`.
|
|
151
|
-
|
|
152
153
|
Then **restart** the web server:
|
|
153
154
|
|
|
154
155
|
```sh
|
|
@@ -158,10 +159,14 @@ dsh web
|
|
|
158
159
|
|
|
159
160
|
Open **Settings → General** to see the **Skins**, **Accent**, **Wallpaper** / **Advanced Wallpaper**, and **Theme Packs** rows.
|
|
160
161
|
|
|
161
|
-
|
|
162
|
+
> The `-w` (workspace) flag is needed on a bare `add` because every profile ships a `pnpm-workspace.yaml`; pnpm treats
|
|
163
|
+
> the profile directory as a workspace root, so a bare add fails with `ERR_PNPM_ADDING_TO_ROOT`. If your profile already
|
|
164
|
+
> uses the workspace, you won't need to repeat it.
|
|
165
|
+
|
|
166
|
+
### Option B: From source / a local directory (developers)
|
|
162
167
|
|
|
163
168
|
```sh
|
|
164
|
-
dsh plugin --profile web add -w dsh-dream-skin
|
|
169
|
+
dsh plugin --profile web add -w /path/to/dsh-dream-skin
|
|
165
170
|
```
|
|
166
171
|
|
|
167
172
|
## 🧩 Compatibility
|
package/README.md
CHANGED
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
|
+
> 🚀 **现已发布到 npm!** 装好 DSH 后,一条命令即可安装,无需 clone:
|
|
28
|
+
> ```sh
|
|
29
|
+
> dsh plugin --profile web add dsh-dream-skin
|
|
30
|
+
> ```
|
|
31
|
+
|
|
27
32
|
> **致敬 [Codex-Dream-Skin](https://github.com/Fei-Away/Codex-Dream-Skin)。** 但实现路径不同:Codex 是往桌面客户端渲染进程
|
|
28
33
|
> 注入 CSS(CDP),而 DSH 本身是 **token 驱动的 Web GUI**,官方就提供了「第三方插件注册主题」的能力——所以本插件是
|
|
29
34
|
> **纯原生接入**,无注入、不改二进制、不因客户端更新失效。
|
|
@@ -126,25 +131,22 @@ DeepSeek Harness 的口号是「一切皆插件」:模型、工具、沙箱、
|
|
|
126
131
|
|
|
127
132
|
```sh
|
|
128
133
|
# 1. 安装
|
|
129
|
-
dsh plugin --profile web add
|
|
134
|
+
dsh plugin --profile web add dsh-dream-skin
|
|
130
135
|
# 2. 重启
|
|
131
136
|
dsh web
|
|
132
137
|
# 3. 打开 设置 → 常规 → 皮肤,挑一套 → 完。
|
|
133
138
|
```
|
|
134
139
|
|
|
135
|
-
>
|
|
140
|
+
> 装的是 npm 已完成发布的正式包,无需 clone。若 `dsh plugin add` 报 workspace 相关错误,补一个 `-w` 即可。
|
|
136
141
|
|
|
137
142
|
## 📦 安装
|
|
138
143
|
|
|
139
|
-
###
|
|
144
|
+
### 方式一:npm(已发布,**推荐**)
|
|
140
145
|
|
|
141
146
|
```sh
|
|
142
|
-
dsh plugin --profile web add
|
|
147
|
+
dsh plugin --profile web add dsh-dream-skin
|
|
143
148
|
```
|
|
144
149
|
|
|
145
|
-
> `-w` 标志**必需**:每个 profile 自带 `pnpm-workspace.yaml`,pnpm 会把它当作 workspace 根,裸 `add` 会报
|
|
146
|
-
> `ERR_PNPM_ADDING_TO_ROOT`。
|
|
147
|
-
|
|
148
150
|
然后**重启** web 服务:
|
|
149
151
|
|
|
150
152
|
```sh
|
|
@@ -154,10 +156,13 @@ dsh web
|
|
|
154
156
|
|
|
155
157
|
打开 **设置 → 常规**,即可看到「皮肤」「强调色」「背景图片 / 高级壁纸」与「主题包」等行。
|
|
156
158
|
|
|
157
|
-
|
|
159
|
+
> `-w` 标志在裸 `add` 时必需:每个 profile 自带 `pnpm-workspace.yaml`,pnpm 会把它当作 workspace 根,裸加报错
|
|
160
|
+
> `ERR_PNPM_ADDING_TO_ROOT`。若已加过 `-w`,后续用现有 workspace 即无需重复。
|
|
161
|
+
|
|
162
|
+
### 方式二:从源码 / 本地目录(开发者)
|
|
158
163
|
|
|
159
164
|
```sh
|
|
160
|
-
dsh plugin --profile web add -w dsh-dream-skin
|
|
165
|
+
dsh plugin --profile web add -w /path/to/dsh-dream-skin
|
|
161
166
|
```
|
|
162
167
|
|
|
163
168
|
## 🧩 兼容性
|
package/lib/client.js
CHANGED
|
@@ -328,7 +328,7 @@ window.__ModuleLoader__.load({
|
|
|
328
328
|
|
|
329
329
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
330
330
|
const zh = {
|
|
331
|
-
"skin.title": "
|
|
331
|
+
"skin.title": "皮肤",
|
|
332
332
|
"skin.default": "默认",
|
|
333
333
|
"skin.abyss": "深海渊",
|
|
334
334
|
"skin.aurora": "极光",
|
|
@@ -365,7 +365,7 @@ window.__ModuleLoader__.load({
|
|
|
365
365
|
|
|
366
366
|
/** English dictionary, checked complete against the zh key set. */
|
|
367
367
|
const en = {
|
|
368
|
-
"skin.title": "Skins
|
|
368
|
+
"skin.title": "Skins",
|
|
369
369
|
"skin.default": "Default",
|
|
370
370
|
"skin.abyss": "Abyss",
|
|
371
371
|
"skin.aurora": "Aurora",
|
|
@@ -1098,6 +1098,7 @@ window.__ModuleLoader__.load({
|
|
|
1098
1098
|
"aria-pressed": gradient === g,
|
|
1099
1099
|
style: {
|
|
1100
1100
|
...styles.presetswatches,
|
|
1101
|
+
background: g,
|
|
1101
1102
|
...(gradient === g ? { outline: "2px solid var(--dsw-alias-brand-primary)" } : {})
|
|
1102
1103
|
},
|
|
1103
1104
|
onClick: () => setGradient(g),
|
|
@@ -1629,26 +1630,39 @@ window.__ModuleLoader__.load({
|
|
|
1629
1630
|
return data ? `url("${data}")` : null;
|
|
1630
1631
|
}
|
|
1631
1632
|
|
|
1633
|
+
/** Guards against re-entrant wallp-paper re-shading (overrideTokens emits theme/change). */
|
|
1634
|
+
let _applyingWallpaper = false;
|
|
1635
|
+
|
|
1632
1636
|
/** Re-render the wallpaper backdrop from the current config. */
|
|
1633
1637
|
function applyWallpaper2(ctx) {
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1638
|
+
// Re-entrancy guard: overrideTokens() below emits `theme/change`, which our
|
|
1639
|
+
// syncSkin listener would answer by calling applyWallpaper2 again — that
|
|
1640
|
+
// recursion would overflow the stack. Applying while already applying is a
|
|
1641
|
+
// no-op; the first (outermost) call performs the shading.
|
|
1642
|
+
if (_applyingWallpaper) return;
|
|
1643
|
+
_applyingWallpaper = true;
|
|
1644
|
+
try {
|
|
1645
|
+
const bg = wallpaperBackgroundCss();
|
|
1646
|
+
const urlIsSet = bg !== null;
|
|
1647
|
+
if (!urlIsSet) {
|
|
1648
|
+
teardownWallpaper();
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
if (wallpaperEl === null || !document.body.contains(wallpaperEl)) {
|
|
1652
|
+
wallpaperEl = document.createElement("div");
|
|
1653
|
+
wallpaperEl.style.cssText = "position:fixed;inset:0;z-index:-1;pointer-events:none;background-size:cover;background-position:center;background-repeat:no-repeat;";
|
|
1654
|
+
document.body.prepend(wallpaperEl);
|
|
1655
|
+
}
|
|
1656
|
+
const blur = readWallpaperBlur();
|
|
1657
|
+
wallpaperEl.style.backgroundImage = bg;
|
|
1658
|
+
wallpaperEl.style.filter = blur > 0 ? `blur(${blur}px)` : "none";
|
|
1659
|
+
// Auto-dim lowers the wash opacity when enabled.
|
|
1660
|
+
const baseFill = readWallpaperOpacity();
|
|
1661
|
+
const wash = readWallpaperAutodim() ? Math.min(baseFill, 0.45) : baseFill;
|
|
1662
|
+
shadeTokens2(ctx, wash, wash);
|
|
1663
|
+
} finally {
|
|
1664
|
+
_applyingWallpaper = false;
|
|
1644
1665
|
}
|
|
1645
|
-
const blur = readWallpaperBlur();
|
|
1646
|
-
wallpaperEl.style.backgroundImage = bg;
|
|
1647
|
-
wallpaperEl.style.filter = blur > 0 ? `blur(${blur}px)` : "none";
|
|
1648
|
-
// Auto-dim lowers the wash opacity when enabled.
|
|
1649
|
-
const baseFill = readWallpaperOpacity();
|
|
1650
|
-
const wash = readWallpaperAutodim() ? Math.min(baseFill, 0.45) : baseFill;
|
|
1651
|
-
shadeTokens2(ctx, wash, wash);
|
|
1652
1666
|
}
|
|
1653
1667
|
|
|
1654
1668
|
/** Like the original shadeTokens but with configurable alphas for the wash. */
|
|
@@ -1730,6 +1744,7 @@ window.__ModuleLoader__.load({
|
|
|
1730
1744
|
const accent = useStore((s) => s.accent);
|
|
1731
1745
|
const base = useStore((s) => s.base);
|
|
1732
1746
|
const activeValue = accent !== DEFAULT_ACCENT ? accent : base;
|
|
1747
|
+
const inputValue = normalizeHex(activeValue) || "#4f83f2";
|
|
1733
1748
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1734
1749
|
style: styles.group,
|
|
1735
1750
|
children: [
|
|
@@ -1742,7 +1757,7 @@ window.__ModuleLoader__.load({
|
|
|
1742
1757
|
children: [
|
|
1743
1758
|
(0, react_jsx_runtime.jsx)("input", {
|
|
1744
1759
|
type: "color",
|
|
1745
|
-
value:
|
|
1760
|
+
value: inputValue,
|
|
1746
1761
|
style: { ...styles.swatch, width: "40px", height: "32px", padding: 0, border: "none", borderRadius: "8px", cursor: "pointer" },
|
|
1747
1762
|
onChange: (event) => setAccent(event.target.value)
|
|
1748
1763
|
}),
|
|
@@ -1951,7 +1966,9 @@ window.__ModuleLoader__.load({
|
|
|
1951
1966
|
let wallpaperBound;
|
|
1952
1967
|
const syncWallpaper = () => {
|
|
1953
1968
|
wallpaperRevision += 1;
|
|
1954
|
-
|
|
1969
|
+
// Store the raw data URL (not the CSS url(...) wrapper) so the
|
|
1970
|
+
// Wallpaper row can render an <img> preview and test `url !== null`.
|
|
1971
|
+
wallpaperBound?.sync(readWallpaper(), readWallpaperOpacity(), readWallpaperBlur(), wallpaperRevision);
|
|
1955
1972
|
};
|
|
1956
1973
|
applyWallpaper2(ctx);
|
|
1957
1974
|
syncWallpaper();
|
|
@@ -2094,6 +2111,7 @@ window.__ModuleLoader__.load({
|
|
|
2094
2111
|
// P0: per-user accent override row.
|
|
2095
2112
|
const accentStore = createAccentStore();
|
|
2096
2113
|
let accentBound;
|
|
2114
|
+
let accentRevision = 0;
|
|
2097
2115
|
const accentInjected = (actions) => {
|
|
2098
2116
|
accentBound = actions;
|
|
2099
2117
|
const base = resolveAccent(ctx.theme.getTheme()) || DEFAULT_ACCENT;
|
|
@@ -2101,12 +2119,19 @@ window.__ModuleLoader__.load({
|
|
|
2101
2119
|
return {
|
|
2102
2120
|
setAccent: (value) => {
|
|
2103
2121
|
const applied = setAccent(ctx, value === DEFAULT_ACCENT ? null : value);
|
|
2104
|
-
accentBound?.sync(
|
|
2122
|
+
accentBound?.sync(
|
|
2123
|
+
applied || DEFAULT_ACCENT,
|
|
2124
|
+
resolveAccent(ctx.theme.getTheme()) || DEFAULT_ACCENT,
|
|
2125
|
+
++accentRevision
|
|
2126
|
+
);
|
|
2105
2127
|
},
|
|
2106
2128
|
clearAccent: () => {
|
|
2107
2129
|
setAccent(ctx, null);
|
|
2108
|
-
accentBound?.sync(
|
|
2109
|
-
|
|
2130
|
+
accentBound?.sync(
|
|
2131
|
+
DEFAULT_ACCENT,
|
|
2132
|
+
resolveAccent(ctx.theme.getTheme()) || DEFAULT_ACCENT,
|
|
2133
|
+
++accentRevision
|
|
2134
|
+
);
|
|
2110
2135
|
}
|
|
2111
2136
|
};
|
|
2112
2137
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-dream-skin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "DeepSeek Harness 换肤插件 (Dream Skin for DeepSeek Harness): curated --dsw-alias-* theme presets, a custom translucent wallpaper with opacity/blur controls, theme-pack import/export + share links, per-user accent, favorites & surprise-me, and durable per-browser persistence — in the spirit of the Codex Dream Skin project.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|