dsh-macos-notify 0.2.1 → 0.3.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 CHANGED
@@ -1,12 +1,12 @@
1
1
  # dsh-macos-notify
2
2
 
3
- Native macOS notifications for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), with event-specific sounds, notification filtering, multi-task coalescing, and a settings card in the DSH Web UI.
3
+ Native macOS notifications for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), with event-specific sounds, notification filtering, multi-task coalescing, and a first-level settings page in the DSH Web UI.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - Notification Center alerts when a turn completes, fails, is blocked, or waits for approval.
8
8
  - Separate sounds for completed, error, aborted, and approval events; any event can be muted.
9
- - System sound picker plus managed custom sound import and deletion from the Web settings card.
9
+ - System sound picker plus managed custom sound import and deletion from the Web settings page.
10
10
  - Custom imports are converted to AIFF, limited to 5 MB and 10 seconds, capped at 20 managed files / 50 MB total, and stored in `~/Library/Sounds`.
11
11
  - A 1.5-second coalescing window and optional digest mode prevent parallel tasks from flooding Notification Center.
12
12
  - Recent notification diagnostics explain whether an event was sent, queued, suppressed, or failed.
@@ -41,7 +41,7 @@ Alternatively, install the latest source directly from GitHub:
41
41
  npx -y @deepseek-ai/dsh plugin --profile web add github:CrombastiC/dsh-macos-notify
42
42
  ```
43
43
 
44
- Then open **Settings → Plugins Plugin configuration macOS notifications**.
44
+ Then open **Settings → macOS notifications** from the first-level settings navigation.
45
45
 
46
46
  To remove the plugin:
47
47
 
@@ -88,7 +88,6 @@ The settings namespace is `macos-notify`. Values changed from the Web card apply
88
88
  | `pauseUntil` | `0` | Temporary pause deadline as Unix milliseconds; managed by quick actions in the Web card. |
89
89
  | `duplicateWindowSec` | `300` | Suppress identical errors from the same session within this window; `0` disables it. |
90
90
  | `projectRulesJson` | `[]` | Project rules managed by the Web card. More-specific descendant paths win. |
91
- | `notifyOnLoad` | `true` | Send a test notification when the plugin loads. |
92
91
 
93
92
  ### Project rule modes
94
93
 
@@ -96,7 +95,7 @@ The settings namespace is `macos-notify`. Values changed from the Web card apply
96
95
  - `errors` — allow only errors, blocked events, and approval requests.
97
96
  - `important` — bypass minimum-duration, focus, idle, quiet-hour, and temporary-pause filters.
98
97
 
99
- The settings card keeps the last 50 decisions in process memory. Each row records whether an event was sent, queued, suppressed, or failed and includes the reason. This history resets when DSH restarts and does not contain message content.
98
+ The settings page keeps the last 50 decisions in process memory. Each row records whether an event was sent, queued, suppressed, or failed and includes the reason. This history resets when DSH restarts and does not contain message content.
100
99
 
101
100
  ## Notification channels
102
101
 
@@ -108,17 +107,17 @@ Sound selection applies to the `osascript` channel. With OSC 9, the terminal con
108
107
 
109
108
  ## Custom sounds
110
109
 
111
- In the settings card, select **Edit → Import sound**. Supported inputs include AAC, AIFF, CAF, FLAC, M4A, MP3, OGG, Opus, and WAV.
110
+ In the settings page, select **Edit → Import sound**. Supported inputs include AAC, AIFF, CAF, FLAC, M4A, MP3, OGG, Opus, and WAV.
112
111
 
113
112
  The host validates the extension, decoded size, converted duration, managed-file count, and total managed size before writing anything to the user sound directory. Imports are converted to 44.1 kHz mono AIFF using macOS `afconvert`, with `ffmpeg` as a fallback for formats that `afconvert` cannot decode. Existing files are never overwritten; a numeric suffix is added instead.
114
113
 
115
- New imports are recorded in `~/Library/Application Support/dsh-macos-notify/sounds.json` and can be deleted from the settings card. If a sound is currently selected, deletion asks for confirmation and changes affected events to silent. Files remain in `~/Library/Sounds` if the plugin is removed without deleting them first.
114
+ New imports are recorded in `~/Library/Application Support/dsh-macos-notify/sounds.json` and can be deleted from the settings page. If a sound is currently selected, deletion asks for confirmation and changes affected events to silent. Files remain in `~/Library/Sounds` if the plugin is removed without deleting them first.
116
115
 
117
116
  ## Known limitations
118
117
 
119
118
  - The plugin is macOS-only. Native notifications use `osascript`, and custom import uses macOS audio tooling.
120
119
  - OSC 9 sound behavior belongs to the terminal and ignores the per-event sound selection.
121
- - The Web settings card uses the trusted `/macos-notify` RPC channel because the current DSH Web settings proxy has a namespace allowlist for built-in settings.
120
+ - The Web settings page uses the trusted `/macos-notify` RPC channel because the current DSH Web settings proxy has a namespace allowlist for built-in settings.
122
121
  - Only sounds imported by v0.2.0 or later are tracked as managed sounds. Earlier manually copied/imported files can still be selected, but must be removed from `~/Library/Sounds` manually.
123
122
 
124
123
  ## Development
@@ -126,7 +125,7 @@ New imports are recorded in `~/Library/Application Support/dsh-macos-notify/soun
126
125
  The package is intentionally build-free:
127
126
 
128
127
  - `index.js` — host plugin, event handling, notification delivery, settings RPC, and sound import.
