dsh-plugin-notify-sounds 1.8.0 → 1.8.6
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 +21 -12
- package/README.zh.md +21 -12
- package/lib/client.js +261 -267
- package/lib/index.js +1080 -1482
- package/package.json +61 -61
package/README.md
CHANGED
|
@@ -13,10 +13,10 @@ English | [中文](README.zh.md)
|
|
|
13
13
|
|
|
14
14
|
Walk away from the window without missing anything: an OS notification in the background (**click it to jump back**), and a "Waiting for you" / "Finished" mark on the taskbar title. Once you have seen it, the plugin goes quiet — it will not nag you like an alarm clock.
|
|
15
15
|
|
|
16
|
-
**Install**: DSH →
|
|
16
|
+
**Install**: DSH → **Plugins** in the left sidebar → Add plugin, paste the line below (keep the version — a release younger than 24 hours is resolved back to the previous one by pnpm's `minimumReleaseAge`) and press **Install**:
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
dsh-plugin-notify-sounds
|
|
19
|
+
dsh-plugin-notify-sounds@1.8.6
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
---
|
|
@@ -36,7 +36,7 @@ Every visual detail of the settings section comes from DSH's own design system:
|
|
|
36
36
|
| **Only what you care about** | Sub-agents (background tasks) are completely silent by default — only your own conversation is announced |
|
|
37
37
|
| **Quiet when it should be** | Quiet hours (e.g. 22:00–08:00, wrapping past midnight), notify-only-when-hidden, and a master switch |
|
|
38
38
|
| **Your sound, your way** | Nine built-in sounds, custom ringtone upload, volume — each feature with its own toggle |
|
|
39
|
-
| **Update checks** |
|
|
39
|
+
| **Update checks** | Checks npm for a newer version and points at the route that installs it — the **Plugins** panel in the sidebar (uninstall, then add again), the marketplace, or `dsh plugin add` on a web profile; the row also flags an install the profile's lockfile does not match |
|
|
40
40
|
|
|
41
41
|
## 💡 Why
|
|
42
42
|
|
|
@@ -54,7 +54,7 @@ Or upload your own ringtone (mp3/wav/ogg, ≤512KB, validated and volume-normali
|
|
|
54
54
|
|
|
55
55
|
Settings → **Sounds** (between General and Models). Every feature has its own toggle, styled exactly like DSH's own preference pages:
|
|
56
56
|
|
|
57
|
-
master switch and volume · per-trigger sounds with preview · sub-agent alerts · system notifications · window title alert · repeat interval · quiet hours · hidden-only mode · custom ringtone upload · update checks
|
|
57
|
+
master switch and volume · per-trigger sounds with preview · sub-agent alerts · system notifications · window title alert · repeat interval · quiet hours · hidden-only mode · custom ringtone upload · update checks (installs go through the package manager)
|
|
58
58
|
|
|
59
59
|
Everything applies immediately — no restart needed.
|
|
60
60
|
|
|
@@ -62,14 +62,15 @@ Everything applies immediately — no restart needed.
|
|
|
62
62
|
|
|
63
63
|
### 🖱️ Simplest: two clicks inside DSH (recommended)
|
|
64
64
|
|
|
65
|
-
1. In DSH open **
|
|
66
|
-
2. Paste the package name
|
|
65
|
+
1. In DSH open the **Plugins** panel in the left sidebar and press **Add plugin**;
|
|
66
|
+
2. Paste the package name **with a version** (this plugin is published on [npm](https://www.npmjs.com/package/dsh-plugin-notify-sounds)):
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
dsh-plugin-notify-sounds
|
|
69
|
+
dsh-plugin-notify-sounds@1.8.6
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
Do not drop the version: pnpm's `minimumReleaseAge` policy keeps a release younger than 24 hours out of automatic resolution, so the bare name resolves to the previous one. The current version is on [npm](https://www.npmjs.com/package/dsh-plugin-notify-sounds?activeTab=versions) and in [Releases](https://github.com/BillCx330/dsh-plugin-notify-sounds/releases).
|
|
73
|
+
(The GitHub repository address `https://github.com/BillCx330/dsh-plugin-notify-sounds` or a local directory path work too, but neither pins a version.)
|
|
73
74
|
3. Press **Install**, then **restart DSH** once.
|
|
74
75
|
|
|
75
76
|
The "install source" dropdown above the box picks the download mirror (mainland China mirror by default; leave it alone unless downloads are slow). DSH warns that a plugin runs with your permissions — this one only reads session state and plays sounds locally; its single request goes to **your own DSH** to raise the window when you click a notification, and nothing is sent anywhere else.
|
|
@@ -78,7 +79,7 @@ The "install source" dropdown above the box picks the download mirror (mainland
|
|
|
78
79
|
|
|
79
80
|
**Upgrades are installed by the package manager**, so the profile's lockfile moves with the files — a DSH plugin cannot install its own update durably (the manager refuses a package that is already declared, and its remove-then-install step unloads the very code that would finish the install). The plugin therefore only *checks*, and tells you where to install:
|
|
80
81
|
|
|
81
|
-
- **Inside DSH (recommended)**:
|
|
82
|
+
- **Inside DSH (recommended, and the only path verified on the Desktop)**: **Plugins** in the left sidebar → uninstall this plugin under *Installed plugins* → **Add plugin** → paste `dsh-plugin-notify-sounds@<version>` → Install → restart DSH. (Keep the version: pnpm's `minimumReleaseAge` policy keeps a freshly published version out of automatic resolution for its first 24 hours, so the bare name can resolve to the previous release.)
|
|
82
83
|
- **With the marketplace plugin** ([dshmarket](https://www.npmjs.com/package/dshmarket)): update it in one click there.
|
|
83
84
|
- **On a `web` profile**: `dsh plugin --profile <your profile> add dsh-plugin-notify-sounds@<version>`.
|
|
84
85
|
|
|
@@ -92,10 +93,12 @@ The update row also warns when the running version is not what the profile's loc
|
|
|
92
93
|
dsh plugin --profile <your profile> add github:BillCx330/dsh-plugin-notify-sounds
|
|
93
94
|
```
|
|
94
95
|
|
|
96
|
+
(A Git install follows the repository's default branch and pins no version; use `package@version` above when the install has to be reproducible.)
|
|
97
|
+
|
|
95
98
|
**Release archive** — download the `.tgz` from [Releases](https://github.com/BillCx330/dsh-plugin-notify-sounds/releases) and install it by its **path on disk**:
|
|
96
99
|
|
|
97
100
|
```sh
|
|
98
|
-
dsh plugin --profile <your profile> add ./dsh-plugin-notify-sounds-1.8.
|
|
101
|
+
dsh plugin --profile <your profile> add ./dsh-plugin-notify-sounds-1.8.6.tgz
|
|
99
102
|
```
|
|
100
103
|
|
|
101
104
|
(`dsh plugin add` hands its argument straight to the package manager, so it takes a local file path — a download URL will not work.)
|
|
@@ -113,9 +116,9 @@ The command line writes `dsh.profile.bundles` and installs the dependency for yo
|
|
|
113
116
|
## ⚠️ Known limitations
|
|
114
117
|
|
|
115
118
|
- **Hand-edited config**: preferences live in the profile's `cordis.patch.yml`; values must match the schema (volume 0–100, a preset id, `HH:MM` times) or the plugin declines to load — just fix the value. The settings UI only ever writes valid values.
|
|
116
|
-
- **Upgrades are installed by the package manager, not by the plugin**: 1.8.0 removed the self-installer (writing files in place never updated the profile's lockfile, so the next plugin install silently restored the old version). The update row still checks npm and reports a newer version, then points at the route that installs —
|
|
119
|
+
- **Upgrades are installed by the package manager, not by the plugin**: 1.8.0 removed the self-installer (writing files in place never updated the profile's lockfile, so the next plugin install silently restored the old version). The update row still checks npm and reports a newer version, then points at the route that installs — the **Plugins** panel in the sidebar (uninstall, then add again), the marketplace, or `dsh plugin add` on a web profile.
|
|
117
120
|
- **Versions up to 1.7.0** reach 1.8.0 through their own updater (1.8.0 keeps the same seven filenames), but that arrival is not registered with pnpm: reinstall once through the package manager as above and every later upgrade stays in place. Versions up to 1.6.9 cannot install a release that adds a file — their fixed whitelist refuses it safely; the same one-time reinstall fixes that too.
|
|
118
|
-
- **Multiple windows**
|
|
121
|
+
- **Multiple windows** elect one page to speak (since 1.7.0): sounds, system notifications and repeat reminders therefore fire once for the whole GUI, not once per window. Title marks stay per-window, because each window has its own title. If the speaking page closes or crashes, another takes over within seconds.
|
|
119
122
|
- **Click-to-return** is fully implemented and tested on Windows; macOS / Linux fall back to the system deep link and are unverified.
|
|
120
123
|
- **The window is found by its title** — deliberately without inspecting other processes (that trips security software). If DSH ever changes its title format, click-to-return silently stops working; sounds and notifications are unaffected.
|
|
121
124
|
- **The nav glyph** depends on the settings panel's DOM structure and silently falls back to the official gear after a DSH redesign — cosmetic only.
|
|
@@ -139,6 +142,12 @@ For anyone hacking on the code (exact details live in the source comments):
|
|
|
139
142
|
|
|
140
143
|
## 📜 Changelog
|
|
141
144
|
|
|
145
|
+
- **v1.8.6** (2026-10-23) **A full audit, paid off — no new features.** Fixed: with goal-only alerting on, turning the switch **off** while the watcher waited still produced the chime it was holding at the end of the goal (the watcher now re-reads the preference); the update check cached a FAILURE for the full day, so one network blip left the row reading "check failed" until tomorrow (failures are now cached for a minute, and the row no longer blames the network — it says neither source returned a usable answer); a `pnpm-lock.yaml` key carrying a peer suffix (`pkg@1.8.4(@scope/peer@3.18.4)`) was read as a version, which flagged a perfectly good install as unregistered and told the user to reinstall it; an unreadable current version rendered as "This version ? · Up to date", which is now its own message; the repeat-interval control displayed a hand-edited 7 as "5 min" while reminders fired every seven (display and timer now share one snap); identical quiet-hours bounds were silently treated as "no quiet" and the description now says so; the client's time parser accepted `9:05` while the Host schema rejected it (both are strict now); a custom-sound read failure was reported as "could not decode"; and one refused notification construction left the row permanently "unsupported" (a successful one now clears it). **Update guidance**: on the Desktop the plugin manager is a **sidebar panel named Plugins**, not "Settings → Plugins" — 1.8.5 got that wrong; every install command now pins the version (it rendered as `@v1.8.5`, and the display prefix does not belong in a command a package manager parses), and the copy explains that a release younger than pnpm's `minimumReleaseAge` window resolves back to the previous one. **Cleanup**: removed the 527-line unreachable self-installer from 1.8.0 (the Host file drops from 1553 to 1023 lines, along with 10 imports that existed only for it), the update notice that could never render, eight dead dictionary keys, and the tests that pinned the dead code; all three route paths are now cross-checked between the halves (`/notify-sounds/goal` was missing, and it is the one that has already drifted once). The README's "multiple windows fire independently" claim contradicted the speaking-page election shipped in 1.7.0 and is corrected.
|
|
146
|
+
- **v1.8.5** (2026-10-20) **The wording catches up with the mechanism.** The update row still said a newer version could be installed "in one click" — it cannot since 1.8.0: the row only checks and points at the package manager. The row now says exactly that, and its in-app guidance carries the version (`dsh-plugin-notify-sounds@{version}`) so a fresh release is not silently resolved to the previous one by pnpm's `minimumReleaseAge` policy. The README feature table, settings summary and install step no longer promise one-click installs; historical changelog entries are left untouched.
|
|
147
|
+
- **v1.8.4** (2026-10-20) **A click always finds the window.** A trace of a real click showed the native raise giving up with "no window found" while the window existed: a hidden or repainting window can transiently answer with an empty title, and the search had nothing else to match on. The window search now also matches the process that owns the window (the Desktop shell is this Host's parent), and the foreground request is retried three times before the deep-link fallback is paid for.
|
|
148
|
+
- **v1.8.3** (2026-10-20) **Click-to-return works when the window is closed to the tray.** The Win32 raise searched only *visible* windows, so a DSH window hidden to the tray was never found and the click fell back to the slow deep-link route — which reads as "clicked the notification, nothing happened". The search now also remembers an invisible window whose title matches, and the raise shows it (`SW_SHOW`) before restoring and focusing it; the deep link stays as the last resort.
|
|
149
|
+
- **v1.8.2** (2026-10-20) **Actually fixes goal-mode alerting.** The 1.8.1 host route read `stateOf(session, "goal")` but took `current.phase`, while the projection value nests the goal: `current.goal.phase`. Every read therefore came back empty and every round chimed. The route now reads the nested field (with a fallback for a flattened shape), and a Host-side debug trace confirmed `current.goal.phase` is `active` on intermediate rounds and `complete` on the final one.
|
|
150
|
+
- **v1.8.1** (2026-10-20) **Fixes goal-mode alerting.** The 1.8.0 switch read the phase from the browser's own session projection, which only carries sessions that page has opened — for a goal in a session it never opened the read came back empty, which the code treated as "no goal", so every round chimed again. The browser half now asks the Host's new read-only `/notify-sounds/goal` route, whose projection store is authoritative, and re-checks it while the goal is still `active` (the single chime lands when the goal completes, pauses or blocks; a session that starts running again stays silent). A Host that does not answer the route keeps the old behaviour.
|
|
142
151
|
- **v1.8.0** (2026-10-20) **The plugin stops installing itself; the package manager owns upgrades.** Writing files in place never updated the profile's lockfile, so the next plugin install — or a market upgrade — silently restored the version pnpm had recorded: a 1.7.0 install could roll back to 1.6.9 with no warning. DSH 0.2.1 makes a durable self-install impossible from inside a plugin (the manager refuses a package that is already declared, and its remove-then-install step unloads the very code that would finish the install), so the self-installer is gone: the update row checks npm, reports the newer version, and points at the route that installs — Settings → Plugins (remove, then add again), the marketplace, or `dsh plugin add` on a web profile. It also compares the running version with the version the profile's lockfile would restore and **says so when they differ**, turning the silent rollback into a self-service fix. **New: goal-mode alerts wait for the goal to end** (issue #2) — a goal runs several automatic rounds and every round used to chime; the new switch **Only alert on the final goal round** stays silent on intermediate rounds and chimes once when the goal completes, pauses or blocks (ordinary sessions are unaffected; off by default). The release keeps the same seven filenames, so 1.6.9 / 1.7.0 installations still reach it through their own updater — after one reinstall through the package manager the upgrade is permanent.
|
|
143
152
|
- **v1.7.0** (2026-10-16) **The update mechanism turns a corner**: one-click update is no longer limited by a fixed list of seven filenames. It now accepts any regular file inside the package directory, governed by rules instead of an inventory — path traversal, absolute paths, symlinks, non-file entries, reserved names (its own backup/temp names and its record file, `.git`, `node_modules`, `.npmrc`), paths containing `:`, names colliding only by case, and a file that differs from the entry point `package.json` declares only by case are all still refused, with the file count and the decompressed size capped (enforced while inflating). **1.7.0 and later update cleanly into a release that adds or drops any number of files**: a file a later release drops is now actually deleted, based on the `.update-manifest.json` record this updater leaves behind — **only files an update installed are ever deleted**, anything you put in that directory yourself is left alone, and installations older than the first record are never guessed at. **1.6.9 and earlier will fail** (safely — nothing is written, the installed version keeps working) if a newer release adds a file, and the README says to reinstall once. Fixed: turning auto-check off ended the daily check chain for good, even after turning it back on; clicking a notification did nothing when the window title changed between the two Win32 reads; prerelease versions compared as strings (`rc.10` looked older than `rc.9`); **two tabs — or two windows — of the same GUI each rang the sound, raised their own system notification and ran their own repeat reminder** (one page is now elected to speak, via BroadcastChannel plus a shared claim, and the others stay silent until it disappears; per-window title marks are unaffected); and custom-sound normalization now visits **every sample** (taking every 8th frame aliased against content near fs/8 and systematically underestimated the peak). A failed update now gives **stage-appropriate advice** — retry for network failures, and the repository plus the uninstall/reinstall steps when the payload itself could not be applied, naming both versions — `package.json` is written **last** (a crash mid-swap leaves the old version number over the new code, so the next check still offers the update instead of declaring success), and the archive's manifest is verified to be this package at the version the registry named. The custom-sound row moved to sit **directly under the three trigger sounds** it is used by, and the smaller fixes on top: the cooldown table is a real LRU rather than FIFO (the session that fired most often was evicted first), one session-list snapshot per pass instead of per session, the macOS Desktop's window-title switch is now disabled rather than merely re-described, the full-width punctuation that leaked into the English update message is gone, and the README's release-archive instructions now give a command that actually works.
|
|
144
153
|
- **v1.6.9** (2026-10-12) Fixes a README filename compatibility issue in v1.6.8: reverted to `README.md` (English) + `README.zh.md` (Chinese) so the update whitelist in every prior version can recognise them. A new filename would be refused by old users' updates — the whitelist is one-directional because the update runs old code.
|
package/README.zh.md
CHANGED
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
人不在窗口前也不怕:后台弹系统通知(**点击即回到窗口**),任务栏标题亮出「待处理 / 已完成」;你回来看过一眼之后,它就闭嘴——不会像闹钟一样反复催你。
|
|
15
15
|
|
|
16
|
-
**安装**:DSH →
|
|
16
|
+
**安装**:DSH → 左侧栏「插件」→ 添加插件,粘贴下面这行(**带上版本号**,否则发布不满 24 小时的版本会被 pnpm 的 `minimumReleaseAge` 解析回上一版),点「安装」:
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
dsh-plugin-notify-sounds
|
|
19
|
+
dsh-plugin-notify-sounds@1.8.6
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
---
|
|
@@ -36,7 +36,7 @@ dsh-plugin-notify-sounds
|
|
|
36
36
|
| **只提醒你关心的** | 子智能体(后台任务)默认完全静默,只提醒主对话,可开关 |
|
|
37
37
|
| **该安静时安静** | 静音时段(如 22:00–08:00,可跨午夜)、仅页面不可见时提示、总开关一键全静音 |
|
|
38
38
|
| **声音随你** | 九种内置音效、自定义铃声上传、音量调节,每项独立开关 |
|
|
39
|
-
| **检测更新** | 设置里检查 npm
|
|
39
|
+
| **检测更新** | 设置里检查 npm 新版本,并指向真正负责安装的入口——**左侧栏「插件」**(卸载后再装)、市场,或 web profile 上的 `dsh plugin add`;若当前安装未被 lockfile 记录,会在行内提示 |
|
|
40
40
|
|
|
41
41
|
## 💡 为什么需要它
|
|
42
42
|
|
|
@@ -54,7 +54,7 @@ DSH 的状态提示只有视觉——状态点、侧栏标记。你一切到别
|
|
|
54
54
|
|
|
55
55
|
设置 → **提示音**(位于「通用设置」与「模型」之间),每项功能都有独立开关,界面与 DSH 原生设置完全一致:
|
|
56
56
|
|
|
57
|
-
总开关与音量 · 三种触发各自的音效(含试听)· 子智能体提醒 · 系统通知 · 窗口标题提醒 · 重复提醒间隔 · 静音时段 · 仅后台提示 · 自定义铃声上传 ·
|
|
57
|
+
总开关与音量 · 三种触发各自的音效(含试听)· 子智能体提醒 · 系统通知 · 窗口标题提醒 · 重复提醒间隔 · 静音时段 · 仅后台提示 · 自定义铃声上传 · 自动检查更新(安装走包管理器)
|
|
58
58
|
|
|
59
59
|
改动即时生效,无需重启。
|
|
60
60
|
|
|
@@ -62,14 +62,15 @@ DSH 的状态提示只有视觉——状态点、侧栏标记。你一切到别
|
|
|
62
62
|
|
|
63
63
|
### 🖱️ 最简单:在 DSH 里点两下(推荐)
|
|
64
64
|
|
|
65
|
-
1. 打开 DSH →
|
|
66
|
-
2.
|
|
65
|
+
1. 打开 DSH → **左侧栏「插件」**,点**添加插件**;
|
|
66
|
+
2. 在输入框粘贴包名**和版本号**(本插件已发布在 [npm](https://www.npmjs.com/package/dsh-plugin-notify-sounds)):
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
dsh-plugin-notify-sounds
|
|
69
|
+
dsh-plugin-notify-sounds@1.8.6
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
版本号不要省:pnpm 的 `minimumReleaseAge` 策略会把刚发布不到 24 小时的版本挡在外面,只写包名会解析回上一个版本。想看最新版本号可到 [npm](https://www.npmjs.com/package/dsh-plugin-notify-sounds?activeTab=versions) 或 [Releases](https://github.com/BillCx330/dsh-plugin-notify-sounds/releases) 查。
|
|
73
|
+
(填 GitHub 仓库地址 `https://github.com/BillCx330/dsh-plugin-notify-sounds` 或本地目录路径也可以,但那样不带版本锁定)
|
|
73
74
|
3. 点**安装**,装完**重启 DSH** 一次。
|
|
74
75
|
|
|
75
76
|
输入框上方的「安装源」是下载源,默认中国大陆镜像源,国内一般不用改。DSH 会提示「插件以你的权限运行」——本插件只读会话状态、在本地发声;唯一的请求是点击系统通知时发给**本机 DSH** 的唤窗请求,不向外部发送任何数据。
|
|
@@ -78,7 +79,7 @@ DSH 的状态提示只有视觉——状态点、侧栏标记。你一切到别
|
|
|
78
79
|
|
|
79
80
|
**升级由包管理器安装**,这样 profile 的 lockfile 会跟着一起更新——DSH 插件无法自己持久地更新自己(管理器拒绝已声明的包,而它的「先移除再安装」会先卸载掉正要完成安装的代码)。所以插件只负责**检查**,并告诉你从哪里装:
|
|
80
81
|
|
|
81
|
-
- **在 DSH
|
|
82
|
+
- **在 DSH 里(推荐,也是唯一实测过的路径)**:**左侧栏「插件」** → 在「已安装插件」里卸载本插件 → **添加插件** → 粘贴 `dsh-plugin-notify-sounds@<版本>` → 安装 → 重启 DSH。(务必带版本号:pnpm 的 `minimumReleaseAge` 会让刚发布不到 24 小时的版本不参与自动解析,只写包名会装回上一个版本。)
|
|
82
83
|
- **装了市场插件**([dshmarket](https://www.npmjs.com/package/dshmarket)):在市场里一键更新。
|
|
83
84
|
- **`web` profile**:`dsh plugin --profile <你的 profile> add dsh-plugin-notify-sounds@<版本>`。
|
|
84
85
|
|
|
@@ -92,10 +93,12 @@ DSH 的状态提示只有视觉——状态点、侧栏标记。你一切到别
|
|
|
92
93
|
dsh plugin --profile <你的 profile> add github:BillCx330/dsh-plugin-notify-sounds
|
|
93
94
|
```
|
|
94
95
|
|
|
96
|
+
(Git 安装跟仓库默认分支走,不带版本锁定;要可复现的安装请用上面的 `包名@版本号`。)
|
|
97
|
+
|
|
95
98
|
**Release 压缩包** —— 从 [Releases](https://github.com/BillCx330/dsh-plugin-notify-sounds/releases) 下载 `.tgz`,用它**在磁盘上的路径**安装:
|
|
96
99
|
|
|
97
100
|
```sh
|
|
98
|
-
dsh plugin --profile <你的 profile> add ./dsh-plugin-notify-sounds-1.8.
|
|
101
|
+
dsh plugin --profile <你的 profile> add ./dsh-plugin-notify-sounds-1.8.6.tgz
|
|
99
102
|
```
|
|
100
103
|
|
|
101
104
|
(`dsh plugin add` 把参数原样交给包管理器,所以要给本地文件路径,不能填下载地址。)
|
|
@@ -113,9 +116,9 @@ dsh plugin --profile <你的 profile> add ./dsh-plugin-notify-sounds
|
|
|
113
116
|
## ⚠️ 已知边界
|
|
114
117
|
|
|
115
118
|
- **手改配置**:偏好写在 profile 的 `cordis.patch.yml`,值必须符合 schema(音量 0–100、音效为预设之一、时间 `HH:MM`);写错会让插件不加载,改回即可。设置界面只会写入合法值。
|
|
116
|
-
- **升级由包管理器安装,不再由插件自己完成**:1.8.0 移除了自安装器(原地写文件从不会更新 profile 的 lockfile,于是下一次插件安装会静默把旧版本装回来)。更新行仍会检查 npm
|
|
119
|
+
- **升级由包管理器安装,不再由插件自己完成**:1.8.0 移除了自安装器(原地写文件从不会更新 profile 的 lockfile,于是下一次插件安装会静默把旧版本装回来)。更新行仍会检查 npm、报告新版,然后指向真正负责安装的入口——**左侧栏「插件」**(卸载后再装)、市场,或 web profile 上的 `dsh plugin add`。
|
|
117
120
|
- **1.7.0 及更早版本**可以通过它们自带的自更新到达 1.8.0(1.8.0 保持同样的七个文件名),但这次到达不会被 pnpm 登记:按上面的方式用包管理器重装一次,此后所有升级都会留下。1.6.9 及更早无法安装「新增了文件」的版本——固定白名单会安全拒绝;同样的一次性重装即可解决。
|
|
118
|
-
-
|
|
121
|
+
- **多窗口**:提示音、系统通知和重复提醒由同一个 GUI 的所有页面选出一个「发声页」来发(1.7.0 起),所以同一个事件只响一次;窗口标题标记仍是每个窗口各自一份,因为它们各自有标题。发声页关闭或崩溃后几秒内由其他页面接管。
|
|
119
122
|
- **点击通知回到窗口**:Windows 完整实现并实测;macOS / Linux 走系统深链,未验证。
|
|
120
123
|
- **唤窗按窗口标题定位主窗口**:刻意不读取其他进程信息(那会触发杀软主动防御)。若将来 DSH 改变标题格式,唤窗会静默失效——提示音与通知本身不受影响。
|
|
121
124
|
- **导航小图标**:依赖设置面板的 DOM 结构,若DSH 改版后自动回落为官方齿轮,仅影响外观。
|
|
@@ -138,6 +141,12 @@ dsh plugin --profile <你的 profile> add ./dsh-plugin-notify-sounds
|
|
|
138
141
|
|
|
139
142
|
## 📜 更新记录
|
|
140
143
|
|
|
144
|
+
- **v1.8.6**(2026-10-23)**把一次全量审计翻出来的问题收干净,没有新功能。** 修复:目标模式下,若用户在等到目标结束之前关掉「只在最终轮提醒」,目标结束后仍会补响一次——等待器现在会复查这个开关;更新检查把「失败」也缓存满 24 小时,一次网络抖动就让整行显示一整天「检查失败」,现在失败只缓存 1 分钟,并且不再断言原因是网络,而是如实说两个源都没给出可用答复;`pnpm-lock.yaml` 里带 peer 后缀的键(`pkg@1.8.4(@scope/peer@3.18.4)`)会被当成版本号,让正常的安装被误报「未被包管理器登记」并劝用户重装;当前版本读不出来时,界面会显示「当前版本 ? · 已是最新」,现在单独说明无法读取;「重复提醒间隔」把手改的 7 分钟显示成 5 分钟、实际按 7 分钟响,现在显示与计时共用同一次吸附;静音时段起止相同被当作「不静音」,描述已写明;客户端的时间解析接受 `9:05` 而宿主 schema 拒绝,现在两边一样严;自定义音效读取文件失败时误报「无法解码」,现在分开说;系统通知构造失败一次后整页永久显示「不支持」,现在成功一次即恢复。**更新指引**:桌面端的插件管理器是**左侧栏「插件」**(不是「设置 → 插件」),1.8.5 写错了,已改正;安装命令一律带版本号(此前渲染成 `@v1.8.5`,多了一个 `v`,复制进包管理器未必能解析),并说明发布不满 24 小时的版本会被 pnpm 的 `minimumReleaseAge` 挡掉。**清理**:移除 1.8.0 留下的 527 行不可达自安装器(宿主文件从 1553 行降到 1023 行,连同 10 个只服务于它的导入)、永远返回 null 的更新通知组件、8 个死字典键,以及只测死代码的测试;三条路由的拼写现在都在跨半契约测试里对齐(`/notify-sounds/goal` 此前漏了,而它正是漂移过一次的那条)。README 里「多窗口各自响一次」的说法与 1.7.0 起的发声页选举矛盾,已改正。
|
|
145
|
+
- **v1.8.5**(2026-10-20)**文案跟上机制。** 更新行此前仍写着「发现新版可一键安装」——从 1.8.0 起已不支持:这一行只负责检查,并指向包管理器。现在行内如实说明,且引导里带上版本号(`dsh-plugin-notify-sounds@{version}`),避免刚发布的版本被 pnpm 的 `minimumReleaseAge` 策略静默解析成上一个版本。README 的功能表、设置摘要与安装步骤不再承诺一键安装;历史更新记录保持原样。
|
|
146
|
+
- **v1.8.4**(2026-10-20)**点击通知一定能找到窗口。** 真实点击的日志显示:窗口明明存在,原生唤窗却报 "no window found"——隐藏或正在重绘的窗口可能瞬时返回空标题,而当时的搜索只认标题。现在窗口搜索同时按「拥有窗口的进程」匹配(桌面壳是本宿主进程的父进程),前台请求连续重试三次之后才走深链兜底。
|
|
147
|
+
- **v1.8.3**(2026-10-20)**窗口关到托盘时,点击通知也能回到 DSH 了。** 原先的 Win32 唤窗只搜**可见**窗口,关到托盘的 DSH 窗口永远找不到,只能退到很慢的深链兜底——表现就是「点了通知没反应」。现在会记住标题匹配的不可见窗口,并在置前之前先 `SW_SHOW` 让它显示出来;深链仍作为最后兜底。
|
|
148
|
+
- **v1.8.2**(2026-10-20)**真正修好目标模式的提醒。** 1.8.1 的宿主路由读了 `stateOf(session, "goal")`,却取 `current.phase`,而投影值把 goal 嵌在里面:`current.goal.phase`。于是每次读取都为空、每轮照响。现在改为读嵌套字段(并保留扁平形状的兜底),宿主侧调试记录已确认:中间轮 `current.goal.phase` 是 `active`,最后一轮是 `complete`。
|
|
149
|
+
- **v1.8.1**(2026-10-20)**修复目标模式的提醒。** 1.8.0 的开关从浏览器自己的会话投影读 phase,而那份投影只包含这个页面打开过的会话——目标所在的会话没被打开过时读到空值,代码把它当成「没有目标」,于是每轮又照响。浏览器半现在改问宿主新增的只读路由 `/notify-sounds/goal`(宿主的投影存储才是权威的),并在目标仍为 `active` 时持续复查:目标完成、暂停或受阻时响唯一一次;会话重新开始运行则保持安静。宿主不回答该路由时退回旧行为。
|
|
141
150
|
- **v1.8.0**(2026-10-20)**插件不再自己安装更新,改由包管理器负责。** 原地写文件从不会更新 profile 的 lockfile,于是下一次插件安装(或市场升级)会静默把 pnpm 记录的版本装回来:1.7.0 的安装可能一声不响退回 1.6.9。DSH 0.2.1 让插件无法从内部持久地自安装(管理器拒绝已声明的包,而它的「先移除再安装」会先卸载掉正要完成安装的代码),所以自安装器被移除:更新行只检查 npm、报告新版,并指向真正负责安装的入口——设置 → 插件(卸载后再装)、市场,或 web profile 上的 `dsh plugin add`。它还会把「运行版本」与「lockfile 会恢复的版本」做比较,**不一致时明确提示**,把静默回退变成用户可自助修复的状态。**新增:目标模式下等目标结束再提醒**(issue #2)——目标模式会自动进行多轮,原先每轮结束都会响;新开关「目标模式下只在最终轮提醒」让中间轮保持安静,只在目标完成、暂停或受阻时响一次(普通对话不受影响;默认关闭)。本版保持同样的七个文件名,1.6.9 / 1.7.0 的安装仍可通过它们自带的自更新到达 1.8.0——之后用包管理器重装一次,升级即永久生效。
|
|
142
151
|
- **v1.7.0**(2026-10-16)**更新机制的转折点**:一键更新不再受「固定七个文件名」的白名单约束,改为按规则接受包目录下的任何普通文件——路径穿越、绝对路径、符号链接、非普通文件、保留名字(更新器自己的备份/临时名与记录文件、`.git`、`node_modules`、`.npmrc`)、含 `:` 的路径段,以及只有大小写不同的重名或**与 `package.json` 声明的入口只差大小写**的文件,依然一律拒绝,文件数与解压体积也都有上限(解压时即受 `gunzip` 上限约束)。**1.7.0 及以后可以正常更新到任意增减文件的新版**:某个版本去掉的文件现在会真的被删掉(依据更新器自己留下的 `.update-manifest.json` 记录,**只删它自己装过的文件**,用户放进目录里的东西一律不动;第一条记录之前的安装不做任何猜测)。**1.6.9 及更早**遇到「新增了文件」的新版会更新失败(安全失败:一个字节都不写,已装版本继续正常工作),README 里说明了重装一次的办法。修复:关掉「自动检查更新」会让每日轮询永久停摆(重新打开也不恢复);窗口标题在两次 Win32 读取之间变短时,点通知唤窗会静默失效;预发布版本号按字符串比较(`rc.10` 被误判为比 `rc.9` 旧);**同一个 GUI 开多个标签页或多个窗口时提示音、系统通知、重复提醒全部翻倍**(现在由 BroadcastChannel + 本地记录选出一个「发声页」,其余页保持安静,只在发声页消失后接管;窗口标题标记各窗口独立,不受影响);自定义音效的峰值归一化改为**逐样本**扫描(原先每 8 帧抽样会与接近 fs/8 的高频混叠、系统性低估峰值)。更新失败时给出**按阶段区分的建议**(网络类提示重试;解包/替换类给出手动重装步骤与仓库地址,并列出失败的两个版本号),写入顺序改为**最后写 `package.json`**(中途崩溃时检查仍会提示更新,用户再点一次即可自愈),并会校验归档里的清单确实是本包、确实是 registry 报的那个版本。设置里「自定义音效」移到**三种提示音之后**(它们才是会用到它的三处);`settings` 相关的小修:冷却表改为真正的 LRU(原先是 FIFO,最常触发的会话反而最先被淘汰)、会话列表每轮只取一次快照、macOS 桌面版的「窗口标题提醒」开关改为**禁用**(原先能打开但标记无处显示)、英文界面更新提示里残留的全角标点修掉、README 的 Release 安装说明改为可照做的本地路径写法。
|
|
143
152
|
- **v1.6.9**(2026-10-12)修正 v1.6.8 的 README 文件名兼容性:改回 `README.md`(英文默认)+ `README.zh.md`(中文),确保旧版本更新白名单能识别。新文件名会让旧用户的更新被拒——白名单是单向兼容的,更新时跑的是旧代码。
|