dsh-notice-center 1.2.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/LICENSE +22 -0
- package/README.md +165 -0
- package/assets/audio/README.md +25 -0
- package/assets/audio/alert-01.mp3 +0 -0
- package/assets/audio/alert-02.mp3 +0 -0
- package/assets/audio/alert-03.mp3 +0 -0
- package/assets/audio/alert-04.mp3 +0 -0
- package/assets/audio/alert-05.mp3 +0 -0
- package/assets/audio/alert-06.mp3 +0 -0
- package/assets/audio/alert-07.mp3 +0 -0
- package/assets/audio/alert-08.mp3 +0 -0
- package/assets/audio/alert-09.mp3 +0 -0
- package/assets/audio/alert-10.mp3 +0 -0
- package/assets/audio/bip-bop-01.mp3 +0 -0
- package/assets/audio/bip-bop-02.mp3 +0 -0
- package/assets/audio/bip-bop-03.mp3 +0 -0
- package/assets/audio/bip-bop-04.mp3 +0 -0
- package/assets/audio/bip-bop-05.mp3 +0 -0
- package/assets/audio/bip-bop-06.mp3 +0 -0
- package/assets/audio/bip-bop-07.mp3 +0 -0
- package/assets/audio/bip-bop-08.mp3 +0 -0
- package/assets/audio/bip-bop-09.mp3 +0 -0
- package/assets/audio/bip-bop-10.mp3 +0 -0
- package/assets/audio/nope-01.mp3 +0 -0
- package/assets/audio/nope-02.mp3 +0 -0
- package/assets/audio/nope-03.mp3 +0 -0
- package/assets/audio/nope-04.mp3 +0 -0
- package/assets/audio/nope-05.mp3 +0 -0
- package/assets/audio/nope-06.mp3 +0 -0
- package/assets/audio/nope-07.mp3 +0 -0
- package/assets/audio/nope-08.mp3 +0 -0
- package/assets/audio/nope-09.mp3 +0 -0
- package/assets/audio/nope-10.mp3 +0 -0
- package/assets/audio/nope-11.mp3 +0 -0
- package/assets/audio/nope-12.mp3 +0 -0
- package/assets/audio/staplebops-01.mp3 +0 -0
- package/assets/audio/staplebops-02.mp3 +0 -0
- package/assets/audio/staplebops-03.mp3 +0 -0
- package/assets/audio/staplebops-04.mp3 +0 -0
- package/assets/audio/staplebops-05.mp3 +0 -0
- package/assets/audio/staplebops-06.mp3 +0 -0
- package/assets/audio/staplebops-07.mp3 +0 -0
- package/assets/audio/yup-01.mp3 +0 -0
- package/assets/audio/yup-02.mp3 +0 -0
- package/assets/audio/yup-03.mp3 +0 -0
- package/assets/audio/yup-04.mp3 +0 -0
- package/assets/audio/yup-05.mp3 +0 -0
- package/assets/audio/yup-06.mp3 +0 -0
- package/cordis.patch.yml +9 -0
- package/lib/client.cjs +1157 -0
- package/lib/index.mjs +126 -0
- package/package.json +71 -0
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
/**
|
|
7
|
+
* dsh-notice-center — Host half.
|
|
8
|
+
*
|
|
9
|
+
* 宿主半的唯一职责:向官方 settings 服务(@deepseek-ai/dsh-settings,由
|
|
10
|
+
* dsh-settings-file 持久化到 settings.yaml)注册 `notice-center` 命名空间的
|
|
11
|
+
* schema。浏览器半(src/client.ts)通过 settingsScope 绑定同一命名空间,
|
|
12
|
+
* 读配置、写配置;favicon 状态机消费配置色。
|
|
13
|
+
*
|
|
14
|
+
* 【不 import dsh-settings】自 0.1.2-rc.1 起 dsh-settings 不再导出
|
|
15
|
+
* `settingsNamespace()`,register 内部自己按 kebab-case 校验字符串,因此这里直接传
|
|
16
|
+
* 纯字符串。这样宿主半的运行时依赖只剩 @deepseek-ai/schemastery(npm 上有对应版本),
|
|
17
|
+
* 插件从 registry 安装时不必解析任何 @deepseek-ai peer —— 而 profile 默认
|
|
18
|
+
* `autoInstallPeers: false`,真去解析反而会因 npm 上的版本不匹配而加载失败。
|
|
19
|
+
*
|
|
20
|
+
* schema 语义(与主人确认的灰区决策一致):
|
|
21
|
+
* green/amber 有默认值(官方侧边栏色),用户未覆盖时回默认;
|
|
22
|
+
* black 无默认值 —— 未配置 = 官方原版 /favicon.svg,配置了才替换。
|
|
23
|
+
* 非法 hex 由 schema pattern 在写入时拒绝(拒绝写入并提示)。
|
|
24
|
+
*/
|
|
25
|
+
/** 本插件拥有的设置命名空间(kebab-case)。 */
|
|
26
|
+
const SETTINGS_NAMESPACE = "notice-center";
|
|
27
|
+
/** 官方侧边栏状态点颜色(静态色板,明暗主题同值)。 */
|
|
28
|
+
const DEFAULT_GREEN = "#22C55E";
|
|
29
|
+
const DEFAULT_AMBER = "#F59E0B";
|
|
30
|
+
/** hex 色值校验:6 位 #RRGGBB(ColorPicker 输出与手输均为此格式)。 */
|
|
31
|
+
const HEX = /^#[0-9a-fA-F]{6}$/;
|
|
32
|
+
/**
|
|
33
|
+
* 解析注册用的命名空间:直接传 kebab-case 字符串(0.1.2-rc.1+ 的 register 自己校验)。
|
|
34
|
+
* @returns settings.register 接受的命名空间。
|
|
35
|
+
*/
|
|
36
|
+
function resolveNamespace() {
|
|
37
|
+
return SETTINGS_NAMESPACE;
|
|
38
|
+
}
|
|
39
|
+
/** 命名空间 schema;也是浏览器侧 wire 校验依据。 */
|
|
40
|
+
const NoticeSettingsSchema = z.object({
|
|
41
|
+
green: z.string().pattern(HEX).default(DEFAULT_GREEN),
|
|
42
|
+
amber: z.string().pattern(HEX).default(DEFAULT_AMBER),
|
|
43
|
+
/** 无默认:用户不配置时 black === undefined → 官方原版 favicon。 */
|
|
44
|
+
black: z.string().pattern(HEX),
|
|
45
|
+
/** 颜色状态灯总开关(关闭时保持官方原版图标)。 */
|
|
46
|
+
colorsEnabled: z.boolean().default(true),
|
|
47
|
+
/** 系统通知总开关(默认关闭;开启时若未授权由设置页发起授权请求)。 */
|
|
48
|
+
notifyEnabled: z.boolean().default(false),
|
|
49
|
+
/** 通知是否自动隐藏(默认 true=系统自行收起;false=常驻,需用户手动关闭)。 */
|
|
50
|
+
notifyAutoHide: z.boolean().default(true),
|
|
51
|
+
/** 通知提示音:完成与待处理为两种不同的预置音。 */
|
|
52
|
+
notifySound: z.boolean().default(true),
|
|
53
|
+
/** 提示音音量(0–1)。 */
|
|
54
|
+
notifyVolume: z.number().min(0).max(1).default(0.6),
|
|
55
|
+
/** 完成提示音 id(见浏览器半音效库;builtin-up = 内置合成音 Chime Up)。 */
|
|
56
|
+
notifyDoneSound: z.string().default("builtin-up"),
|
|
57
|
+
/** 待处理提示音 id(builtin-down = 内置合成音 Chime Down)。 */
|
|
58
|
+
notifyPendingSound: z.string().default("builtin-down")
|
|
59
|
+
});
|
|
60
|
+
/** 音效静态路由前缀:浏览器半按 `<前缀>/<id>.mp3` 取音频。 */
|
|
61
|
+
const SOUND_ROUTE = "/notice-center-sounds";
|
|
62
|
+
/** 随包分发的音效目录(音源:anomalyco/opencode packages/ui/src/assets/audio,MIT)。 */
|
|
63
|
+
const SOUND_DIR = fileURLToPath(new URL("../assets/audio/", import.meta.url));
|
|
64
|
+
/** 只放行音效库的文件名形态,杜绝路径穿越。 */
|
|
65
|
+
const SOUND_FILE = /^[a-z0-9-]+\.mp3$/;
|
|
66
|
+
/**
|
|
67
|
+
* 构建音效静态路由(不依赖 cordis,可直接挂到 node:http 做测试)。
|
|
68
|
+
* 命中 `[a-z0-9-]+\.mp3` 才读盘,其余一律 404;音频是随包常量,故长缓存。
|
|
69
|
+
* @returns 路由数组(ctx.webServer.register 接受的形态)。
|
|
70
|
+
*/
|
|
71
|
+
function buildSoundRoutes() {
|
|
72
|
+
return [{
|
|
73
|
+
kind: "prefix",
|
|
74
|
+
path: SOUND_ROUTE,
|
|
75
|
+
handler: async (req, res) => {
|
|
76
|
+
const name = decodeURIComponent(String(req.url ?? "").slice(SOUND_ROUTE.length)).replace(/^\/+/, "");
|
|
77
|
+
const headers = {
|
|
78
|
+
"content-type": "text/plain; charset=utf-8",
|
|
79
|
+
"cache-control": "no-store"
|
|
80
|
+
};
|
|
81
|
+
if (!SOUND_FILE.test(name)) {
|
|
82
|
+
res.writeHead(404, headers);
|
|
83
|
+
res.end("Not Found");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const data = await readFile(join(SOUND_DIR, name));
|
|
88
|
+
res.writeHead(200, {
|
|
89
|
+
"content-type": "audio/mpeg",
|
|
90
|
+
"content-length": String(data.length),
|
|
91
|
+
"cache-control": "public, max-age=31536000, immutable"
|
|
92
|
+
});
|
|
93
|
+
res.end(data);
|
|
94
|
+
} catch {
|
|
95
|
+
res.writeHead(404, headers);
|
|
96
|
+
res.end("Not Found");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}];
|
|
100
|
+
}
|
|
101
|
+
var src_default = {
|
|
102
|
+
name: "dsh-notice-center",
|
|
103
|
+
apply(ctx) {
|
|
104
|
+
/** 路由注销器(apply 卸载时统一回收)。 */
|
|
105
|
+
const disposers = [];
|
|
106
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
107
|
+
settingsCtx.settings.register(resolveNamespace(), NoticeSettingsSchema);
|
|
108
|
+
/* 启动自证:注册成功会在 Harness 控制台留一行,便于排查命名空间未接上的问题。 */
|
|
109
|
+
settingsCtx.logger.info("dsh-notice-center: settings namespace \"%s\" registered", SETTINGS_NAMESPACE);
|
|
110
|
+
});
|
|
111
|
+
/* 可选通道:webServer 缺席时音频路由不挂载,浏览器半自动回退到合成音。 */
|
|
112
|
+
ctx.inject(["webServer"], (webCtx) => {
|
|
113
|
+
for (const route of buildSoundRoutes()) disposers.push(webCtx.webServer.register(route));
|
|
114
|
+
webCtx.logger?.info?.("dsh-notice-center: sound route \"%s\" registered", SOUND_ROUTE);
|
|
115
|
+
});
|
|
116
|
+
return () => {
|
|
117
|
+
for (const dispose of disposers) {
|
|
118
|
+
try {
|
|
119
|
+
dispose();
|
|
120
|
+
} catch {}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
export { DEFAULT_AMBER, DEFAULT_GREEN, SETTINGS_NAMESPACE, SOUND_ROUTE, NoticeSettingsSchema, buildSoundRoutes, src_default as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-notice-center",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "DeepSeek Harness 通知中心:标签页鲸鱼状态灯(绿=跑完 / 琥珀=待处理)+ 浏览器系统通知(完成/待处理提示、45 个 opencode 音效可选、音量可配)。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node test/host-half.smoke.mjs && node test/client-half.smoke.mjs",
|
|
8
|
+
"test:host": "node test/host-half.smoke.mjs",
|
|
9
|
+
"test:client": "node test/client-half.smoke.mjs",
|
|
10
|
+
"prepublishOnly": "npm test"
|
|
11
|
+
},
|
|
12
|
+
"main": "lib/index.mjs",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"default": "./lib/index.mjs"
|
|
16
|
+
},
|
|
17
|
+
"./client": {
|
|
18
|
+
"default": "./lib/client.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib/index.mjs",
|
|
25
|
+
"lib/client.cjs",
|
|
26
|
+
"cordis.patch.yml",
|
|
27
|
+
"assets",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
33
|
+
},
|
|
34
|
+
"dsh": {
|
|
35
|
+
"bundle": {
|
|
36
|
+
"patch": "./cordis.patch.yml"
|
|
37
|
+
},
|
|
38
|
+
"client": {
|
|
39
|
+
"inject": [
|
|
40
|
+
"@deepseek-ai/dsh-client-locale",
|
|
41
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-session"
|
|
43
|
+
],
|
|
44
|
+
"platform": "web"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/SCP-QQ/dsh-notice-center.git"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/SCP-QQ/dsh-notice-center#readme",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/SCP-QQ/dsh-notice-center/issues"
|
|
54
|
+
},
|
|
55
|
+
"keywords": [
|
|
56
|
+
"dsh",
|
|
57
|
+
"dsh-plugin",
|
|
58
|
+
"deepseek-harness",
|
|
59
|
+
"notification",
|
|
60
|
+
"system-notification",
|
|
61
|
+
"favicon"
|
|
62
|
+
],
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.2-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.2-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1"
|
|
69
|
+
},
|
|
70
|
+
"license": "MIT"
|
|
71
|
+
}
|