129
- - `client.js` — hand-written DSH client module for focus reporting and the Web settings card.
128
+ - `client.js` — hand-written DSH client module for focus reporting and the first-level Web settings page.
130
129
  - `cordis.patch.yml` — profile bundle patch.
131
130
 
132
131
  Run the release checks:
package/client.js CHANGED
@@ -196,7 +196,15 @@ window.__ModuleLoader__.load({
196
196
  var timer = setInterval(report, 30000)
197
197
  var call = function (endpoint, payload) { return ctx.connection.rpc.call('/macos-notify', endpoint, payload).then(function (result) { if (!result || result.ok !== true) throw new Error(result && result.error && result.error.message || 'RPC 调用失败'); return result.value }) }
198
198
  var getCurrentCwd = function () { try { var state = ctx.sessions.list.getSnapshot(); return state.current && state.byId[state.current] && state.byId[state.current].cwd || '' } catch { return '' } }
199
- ctx.slots.inject('settings.plugin.item', function* () { yield ctx.slots.register({ name: 'settings.plugin.item', id: 'macos-notify', order: 100, inject: function () { return { call: call, getCurrentCwd: getCurrentCwd } } }, Card) })
199
+ ctx.slots.inject('settings.section', function () {
200
+ return ctx.slots.register({
201
+ name: 'settings.section',
202
+ id: 'macos-notify',
203
+ order: 100,
204
+ label: 'macOS 通知',
205
+ inject: function () { return { call: call, getCurrentCwd: getCurrentCwd } },
206
+ }, Card)
207
+ })
200
208
  ctx.effect(function () { return function () { clearInterval(timer); document.removeEventListener('visibilitychange', report); window.removeEventListener('focus', report); window.removeEventListener('blur', report) } })
201
209
  }
202
210
  return module.exports
package/index.js CHANGED
@@ -53,8 +53,8 @@ export const Config = Schema.object({
53
53
  duplicateWindowSec: Schema.number().default(300),
54
54
  /** 项目规则 JSON:[{ path, mode }],mode 为 mute / errors / important */
55
55
  projectRulesJson: Schema.string().default('[]'),
56
- /** 插件加载时发一条测试通知 */
57
- notifyOnLoad: Schema.boolean().default(true),
56
+ /** 兼容旧配置;成功加载现在始终静默,仅初始化失败时提醒 */
57
+ notifyOnLoad: Schema.boolean().default(false),
58
58
  })
59
59
 
60
60
  /** 设置页可编辑的提示音字段 */
@@ -295,6 +295,11 @@ function notify(title, body, sound, channel, onResult = () => {}) {
295
295
  })
296
296
  }
297
297
 
298
+ function notifyStartupFailure(err, sound = 'Basso') {
299
+ const detail = String(err?.message ?? err ?? '未知错误').replace(/\s+/g, ' ').trim().slice(0, 180)
300
+ notify('DSH', `macOS 通知插件加载失败:${detail || '未知错误'}`, sound, 'osascript')
301
+ }
302
+
298
303
  // —— OSC 9 通道(思路参考 kimi-code 的 terminal-notification.ts)——
299
304
 
300
305
  /** 认识 OSC 9 桌面通知的终端白名单;不认识 OSC 9 的终端收到转义序列会打印乱码,所以必须保守 */
@@ -378,7 +383,7 @@ function isCriticalKind(kind) {
378
383
  return kind === '出错' || kind === '被阻止' || kind === '审批'
379
384
  }
380
385
 
381
- export function apply(ctx, config) {
386
+ function applyImpl(ctx, config) {
382
387
  // 配置三层叠加:schema 默认值 < cordis 组合层(base = 插件 config)< 用户层(设置页)。
383
388
  // 设置页写入后经 watch 实时生效,不需要重启。
384
389
  const scope = ctx.settings.register('macos-notify', Config, { base: config, applies: 'live' })
@@ -597,6 +602,7 @@ export function apply(ctx, config) {
597
602
  console.log('[dsh-macos-notify] RPC intercept mounted')
598
603
  } catch (err) {
599
604
  console.error('[dsh-macos-notify] RPC intercept failed:', err)
605
+ notifyStartupFailure(err, current.sounds.error)
600
606
  }
601
607
  })
602
608
 
@@ -780,10 +786,6 @@ export function apply(ctx, config) {
780
786
  if (!flushTimer) flushTimer = setTimeout(flush, current.coalesceMs)
781
787
  }
782
788
 
783
- if (current.notifyOnLoad) {
784
- send('DSH', 'macOS 通知插件已加载', current.sounds.completed, [], { detail: '插件加载测试通知' })
785
- }
786
-
787
789
  ctx.on('session/event', (session, event) => {
788
790
  if (event.type === 'session/title') {
789
791
  titles.set(session.id, event.data.title)
@@ -856,3 +858,13 @@ export function apply(ctx, config) {
856
858
  if (digestTimer) clearInterval(digestTimer)
857
859
  })
858
860
  }
861
+
862
+ export function apply(ctx, config) {
863
+ try {
864
+ return applyImpl(ctx, config)
865
+ } catch (err) {
866
+ console.error('[dsh-macos-notify] plugin initialization failed:', err)
867
+ notifyStartupFailure(err, config?.sounds?.error)
868
+ throw err
869
+ }
870
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-macos-notify",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Native macOS notifications and configurable sounds for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -40,6 +40,7 @@
40
40
  "inject": [
41
41
  "@deepseek-ai/dsh-client-connection",
42
42
  "@deepseek-ai/dsh-client-runtime",
43
+ "@deepseek-ai/dsh-client-ui-settings",
43
44
  "@deepseek-ai/dsh-client-ui-slots"
44
45
  ]
45
46
  }