deadbushxw/dsh-task-ask-notify ↗★ 0

dsh-task-ask-notify

模型回复完成或提问时触发系统通知与声音提示 适合在后台运行长任务的用户,能及时接收模型响应提醒,避免挂机等待。

套件
dsh-task-ask-notify
相容性
待驗證
版本
0.1.0
授權
MIT
最近更新
2026年10月1日

安裝

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:deadbushxw/dsh-task-ask-notify

Configuration

The configuration page in DSH

The plugin ships a browser half, so it is configured from the interface:

Plugins list → dsh-task-ask-notify — the form is rendered directly on the bundle's page, and the same page is also reachable from the configure control on the plugin's row. It edits the everyday settings: the master switch, the completion alert and its quiet period, the single/multiple question alerts, sound on/off, volume and the minimum gap, notification on/off, the question-in-body option, and whether subagent sessions alert.

Saving takes effect immediately: a change is committed into the running plugin, so the next alert already uses it. No restart, no reload, no file editing.

Listen. Next to the volume number, one button plays a sound so the setting can be judged by ear instead of guessed at. One click applies whatever is on the page and plays one sound through the same path a real alert takes — same directories, same uniform choice, same adapter, same volume — with the notification suppressed, so what you hear is what you will hear. It draws its sound from a randomly chosen scenario (complete, ask-single, ask-multiple), which means it plays one of the sounds you imported, not a sample shipped with the plugin. It deliberately still works when sound.enabled is off, since calibrating the volume before switching sound on is a reasonable order to do things in.

Those fields are declared .volatile() in the exported schema, which is what makes DSH offer a form for them at all and what lets an edit reach a running plugin; the page writes through DSH's own settings service, so a refused or conflicting write is reported rather than silently lost. Everything not on the page — sound directories, notification wording, the AUMID — is changed in the layers below, because those need a reload rather than a live update.

The file layers

Two layers, the later one winning per field:

  1. the plugin row's config in cordis.patch.yml (validated by the Loader against the exported Config schema — this is the same schema DSH's own configuration surfaces project); and

  2. an optional JSON file you own, outside this repository:

    %DSH_HOME%\plugin-data\dsh-task-ask-notify\config.json
    

    %DSH_HOME% is %USERPROFILE%\.dsh by default. Override the whole path with the DSH_TASK_ASK_NOTIFY_CONFIG environment variable.

The JSON file is re-read whenever it changes, so you can correct a value while DSH is running. A file that is not valid JSON, or holds a value the schema rejects, is reported in the log and then ignored — the last good configuration stays in force, and the reason is printed with the offending field path. The JSON layer wins over the page and over the row, so a field you pin there is not editable from the interface.

Every field is optional; omitted fields fall back to the value in the table. To turn every alert off without uninstalling, write {"enabled": false}.

FieldDefaultMeaning
enabledtrueMaster switch for all three scenarios.
complete.enabledtrueAlert when a turn ends cleanly.
complete.dir"audio/complete"Sound directory. Relative paths prefer your audio folder, then the package; absolute paths are used as given.
complete.debounceMs2000Quiet period after a clean turn end before alerting. Raise it (for example to 15000) if a multi-turn goal task should produce one alert instead of several; short tasks then wait that long too.
askSingle.enabledtrueAlert when the model asks one question.
askSingle.dir"audio/ask-single"Sound directory.
askMultiple.enabledtrueAlert when the model asks two or more questions.
askMultiple.dir"audio/ask-multiple"Sound directory.
sound.enabledtruePlay a sound at all.
sound.volume100Playback volume on a 0–100 scale: 0 is silent, 100 is the file at full amplitude. A stored value in (0, 1] is read as the old 0–1 scale and multiplied by 100, so an existing setting keeps its loudness.
sound.minGapMs400Two alerts closer than this share one sound. Both still notify.
sound.auditionAt0Diagnostic, not a preference: the page's Listen button sets this to the time of the click, and the plugin plays one sound whenever it changes.
sound.fallback"audio/_default/chime.wav"Used when a scenario directory is empty or missing. A directory here is also accepted. Resolved the same way as the scenario directories.
sound.maxDurationMs10000Hard cap on how long a playback process may live.
notify.enabledtrueShow a Windows notification.
notify.aumid"com.deepseek.dsh"The AUMID that owns the toast. Change it only if DSH's shortcut changes; see Troubleshooting.
notify.silentSystemSoundtrueSuppress the Windows notification sound, because the plugin plays its own file.
notify.bodyMaxChars80Longest notification body kept before truncation.
notify.includeQuestionInBodyfalseAppend the first question to the notification body. Off by default: the body is the session title.
dedup.completeMs3000Repeat completion alerts for one session inside this window are dropped.
sessions.includeSubagentsfalseAlso alert for subagent sessions. Off by default so a fan-out of background helpers does not produce a wall of notifications.
messages.completeTitle"任务完成"Notification title for a finished turn.
messages.askSingleTitle"需要你回复"Notification title for one question.
messages.askMultipleTitleTemplate"有 {count} 个问题等你回复"Notification title for several; {count} is replaced.
messages.fallbackBody"DeepSeek Harness"Body used when the session has neither a title nor a workspace directory.

Example — quieter, English wording, and a directory you already keep sounds in:

{
  "complete": { "debounceMs": 15000, "dir": "D:\\my-sounds\\done" },
  "askSingle": { "dir": "D:\\my-sounds\\ask" },
  "askMultiple": { "dir": "D:\\my-sounds\\ask-many" },
  "sound": { "volume": 0.5 },
  "messages": {
    "completeTitle": "Task finished",
    "askSingleTitle": "Your input is needed",
    "askMultipleTitleTemplate": "{count} questions are waiting",
    "fallbackBody": "Session"
  }
}

The notification body is the session title, falling back to the name of the session's workspace directory, then to messages.fallbackBody.


The configuration page in DSH

The plugin ships a browser half, so it is configured from the interface:

Plugins list → dsh-task-ask-notify — the form is rendered directly on the bundle's page, and the same page is also reachable from the configure control on the plugin's row. It edits the everyday settings: the master switch, the completion alert and its quiet period, the single/multiple question alerts, sound on/off, volume and the minimum gap, notification on/off, the question-in-body option, and whether subagent sessions alert.

Saving takes effect immediately: a change is committed into the running plugin, so the next alert already uses it. No restart, no reload, no file editing.

Listen. Next to the volume number, one button plays a sound so the setting can be judged by ear instead of guessed at. One click applies whatever is on the page and plays one sound through the same path a real alert takes — same directories, same uniform choice, same adapter, same volume — with the notification suppressed, so what you hear is what you will hear. It draws its sound from a randomly chosen scenario (complete, ask-single, ask-multiple), which means it plays one of the sounds you imported, not a sample shipped with the plugin. It deliberately still works when sound.enabled is off, since calibrating the volume before switching sound on is a reasonable order to do things in.

Those fields are declared .volatile() in the exported schema, which is what makes DSH offer a form for them at all and what lets an edit reach a running plugin; the page writes through DSH's own settings service, so a refused or conflicting write is reported rather than silently lost. Everything not on the page — sound directories, notification wording, the AUMID — is changed in the layers below, because those need a reload rather than a live update.