dsh-plugin-session-notifier 0.1.0 → 0.1.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 +2 -2
- package/README.md +3 -3
- package/client.js +45 -18
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -46,10 +46,10 @@ The panel says so as well.
|
|
|
46
46
|
**1. By package name (recommended).** Ask the agent to call:
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
plugin_manager({ action: "install_bundle", target: "dsh-plugin-session-notifier
|
|
49
|
+
plugin_manager({ action: "install_bundle", target: "dsh-plugin-session-notifier" })
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
You can also type `dsh-plugin-session-notifier` into **Plugins → Add plugin** yourself. Pick the
|
|
52
|
+
Omitting the version installs the latest one. You can also type `dsh-plugin-session-notifier` into **Plugins → Add plugin** yourself. Pick the
|
|
53
53
|
China mainland registry mirror if you are there, it is much faster.
|
|
54
54
|
|
|
55
55
|
**2. Local development:** `plugin_manager({ action: "install_bundle", target: "/absolute/path/dsh-plugin-session-notifier" })`.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 会话提醒 · Session Notifier
|
|
2
2
|
|
|
3
3
|
[English](README.en.md) | 中文
|
|
4
4
|
|
|
@@ -43,10 +43,10 @@ DeepSeek Harness 插件。会话跑完、出错,或者停下来等你回答(
|
|
|
43
43
|
**一、按包名安装(推荐)**。让智能体调用:
|
|
44
44
|
|
|
45
45
|
```
|
|
46
|
-
plugin_manager({ action: "install_bundle", target: "dsh-plugin-session-notifier
|
|
46
|
+
plugin_manager({ action: "install_bundle", target: "dsh-plugin-session-notifier" })
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
不写版本号会装最新版。也可以自己在「插件 → 添加插件」里输入 `dsh-plugin-session-notifier`。
|
|
50
50
|
安装源可选「中国大陆镜像源」,国内会快很多。
|
|
51
51
|
|
|
52
52
|
**二、本地开发**:`plugin_manager({ action: "install_bundle", target: "/绝对路径/dsh-plugin-session-notifier" })`。
|
package/client.js
CHANGED
|
@@ -30,11 +30,13 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
const RECENT_LIMIT = 12;
|
|
31
31
|
/** Wait before reminding about the session the user is looking at. */
|
|
32
32
|
const VIEWING_MERGE_MS = 1000;
|
|
33
|
+
/** Two reminders landing together share one tone instead of stacking two. */
|
|
34
|
+
const TONE_GAP_MS = 250;
|
|
33
35
|
|
|
34
36
|
//#region copy
|
|
35
37
|
const zh = {
|
|
36
38
|
'panel.label': '会话提醒',
|
|
37
|
-
'panel.title': '
|
|
39
|
+
'panel.title': '会话提醒',
|
|
38
40
|
'panel.desc':
|
|
39
41
|
'会话跑完或停下来等你回答时,用桌面通知和提示音提醒你。切到别的窗口、全屏看视频或打游戏时也不会错过。',
|
|
40
42
|
'group.master': '总开关',
|
|
@@ -104,8 +106,8 @@ window.__ModuleLoader__.load({
|
|
|
104
106
|
};
|
|
105
107
|
|
|
106
108
|
const en = {
|
|
107
|
-
'panel.label': 'Session
|
|
108
|
-
'panel.title': 'Session
|
|
109
|
+
'panel.label': 'Session Notifier',
|
|
110
|
+
'panel.title': 'Session Notifier',
|
|
109
111
|
'panel.desc':
|
|
110
112
|
'A desktop notification and a short chime when a session finishes or stops to wait for you — so a task that ends while you are on another window is not missed.',
|
|
111
113
|
'group.master': 'Master switch',
|
|
@@ -177,11 +179,11 @@ window.__ModuleLoader__.load({
|
|
|
177
179
|
|
|
178
180
|
//#region settings
|
|
179
181
|
/**
|
|
180
|
-
* Stored-document version
|
|
181
|
-
*
|
|
182
|
-
*
|
|
182
|
+
* Stored-document version, written with every save. Nothing reads it yet: the key
|
|
183
|
+
* was introduced with the current defaults, so no older document can exist. It is
|
|
184
|
+
* here so a future default change can migrate instead of guessing.
|
|
183
185
|
*/
|
|
184
|
-
const SETTINGS_VERSION =
|
|
186
|
+
const SETTINGS_VERSION = 1;
|
|
185
187
|
|
|
186
188
|
/** Merge-window choices, in milliseconds. */
|
|
187
189
|
const COMBINE_CHOICES = [10000, 20000, 30000];
|
|
@@ -223,12 +225,6 @@ window.__ModuleLoader__.load({
|
|
|
223
225
|
for (const key of Object.keys(DEFAULTS)) {
|
|
224
226
|
if (typeof parsed[key] === typeof DEFAULTS[key]) next[key] = parsed[key];
|
|
225
227
|
}
|
|
226
|
-
const version = typeof parsed.v === 'number' ? parsed.v : 1;
|
|
227
|
-
if (version < SETTINGS_VERSION) {
|
|
228
|
-
// The two defaults that changed; other stored choices stay as the user left them.
|
|
229
|
-
next.whenFocused = DEFAULTS.whenFocused;
|
|
230
|
-
next.combineMs = DEFAULTS.combineMs;
|
|
231
|
-
}
|
|
232
228
|
} catch (_storageUnavailable) {
|
|
233
229
|
// A blocked or corrupt store simply falls back to the defaults.
|
|
234
230
|
}
|
|
@@ -287,8 +283,33 @@ window.__ModuleLoader__.load({
|
|
|
287
283
|
/** Newest-first reminder log for the panel. */
|
|
288
284
|
recent: [],
|
|
289
285
|
recentListeners: new Set(),
|
|
286
|
+
/** Timers owned by one notification or tone, cleared with the plugin. */
|
|
287
|
+
timers: new Set(),
|
|
288
|
+
/** Wall-clock time of the last tone, so two reminders do not overlap. */
|
|
289
|
+
lastToneAt: 0,
|
|
290
290
|
};
|
|
291
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Run a callback later, keeping its timer id in the owned set.
|
|
294
|
+
* @param callback - work to run once.
|
|
295
|
+
* @param delay - delay in milliseconds.
|
|
296
|
+
* @returns the timer id.
|
|
297
|
+
*/
|
|
298
|
+
function startTimer(callback, delay) {
|
|
299
|
+
const id = window.setTimeout(() => {
|
|
300
|
+
state.timers.delete(id);
|
|
301
|
+
callback();
|
|
302
|
+
}, delay);
|
|
303
|
+
state.timers.add(id);
|
|
304
|
+
return id;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** Drop every timer this plugin started. */
|
|
308
|
+
function clearTimers() {
|
|
309
|
+
for (const id of state.timers) window.clearTimeout(id);
|
|
310
|
+
state.timers.clear();
|
|
311
|
+
}
|
|
312
|
+
|
|
292
313
|
/** Faces assigned when they become available; every consumer tolerates absence. */
|
|
293
314
|
const services = {
|
|
294
315
|
sessions: null,
|
|
@@ -397,8 +418,13 @@ window.__ModuleLoader__.load({
|
|
|
397
418
|
* Play the reminder tone for one kind of event.
|
|
398
419
|
* @param kind - `done`, `awaiting`, `error`, or `test`.
|
|
399
420
|
*/
|
|
400
|
-
function chime(kind) {
|
|
421
|
+
function chime(kind, force) {
|
|
401
422
|
if (!settings.sound) return;
|
|
423
|
+
const at = Date.now();
|
|
424
|
+
if (force !== true) {
|
|
425
|
+
if (at - state.lastToneAt < TONE_GAP_MS) return;
|
|
426
|
+
state.lastToneAt = at;
|
|
427
|
+
}
|
|
402
428
|
const context = audioContext();
|
|
403
429
|
if (context === null) return;
|
|
404
430
|
if (context.state === 'suspended' && typeof context.resume === 'function') {
|
|
@@ -439,7 +465,7 @@ window.__ModuleLoader__.load({
|
|
|
439
465
|
oscillator.start(start + offset);
|
|
440
466
|
oscillator.stop(start + offset + duration + 0.03);
|
|
441
467
|
}
|
|
442
|
-
|
|
468
|
+
startTimer(() => {
|
|
443
469
|
try {
|
|
444
470
|
master.disconnect();
|
|
445
471
|
} catch (_disconnected) {
|
|
@@ -525,8 +551,8 @@ window.__ModuleLoader__.load({
|
|
|
525
551
|
// Already gone.
|
|
526
552
|
}
|
|
527
553
|
};
|
|
528
|
-
|
|
529
|
-
|
|
554
|
+
startTimer(() => settle('unconfirmed'), 2500);
|
|
555
|
+
startTimer(() => {
|
|
530
556
|
try {
|
|
531
557
|
notification.close();
|
|
532
558
|
} catch (_closed) {
|
|
@@ -657,7 +683,7 @@ window.__ModuleLoader__.load({
|
|
|
657
683
|
*/
|
|
658
684
|
function runTestReminder() {
|
|
659
685
|
primeAudio();
|
|
660
|
-
chime('test');
|
|
686
|
+
chime('test', true);
|
|
661
687
|
publishProbe({ status: 'pending' });
|
|
662
688
|
const delivery = notifyDesktop(
|
|
663
689
|
'test',
|
|
@@ -1328,6 +1354,7 @@ window.__ModuleLoader__.load({
|
|
|
1328
1354
|
ctx.effect(
|
|
1329
1355
|
() => () => {
|
|
1330
1356
|
cancelAll();
|
|
1357
|
+
clearTimers();
|
|
1331
1358
|
},
|
|
1332
1359
|
'session-notifier: timers',
|
|
1333
1360
|
);
|
package/locale/en.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
|
-
"title": "Session
|
|
4
|
-
"description": "
|
|
3
|
+
"title": "Session Notifier",
|
|
4
|
+
"description": "A desktop notification and a short chime when a session finishes or stops to wait for you — so a task that ends while you are on another window is not missed."
|
|
5
5
|
}
|
|
6
6
|
}
|
package/locale/zh.json
CHANGED
package/package.json
CHANGED