dsh-theme-mineradio 0.1.0
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 +90 -0
- package/cordis.patch.yml +6 -0
- package/dist/client.cjs +88 -0
- package/dist/index.cjs +79 -0
- package/lib/index.d.ts +18 -0
- package/lib/index.js +20 -0
- package/lib/theme.d.ts +31 -0
- package/lib/theme.js +44 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# dsh-theme-mineradio
|
|
2
|
+
|
|
3
|
+
把 **Mineradio**([github.com/XxHuberrr/Mineradio](https://github.com/XxHuberrr/Mineradio))的 UI 视觉风格移植成 **DeepSeek Harness (dsh) Web UI 主题插件**。
|
|
4
|
+
|
|
5
|
+
风格定位:暗色玻璃拟态(Glassmorphism)+ 青/金霓虹,外加一层**电影感漂移光晕的动态背景**。
|
|
6
|
+
|
|
7
|
+
- 招牌青 `#00F5D4`、香槟金 `#f4d28a`、近黑底 `#08090B`、大量 `backdrop-blur` 与青色微光阴影
|
|
8
|
+
- 动态背景:青 / 金 / 青蓝三团光晕用 CSS `@keyframes` 缓慢漂移,尊重 `prefers-reduced-motion`
|
|
9
|
+
- UI 表面半透明,光晕从缝隙透出,复刻 Mineradio 的「沉浸式」观感
|
|
10
|
+
|
|
11
|
+
> 仅作视觉风格参考移植,配色与动画为按其公开的 `index.css` 还原;Mineradio 的界面视觉设计与原创表达归原作者所有。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 它到底改了什么(原理)
|
|
16
|
+
|
|
17
|
+
dsh 的 Web UI 配色是一套两层 CSS 变量:`--dsw-static-*`(静态色板)和 `--dsw-alias-*`(语义别名,100+ 个)。本插件做两件事,全部在**浏览器半(Client half)**完成:
|
|
18
|
+
|
|
19
|
+
1. **注册主题**:`ctx.theme.register(theme)` 把 Mineradio 配色映射进 `--dsw-alias-*`。注册后主题出现在 dsh 内置「设置 → 外观 / 主题」切换器,选择由 dsh 自己的 `ui-theme` 命名空间持久化(跨重启保留)。
|
|
20
|
+
2. **注入动态背景层**:在 `document.body` 挂一个 `position: fixed; z-index: -1` 的全屏层,里面跑 CSS 动画光晕。因为主题把 UI 表面设成了半透明(`rgba(...)`),光晕会从面板缝隙透出来。
|
|
21
|
+
|
|
22
|
+
全程**零侵入核心 UI、不需要 Host 半、不踩浏览器侧 settings 白名单**(`settings-not-exposed`)。
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 文件结构
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
project_017+dsh-theme-plugin/
|
|
30
|
+
├── package.json # 含 dsh.client 声明 + exports["./client"]
|
|
31
|
+
├── tsconfig.json # Host 半(Node)编译配置
|
|
32
|
+
├── tsdown.config.ts # 浏览器半打包(单文件 CJS)
|
|
33
|
+
├── cordis.patch.yml # 手动安装时贴进 profiles/web/cordis.patch.yml
|
|
34
|
+
├── scripts/
|
|
35
|
+
│ └── wrap-client.mjs # 把 CJS bundle 包成 DSH 的 __ModuleLoader__ 工厂
|
|
36
|
+
├── src/
|
|
37
|
+
│ ├── theme.ts # ★ 配色在这里(Mineradio 真实色值 → --dsw-alias-*)
|
|
38
|
+
│ ├── client/index.ts # ★ 浏览器半:注册主题 + 注入动态背景层
|
|
39
|
+
│ └── index.ts # Host 半最小占位(可选扩展点)
|
|
40
|
+
└── README.md
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**你以后只改两处**:
|
|
44
|
+
- `src/theme.ts` —— 调色板(改色值即可换肤)。
|
|
45
|
+
- `src/client/index.ts` 里 `injectBackgroundLayer()` 的 `<style>` —— 动态光晕的颜色 / 形状 / 动画节奏。
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 本地构建
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cd project_017+dsh-theme-plugin
|
|
53
|
+
npm install
|
|
54
|
+
npm run build
|
|
55
|
+
# 产物:lib/index.js(Host 半) + dist/client.cjs(浏览器半,已包成 ModuleLoader 工厂)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> 构建链:tsdown 把 `src/client/index.ts` 打成单文件 CJS,再用 `scripts/wrap-client.mjs` 包成 dsh 要求的 `window.__ModuleLoader__.load({ id, factory })`。`tsdown` 版本写成 `>=0.4.0`,安装时取最新即可。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 安装进 dsh web
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# 1. 构建(见上)
|
|
66
|
+
# 2. 安装进 web profile(用本包的绝对路径)
|
|
67
|
+
dsh plugin --profile web add "file:<本包绝对路径>"
|
|
68
|
+
|
|
69
|
+
# 3. 确保 $DSH_HOME/profiles/web/cordis.patch.yml 里有这一段
|
|
70
|
+
# (dsh plugin add 通常会自动写入;手动装则贴 cordis.patch.yml 内容)
|
|
71
|
+
# - insert:
|
|
72
|
+
# - id: dsh-theme-mineradio
|
|
73
|
+
# name: 'dsh-theme-mineradio'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
重启 `dsh web`,打开「设置 → 外观 / 主题」,选择 **mineradio**,即可看到暗色玻璃 + 青金光晕漂移动态背景。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 调优与排错
|
|
81
|
+
|
|
82
|
+
- **光晕没透出来?** 多半是 `--dsw-alias-bg-*` 的令牌名与 dsh 实际不一致。打开 dsh 随包分发的 `dsh-client-ui-theme` README 核对真实令牌名(例如底色可能叫 `--dsw-alias-canvas` / `--dsw-alias-surface` 等),在 `src/theme.ts` 改成对的名字即可。未知令牌名 dsh 会直接忽略、不报错。
|
|
83
|
+
- **文字看不清?** 保持 `--dsw-alias-bg-layer-2`(面板)接近不透明(已设为 `rgba(14,16,20,0.92)`)。这是壁纸皮肤插件 `dsh-skin-alphacoders` 实测出来的坑:全表面半透明会让文字糊掉。
|
|
84
|
+
- **想让用户调动画 / 选配色并持久化?** 浏览器侧走 `api-proxy` 会被 settings 白名单拦下。需要在 **Host 半**用 `ctx.settings.register('ui-mineradio', schema)` 持有 owner scope,再用 `ctx.webServer.register({ kind:'prefix', path:'/mineradio', handler })` 给浏览器侧开同源读写通道(参考 `dsh-skin-alphacoders`)。
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 许可证
|
|
89
|
+
|
|
90
|
+
MIT。视觉风格参考自 Mineradio,原作者保留其界面视觉设计的著作权。
|
package/cordis.patch.yml
ADDED
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "dsh-theme-mineradio",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} }
|
|
5
|
+
var exports = module.exports
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
//#region src/theme.ts
|
|
8
|
+
const theme = {
|
|
9
|
+
id: "mineradio",
|
|
10
|
+
colorScheme: "dark",
|
|
11
|
+
tokens: {
|
|
12
|
+
"--dsw-alias-bg-base": "rgba(8, 9, 11, 0.42)",
|
|
13
|
+
"--dsw-alias-bg-layer-1": "rgba(14, 16, 20, 0.55)",
|
|
14
|
+
"--dsw-alias-bg-layer-2": "rgba(14, 16, 20, 0.92)",
|
|
15
|
+
"--dsw-alias-text-base": "#E8ECEF",
|
|
16
|
+
"--dsw-alias-text-muted": "#8A9099",
|
|
17
|
+
"--dsw-alias-text-on-fill": "#061116",
|
|
18
|
+
"--dsw-alias-brand-primary": "#00F5D4",
|
|
19
|
+
"--dsw-alias-brand-secondary": "#f4d28a",
|
|
20
|
+
"--dsw-alias-button-primary-fill": "#00F5D4",
|
|
21
|
+
"--dsw-alias-button-primary-fill-hover": "#37F7DF",
|
|
22
|
+
"--dsw-alias-border-subtle": "rgba(0, 245, 212, 0.16)",
|
|
23
|
+
"--dsw-alias-border-strong": "rgba(0, 245, 212, 0.34)",
|
|
24
|
+
"--dsw-alias-success": "#45D68F",
|
|
25
|
+
"--dsw-alias-warning": "#f4d28a",
|
|
26
|
+
"--dsw-alias-danger": "#FF5367"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/client/index.ts
|
|
31
|
+
/** Cordis 插件名(保持与 package.json 的 name 一致)。 */
|
|
32
|
+
const name = "dsh-theme-mineradio";
|
|
33
|
+
/** 声明本插件需要的服务:ctx.theme(ThemeRuntime)。 */
|
|
34
|
+
const inject = ["theme"];
|
|
35
|
+
const LAYER_ID = "mineradio-bg-layer";
|
|
36
|
+
/** 注入动态背景层(幂等:已存在则直接返回)。 */
|
|
37
|
+
function injectBackgroundLayer() {
|
|
38
|
+
const existing = document.getElementById(LAYER_ID);
|
|
39
|
+
if (existing) return existing;
|
|
40
|
+
const style = document.createElement("style");
|
|
41
|
+
style.textContent = `
|
|
42
|
+
#${LAYER_ID} {
|
|
43
|
+
position: fixed; inset: 0; z-index: -1; pointer-events: none;
|
|
44
|
+
background:
|
|
45
|
+
radial-gradient(40% 50% at 20% 25%, rgba(0,245,212,0.20), transparent 60%),
|
|
46
|
+
radial-gradient(45% 55% at 80% 30%, rgba(244,210,138,0.16), transparent 60%),
|
|
47
|
+
radial-gradient(50% 60% at 50% 85%, rgba(143,233,255,0.14), transparent 62%),
|
|
48
|
+
#000;
|
|
49
|
+
filter: saturate(1.1);
|
|
50
|
+
}
|
|
51
|
+
#${LAYER_ID}::before, #${LAYER_ID}::after {
|
|
52
|
+
content: ""; position: absolute; inset: -20%;
|
|
53
|
+
background:
|
|
54
|
+
radial-gradient(35% 35% at 30% 40%, rgba(0,245,212,0.18), transparent 60%),
|
|
55
|
+
radial-gradient(30% 30% at 70% 60%, rgba(244,210,138,0.14), transparent 60%);
|
|
56
|
+
mix-blend-mode: screen;
|
|
57
|
+
}
|
|
58
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
59
|
+
#${LAYER_ID}::before { animation: mr-drift-a 26s ease-in-out infinite alternate; }
|
|
60
|
+
#${LAYER_ID}::after { animation: mr-drift-b 34s ease-in-out infinite alternate; }
|
|
61
|
+
}
|
|
62
|
+
@keyframes mr-drift-a {
|
|
63
|
+
from { transform: translate3d(-4%, -3%, 0) scale(1); }
|
|
64
|
+
to { transform: translate3d(6%, 4%, 0) scale(1.15); }
|
|
65
|
+
}
|
|
66
|
+
@keyframes mr-drift-b {
|
|
67
|
+
from { transform: translate3d(5%, 2%, 0) scale(1.1); }
|
|
68
|
+
to { transform: translate3d(-5%, -4%, 0) scale(1); }
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
document.head.appendChild(style);
|
|
72
|
+
const layer = document.createElement("div");
|
|
73
|
+
layer.id = LAYER_ID;
|
|
74
|
+
document.body.appendChild(layer);
|
|
75
|
+
return layer;
|
|
76
|
+
}
|
|
77
|
+
function apply(ctx) {
|
|
78
|
+
ctx.theme.register(theme);
|
|
79
|
+
injectBackgroundLayer();
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
exports.apply = apply;
|
|
83
|
+
exports.inject = inject;
|
|
84
|
+
exports.name = name;
|
|
85
|
+
|
|
86
|
+
return module.exports
|
|
87
|
+
}
|
|
88
|
+
})
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/theme.ts
|
|
3
|
+
const theme = {
|
|
4
|
+
id: "mineradio",
|
|
5
|
+
colorScheme: "dark",
|
|
6
|
+
tokens: {
|
|
7
|
+
"--dsw-alias-bg-base": "rgba(8, 9, 11, 0.42)",
|
|
8
|
+
"--dsw-alias-bg-layer-1": "rgba(14, 16, 20, 0.55)",
|
|
9
|
+
"--dsw-alias-bg-layer-2": "rgba(14, 16, 20, 0.92)",
|
|
10
|
+
"--dsw-alias-text-base": "#E8ECEF",
|
|
11
|
+
"--dsw-alias-text-muted": "#8A9099",
|
|
12
|
+
"--dsw-alias-text-on-fill": "#061116",
|
|
13
|
+
"--dsw-alias-brand-primary": "#00F5D4",
|
|
14
|
+
"--dsw-alias-brand-secondary": "#f4d28a",
|
|
15
|
+
"--dsw-alias-button-primary-fill": "#00F5D4",
|
|
16
|
+
"--dsw-alias-button-primary-fill-hover": "#37F7DF",
|
|
17
|
+
"--dsw-alias-border-subtle": "rgba(0, 245, 212, 0.16)",
|
|
18
|
+
"--dsw-alias-border-strong": "rgba(0, 245, 212, 0.34)",
|
|
19
|
+
"--dsw-alias-success": "#45D68F",
|
|
20
|
+
"--dsw-alias-warning": "#f4d28a",
|
|
21
|
+
"--dsw-alias-danger": "#FF5367"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/client/index.ts
|
|
26
|
+
/** Cordis 插件名(保持与 package.json 的 name 一致)。 */
|
|
27
|
+
const name = "dsh-theme-mineradio";
|
|
28
|
+
/** 声明本插件需要的服务:ctx.theme(ThemeRuntime)。 */
|
|
29
|
+
const inject = ["theme"];
|
|
30
|
+
const LAYER_ID = "mineradio-bg-layer";
|
|
31
|
+
/** 注入动态背景层(幂等:已存在则直接返回)。 */
|
|
32
|
+
function injectBackgroundLayer() {
|
|
33
|
+
const existing = document.getElementById(LAYER_ID);
|
|
34
|
+
if (existing) return existing;
|
|
35
|
+
const style = document.createElement("style");
|
|
36
|
+
style.textContent = `
|
|
37
|
+
#${LAYER_ID} {
|
|
38
|
+
position: fixed; inset: 0; z-index: -1; pointer-events: none;
|
|
39
|
+
background:
|
|
40
|
+
radial-gradient(40% 50% at 20% 25%, rgba(0,245,212,0.20), transparent 60%),
|
|
41
|
+
radial-gradient(45% 55% at 80% 30%, rgba(244,210,138,0.16), transparent 60%),
|
|
42
|
+
radial-gradient(50% 60% at 50% 85%, rgba(143,233,255,0.14), transparent 62%),
|
|
43
|
+
#000;
|
|
44
|
+
filter: saturate(1.1);
|
|
45
|
+
}
|
|
46
|
+
#${LAYER_ID}::before, #${LAYER_ID}::after {
|
|
47
|
+
content: ""; position: absolute; inset: -20%;
|
|
48
|
+
background:
|
|
49
|
+
radial-gradient(35% 35% at 30% 40%, rgba(0,245,212,0.18), transparent 60%),
|
|
50
|
+
radial-gradient(30% 30% at 70% 60%, rgba(244,210,138,0.14), transparent 60%);
|
|
51
|
+
mix-blend-mode: screen;
|
|
52
|
+
}
|
|
53
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
54
|
+
#${LAYER_ID}::before { animation: mr-drift-a 26s ease-in-out infinite alternate; }
|
|
55
|
+
#${LAYER_ID}::after { animation: mr-drift-b 34s ease-in-out infinite alternate; }
|
|
56
|
+
}
|
|
57
|
+
@keyframes mr-drift-a {
|
|
58
|
+
from { transform: translate3d(-4%, -3%, 0) scale(1); }
|
|
59
|
+
to { transform: translate3d(6%, 4%, 0) scale(1.15); }
|
|
60
|
+
}
|
|
61
|
+
@keyframes mr-drift-b {
|
|
62
|
+
from { transform: translate3d(5%, 2%, 0) scale(1.1); }
|
|
63
|
+
to { transform: translate3d(-5%, -4%, 0) scale(1); }
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
document.head.appendChild(style);
|
|
67
|
+
const layer = document.createElement("div");
|
|
68
|
+
layer.id = LAYER_ID;
|
|
69
|
+
document.body.appendChild(layer);
|
|
70
|
+
return layer;
|
|
71
|
+
}
|
|
72
|
+
function apply(ctx) {
|
|
73
|
+
ctx.theme.register(theme);
|
|
74
|
+
injectBackgroundLayer();
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.apply = apply;
|
|
78
|
+
exports.inject = inject;
|
|
79
|
+
exports.name = name;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mineradio 主题插件 —— Node 半(Host half,可选)
|
|
3
|
+
* ---------------------------------------------------------------
|
|
4
|
+
* 纯「换色 + 动态背景」主题插件在 Client 半就能完成,无需 Host 逻辑。
|
|
5
|
+
* 这里保留一个最小占位,满足「包必须有 exports['.'] 入口」的约定,
|
|
6
|
+
* 也方便你将来扩展:
|
|
7
|
+
*
|
|
8
|
+
* - 若要让用户「调动画速度 / 选光晕配色」并持久化:
|
|
9
|
+
* 浏览器侧走 api-proxy 会被 settings 白名单拦下(settings-not-exposed)。
|
|
10
|
+
* 正确做法是在 Host 半用 ctx.settings.register('ui-mineradio', schema)
|
|
11
|
+
* 持有 owner scope,再用
|
|
12
|
+
* ctx.webServer.register({ kind: 'prefix', path: '/mineradio', handler })
|
|
13
|
+
* 给浏览器侧开一个同源读写通道。详见 dsh-skin-alphacoders 的实现。
|
|
14
|
+
*/
|
|
15
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
16
|
+
export declare const name = "dsh-theme-mineradio";
|
|
17
|
+
export declare const inject: string[];
|
|
18
|
+
export declare function apply(_ctx: Context): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mineradio 主题插件 —— Node 半(Host half,可选)
|
|
3
|
+
* ---------------------------------------------------------------
|
|
4
|
+
* 纯「换色 + 动态背景」主题插件在 Client 半就能完成,无需 Host 逻辑。
|
|
5
|
+
* 这里保留一个最小占位,满足「包必须有 exports['.'] 入口」的约定,
|
|
6
|
+
* 也方便你将来扩展:
|
|
7
|
+
*
|
|
8
|
+
* - 若要让用户「调动画速度 / 选光晕配色」并持久化:
|
|
9
|
+
* 浏览器侧走 api-proxy 会被 settings 白名单拦下(settings-not-exposed)。
|
|
10
|
+
* 正确做法是在 Host 半用 ctx.settings.register('ui-mineradio', schema)
|
|
11
|
+
* 持有 owner scope,再用
|
|
12
|
+
* ctx.webServer.register({ kind: 'prefix', path: '/mineradio', handler })
|
|
13
|
+
* 给浏览器侧开一个同源读写通道。详见 dsh-skin-alphacoders 的实现。
|
|
14
|
+
*/
|
|
15
|
+
export const name = 'dsh-theme-mineradio';
|
|
16
|
+
export const inject = [];
|
|
17
|
+
export function apply(_ctx) {
|
|
18
|
+
// 纯主题插件:Host 半无需做任何事。
|
|
19
|
+
// 需要 Host 能力时再在这里写逻辑。
|
|
20
|
+
}
|
package/lib/theme.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mineradio 主题定义(移植自 github.com/XxHuberrr/Mineradio,已获视觉风格参考)
|
|
3
|
+
* ---------------------------------------------------------------
|
|
4
|
+
* 提取到的 Mineradio 真实配色(暗色玻璃拟态 + 青/金霓虹):
|
|
5
|
+
* 基础 --fc-bg #08090B · --fc-paper #0E1014 · --fc-ink #E8ECEF
|
|
6
|
+
* --fc-muted #8A9099 · --fc-hair #1A1D22 / #262A31
|
|
7
|
+
* 招牌强调 --home-accent #00F5D4(青)· --champagne #f4d28a(香槟金)
|
|
8
|
+
* --fc-blue #2442ff · --chill-cyan #8fe9ff · --chill-mint #9cffdf
|
|
9
|
+
* 玻璃边 --glass-border rgba(0,245,212,.30),阴影带青色微光
|
|
10
|
+
* 字体 --font-sans: Noto Sans SC / PingFang SC / HarmonyOS Sans SC / Inter / system-ui
|
|
11
|
+
*
|
|
12
|
+
* 下面把这套配色映射到 DSH 的 --dsw-alias-* 语义令牌。
|
|
13
|
+
* 注意:未知令牌名 DSH 会直接忽略、不会报错,所以可放心补充/修正。
|
|
14
|
+
* 完整令牌清单见 DSH 随包分发的 dsh-client-ui-theme README(100+ 个)。
|
|
15
|
+
*/
|
|
16
|
+
/** 单个主题的令牌覆盖层:键是 --dsw-alias-* 变量名,值是 CSS 颜色。 */
|
|
17
|
+
export type ThemeTokens = Record<string, string>;
|
|
18
|
+
/** 通过 ctx.theme.register() 注册的主题定义。 */
|
|
19
|
+
export interface ThemeDefinition {
|
|
20
|
+
/** 主题唯一 id(切换、持久化都靠它)。改名后旧选择会失效。 */
|
|
21
|
+
id: string;
|
|
22
|
+
/**
|
|
23
|
+
* 基于哪种基础色板:'dark' → DSH 把正文/边框等对比令牌设为浅色。
|
|
24
|
+
* Mineradio 是暗色界面,务必填 'dark'。
|
|
25
|
+
*/
|
|
26
|
+
colorScheme: 'light' | 'dark';
|
|
27
|
+
/** 要覆盖的 --dsw-alias-* 语义令牌。只写要改的,没写的沿用默认。 */
|
|
28
|
+
tokens: ThemeTokens;
|
|
29
|
+
}
|
|
30
|
+
export declare const theme: ThemeDefinition;
|
|
31
|
+
export default theme;
|
package/lib/theme.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mineradio 主题定义(移植自 github.com/XxHuberrr/Mineradio,已获视觉风格参考)
|
|
3
|
+
* ---------------------------------------------------------------
|
|
4
|
+
* 提取到的 Mineradio 真实配色(暗色玻璃拟态 + 青/金霓虹):
|
|
5
|
+
* 基础 --fc-bg #08090B · --fc-paper #0E1014 · --fc-ink #E8ECEF
|
|
6
|
+
* --fc-muted #8A9099 · --fc-hair #1A1D22 / #262A31
|
|
7
|
+
* 招牌强调 --home-accent #00F5D4(青)· --champagne #f4d28a(香槟金)
|
|
8
|
+
* --fc-blue #2442ff · --chill-cyan #8fe9ff · --chill-mint #9cffdf
|
|
9
|
+
* 玻璃边 --glass-border rgba(0,245,212,.30),阴影带青色微光
|
|
10
|
+
* 字体 --font-sans: Noto Sans SC / PingFang SC / HarmonyOS Sans SC / Inter / system-ui
|
|
11
|
+
*
|
|
12
|
+
* 下面把这套配色映射到 DSH 的 --dsw-alias-* 语义令牌。
|
|
13
|
+
* 注意:未知令牌名 DSH 会直接忽略、不会报错,所以可放心补充/修正。
|
|
14
|
+
* 完整令牌清单见 DSH 随包分发的 dsh-client-ui-theme README(100+ 个)。
|
|
15
|
+
*/
|
|
16
|
+
export const theme = {
|
|
17
|
+
id: 'mineradio',
|
|
18
|
+
colorScheme: 'dark',
|
|
19
|
+
tokens: {
|
|
20
|
+
// —— 背景:做成半透明,让 client 注入的「电影感动态光晕」从缝隙透出来 ——
|
|
21
|
+
// 若 DSH 实际用到的底色令牌名不同,这里改一下即可;未知名会被忽略。
|
|
22
|
+
'--dsw-alias-bg-base': 'rgba(8, 9, 11, 0.42)',
|
|
23
|
+
'--dsw-alias-bg-layer-1': 'rgba(14, 16, 20, 0.55)',
|
|
24
|
+
'--dsw-alias-bg-layer-2': 'rgba(14, 16, 20, 0.92)', // 面板近不透明,保证文字清晰(壁纸插件的踩坑)
|
|
25
|
+
// —— 文字 ——
|
|
26
|
+
'--dsw-alias-text-base': '#E8ECEF',
|
|
27
|
+
'--dsw-alias-text-muted': '#8A9099',
|
|
28
|
+
'--dsw-alias-text-on-fill': '#061116',
|
|
29
|
+
// —— 品牌 / 强调:招牌青 + 香槟金 ——
|
|
30
|
+
'--dsw-alias-brand-primary': '#00F5D4',
|
|
31
|
+
'--dsw-alias-brand-secondary': '#f4d28a',
|
|
32
|
+
// —— 按钮 ——
|
|
33
|
+
'--dsw-alias-button-primary-fill': '#00F5D4',
|
|
34
|
+
'--dsw-alias-button-primary-fill-hover': '#37F7DF',
|
|
35
|
+
// —— 边框:青色微光玻璃边 ——
|
|
36
|
+
'--dsw-alias-border-subtle': 'rgba(0, 245, 212, 0.16)',
|
|
37
|
+
'--dsw-alias-border-strong': 'rgba(0, 245, 212, 0.34)',
|
|
38
|
+
// —— 状态色 ——
|
|
39
|
+
'--dsw-alias-success': '#45D68F',
|
|
40
|
+
'--dsw-alias-warning': '#f4d28a',
|
|
41
|
+
'--dsw-alias-danger': '#FF5367',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
export default theme;
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-theme-mineradio",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DSH (DeepSeek Harness) Web UI theme — ports the Mineradio music player's dark glassmorphism look (teal/champagne neon) with a cinematic drifting-glow dynamic background.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"dsh",
|
|
9
|
+
"dsh-plugin",
|
|
10
|
+
"deepseek-harness",
|
|
11
|
+
"theme",
|
|
12
|
+
"skin",
|
|
13
|
+
"mineradio",
|
|
14
|
+
"glassmorphism",
|
|
15
|
+
"dynamic-background"
|
|
16
|
+
],
|
|
17
|
+
"main": "./lib/index.js",
|
|
18
|
+
"types": "./lib/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./lib/index.d.ts",
|
|
22
|
+
"default": "./lib/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./client": "./dist/client.cjs"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"lib",
|
|
28
|
+
"dist",
|
|
29
|
+
"cordis.patch.yml",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"dsh": {
|
|
33
|
+
"client": {
|
|
34
|
+
"platform": "web",
|
|
35
|
+
"immediately": false,
|
|
36
|
+
"inject": [
|
|
37
|
+
"@deepseek-ai/dsh-client-runtime"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build:host": "tsc -p tsconfig.json",
|
|
43
|
+
"build:client": "node scripts/build-client.mjs && node scripts/wrap-client.mjs",
|
|
44
|
+
"build": "npm run build:host && npm run build:client",
|
|
45
|
+
"test": "npm run build"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@deepseek-ai/cordis": "^4.0.1"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
52
|
+
"typescript": "^5.5.0",
|
|
53
|
+
"tsdown": ">=0.4.0"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"registry": "https://registry.npmjs.org/",
|
|
57
|
+
"access": "public"
|
|
58
|
+
}
|
|
59
|
+
}
|