AllDSH
中文

dsh-notifier

THEWOLFWALKER · THEWOLFWALKER/dsh-notifier

One notify() API over 27 channels, plus approvals, questions and session control answered from your phone — heartbeats and stall alerts included, zero runtime dependencies.

dsh-notifier is a DSH plugin by THEWOLFWALKER. One notify() API over 27 channels, plus approvals, questions and session control answered from your phone — heartbeats and stall alerts included, zero runtime dependencies. It is filed under Integrations & Connections and Workflow & Automation, for Notifications. Verification level L3 (Install spec), an automated security scan has not run yet, and it targets DeepSeek Harness >=0.1.0-rc.6; the listing was last checked on 2026-09-17 and is published under the MIT licence. Install it with dsh plugin --profile web add dsh-notifier

Listing checked by Chiyu , data updated · How to cite

L3active
dsh-notifier verification panel: level L3 of 5 (Install spec) — Install command parsed, DSH target declared. Security scan: unverified — no scan has run. Compatibility target: DeepSeek Harness >=0.1.0-rc.6. Licence: MIT. GitHub stars: 49. Listing last checked 2026-09-17.
Verification panel for dsh-notifier. The listing holds level L3 of 5 — Install spec: Install command parsed, DSH target declared. Security scan: unverified — no scan has run. Compatibility target: DeepSeek Harness >=0.1.0-rc.6. Licence: MIT. Listing last checked 2026-09-17. How verification works

Install command

dsh plugin --profile web add dsh-notifier

Requires a running harness: start it withnpx @deepseek-ai/dsh webthen run the command above.New to this? See the installation guide.

What it does

dsh-notifier puts one notify() call in front of 27 delivery channels, then adds the things a notification alone cannot do: answer an approval, answer a question, and stop a runaway turn — all from the phone that already received the message.

Two trigger lines feed the same core. The harness pushes session events on its own (turn/end, approval/asked, agent/error), debounced and deduplicated; and the model calls a notify tool directly with { message, channel, title }. Every message then resolves through one chain — level (timeSensitive / active / passive) → routing (a multi-agent × channel matrix) → channel adapter — so per-channel delivery semantics such as silent push, priority headers or @-mentions follow from the level rather than from per-call special cases.

Outbound-only would already be a complete plugin. What makes it more than that is the reverse direction.

The half that is not a notifier

Six of the channels also open inbound, over long-lived connections or long polling, so no public IP or port forward is required (only the WxPusher callback needs one). Through them:

  • Remote approval. Answer an approval from your phone. Telegram and Feishu get native cards, QQ gets native buttons in 1:1 chats, and channels without cards fall back to a numbered reply. Group destinations use a safe text fallback. The README’s rule is blunt and correct: silence never approves, and decisions are single-use and fail-closed — unknown sources and QQ group control are rejected by default.
  • Remote questions (ask_user). The model asks you multiple-choice questions on your phone: one to four questions, two to five options each, multi-select supported. Telegram’s single-select cards also carry custom-answer and skip buttons, token-checked with first-arrival-wins. An out-of-range answer re-prompts without voiding the question, and a timeout never fabricates an answer.
  • Remote conversation. Plain text becomes followup or inject; a ! prefix steers mid-turn; a merge window reassembles the way people actually type on a phone.
  • Session control. /stop cancels the turn, /quiet and /unquiet mute a session’s pushes, and the /agent family rebinds which session a chat is driving.

Long turns are covered too, and on by default since v0.5: a heartbeat after 15 minutes and then every 15 minutes, a stall alert after 10 minutes of silence, and a ⏹ stop button on the Telegram and Feishu cards using the same one-time-token chain as approvals. turnStart is deliberately off, and the README’s reason is a good one — one message per turn is noise when you are at the desk, and you turn it on when you are not.

Identity is a runtime object rather than a YAML list: pairing codes (/pair <code> in any DM, first redeemer becomes owner), composite-key bindings (channel:userId, so a Telegram-bound id does not admit a Feishu message), role management, and rejection receipts that tell an unbound sender how to get in. An empty whitelist boots into a guided state with a bootstrap pairing code written to a local 0600 file — the log prints the path, never the code — instead of refusing to start.

27 outbound channels, six that answer back

The channel matrix is generated from the code (node scripts/gen-channel-matrix.mjs), which is a good sign: it is a registry, not a README table that drifts. The set spans three kinds of destination:

  • IM platforms — Telegram, Slack, Discord, Feishu, DingTalk, WeCom (group robot and app message), QQ bot, OneBot, Microsoft Teams, Mattermost, Google Chat.
  • Push services — Bark, Pushover, PushDeer, Chanify, ntfy, Gotify, iGot, WxPusher, PushPlus, Server酱, Qmsg, 息知. Several of these are China-market apps, which is where this plugin’s coverage is genuinely wider than most.
  • Local and generic — a terminal bell, a native desktop notification (osascript / notify-send / a PowerShell toast), and a plain webhook.

Inbound is the six listed above: telegram, feishu, qq-bot, wxpusher, wechat and dingtalk.

Requirements and install

  • Node >=22.

  • Harness: the README states --profile is required from DSH 0.1.0-rc.6+, and the manifest’s compatibility block lists 0.1.0-rc.6. This listing records the floor as >=0.1.0-rc.6 — the author’s own 0.1.0-rc.6+ rendered as a semver range — and that declaration is what makes it L3.

  • From npm (published, 0.10.2 at the time of writing):

    dsh plugin --profile web add dsh-notifier

    The README writes the same command with the flag last (dsh plugin add dsh-notifier --profile <profile-name>); the order does not matter, the profile name does.

  • Then restart DSH and open the link the startup line prints — http://127.0.0.1:<port>/#token=.... The token lives only in the URL fragment and is printed once; port conflicts fall back to a free port automatically. The first-visit wizard walks you through channel → credentials → “send a real test notification”, and setup is finished when your phone buzzes.

  • Uninstall: dsh plugin --profile web remove dsh-notifier.

What it declares, and what that costs you

Two things are worth reading before installing, and both come from the package rather than the prose.

It asks for a lot of permissions. The manifest declares harness:tool, harness:event, network:outbound, network:listen, file:read, file:write, subprocess:exec and credentials:write. Some of that is unavoidable — an HTTP listener for the console, credential storage for 27 channel tokens, a subprocess for desktop toasts — but credentials:write plus subprocess:exec is the combination to notice. The mitigation is structural rather than promised: secrets are typed role('secret') and redacted everywhere, and ${ENV:NAME} references keep them out of the profile.

Zero runtime dependencies is not a slogan here. dependencies is empty. The two entries in optionalDependencies are exact-pinned and lazily imported, and their absence degrades one channel with an install hint instead of breaking startup. There is also a licensing decision worth crediting: @tencent-connect/qqbot-connector is not a dependency, because npm flags it UNLICENSED — the README states it stays a design reference only and is never copied, redistributed or introduced as a dependency.

A test count, reported. The package declares dshQuality.testCount: 1616 and the README repeats “1616 automated contract tests (1616 pass)”. This directory did not run them; that is the author’s claim, and it is recorded as one.

Configuration

Channels live under config.channels:

insert:
  - id: dsh-notifier
    config:
      channels:
        - type: telegram
          botToken: "123456:ABC-DEF..."
          chatId: "987654321"
        - type: feishu
          webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/..."
        - type: serverchan
          sct: "SCT..."

Optional blocks each opt in under their own key — inbound (allow users; first import only, managed at runtime afterwards), approval (mode: answer), conversation (mergeWindowMs), route (sessionTtlHours), admin (on by default, loopback only), events/keywords/graceSeconds (anti-disturb gates), digest (ledger plus a daily summary), and the v0.5 status line (longRunning.firstAfterMs: 900000).

The status line defaults matter more than they look: longRunning and stall are on with a 15-minute first heartbeat and a 10-minute stall threshold, and all timings clamp to a 60-second floor. That means a long task is no longer a black box out of the box — and also that a session which goes quiet will page you. Both are configurable, and both can be switched off with enabled: false.

Known limits

  • The author is on exam leave until 2026-10-01. The README opens with a maintenance notice: until that date the author cannot promptly maintain the project or review PRs and issues, and replies will be delayed. This is a declared, temporary window, not an abandoned project — the last push was 2026-09-13, three days before this listing — but if you need upstream responsiveness this month, plan for the delay.
  • Outbound config changes are “view-hot, delivery-cold”. Saving a channel in the admin console updates the UI immediately and badges the card “重启后生效”; the delivery layer merges runtime config only at the next plugin startup. Test-send is the exception and runs against the latest config at once. This is documented honestly and it is still the most likely thing to confuse you.
  • The web console is a second control surface, and it is one. It binds loopback only and authenticates with a bearer token carried in the URL fragment, which is a reasonable design — but it is still an HTTP listener on your machine with credentials:write behind it. Treat the printed link as a secret.
  • Six channels can drive the session, and five of them are chat platforms. The identity system is genuinely careful (single-use decisions, fail-closed, composite-key bindings, group control refused). The residual risk is the ordinary one: whoever holds your phone can approve.
  • Star counts disagree with themselves. This listing records the live figure, 49. The nightly index recorded 95 for the same repository — a decrease, not a typo, and a reminder that stars measure accumulated exposure and can move in both directions.
  • The name space is crowded. In the nightly index, 144 repositories carry “notif” in their name and 119 of them sit at 0–2 stars; this is one of only two above 50. It is also one keystroke away from dsh-notification, which is a different project by a different author with a different install path. Read the last four characters.
  • Stars (49) are attention, not review. This listing records security: unverified; no third-party scan or independent audit is on record, and no listing on this site claims L4 or L5.

When to use it — and when not to

Use it when the session outlives your attention and the phone in your pocket is where you want the decision to land. The interesting capability is not the 27 channels — it is that an approval, a multiple-choice question and a stop button all arrive with the notification, so you can keep a long run moving without going back to the desk. If you already use a China-market push app, its coverage is wider than most of the field.

Do not install it because it is the biggest notifier here. It asks for credentials:write and subprocess:exec, it stores channel credentials, and it opens an inbound path from six platforms into a session that has tools. If the machine running the harness is the machine you are looking at, dsh-notification does the job with no credentials at all and nothing added to the model’s context. If what you want is to hold an actual conversation with the session from a chat window, dsh-im is the more direct shape — with its own, larger access-control obligations.

FAQ

Is it a notifier or a remote control?

Both, and the split is clean. Outbound is a notifier: 27 channels, level routing, retries, segmentation, anti-disturb rules, a ledger. Inbound is a remote control for six of those channels: approvals, questions, conversation and /stop. You can use the first half and never enable the second — inbound is opt-in.

Does it need a public IP or a port forward?

No. Every channel is reached outbound over a long-lived connection or long polling. The single exception named in the README is the WxPusher callback, which does need to be reachable.

What happens if a channel is misconfigured?

Startup survives. A misconfigured channel is skipped silently with a log line, which is the right failure mode for a notifier — the alternative is a plugin that refuses to boot because one push service changed its API.

Can other plugins send through it?

Yes, and it is a documented contract rather than an accident. Another plugin injects the notifier service (ctx.inject(['notifier'], …)) and shares the config, routing, ledger, rate limits and flush, or subscribes to delivery metadata via ctx.on('dsh-notifier/sent'). Broadcast and directed sends each produce one audited event, and message text is never exposed. Per-source rate limiting is 10 per minute, with a 20,000-codepoint clamp and a never-reject API.

Where do the credentials live?

In the profile and the runtime store, with ${ENV:NAME} references supported so the values can stay in the environment. Secrets are typed role('secret') and redacted wherever they would otherwise be rendered, and the console’s credential forms show masked values — untouched masked fields are never resubmitted.

Sources & references

The technical claims on this page rest on the primary documents below. Each link is followed so it can be checked directly.

  1. [1]THEWOLFWALKER/dsh-notifier — GitHubThe plugin’s own repository and README — the primary document every claim in this listing is checked against.
  2. [2]dsh-notifier on npm — npmThe published package the install command on this page resolves.
  3. [3]deepseek-ai/deepseek-harness — GitHubUpstream repository for DeepSeek Harness, the Cordis runtime and the plugin loading model.
  4. [4]@deepseek-ai/dsh on npm — npmPublished harness package, including the release tags our dshTarget field tracks.
  5. [5]dsh-plugin GitHub topic — GitHubThe discovery mechanism used to find plugins listed in this directory.

All links last verified 2026-09-11

Questions about this listing

Is dsh-notifier safe to install?
dsh-notifier holds verification level L3 of 5 — Install command parsed, DSH target declared — and its security status is unverified — no scan has run. A verification level records how far the install path was exercised; it is not a safety guarantee. Safety depends on what the plugin can actually reach, so read its source and install script and check its file, shell, network and credential access before you run it.
Which DeepSeek Harness version does dsh-notifier target?
dsh-notifier declares dshTarget >=0.1.0-rc.6, the DeepSeek Harness release this listing was checked against. dshTarget is the compatibility target the plugin author declares: it records that a release was checked, not that the plugin keeps working after upstream ships something new. Test in an isolated profile before upgrading your harness.
How do I install dsh-notifier?
Start the harness with npx @deepseek-ai/dsh web, then copy the install command shown at the top of this page. That command is generated from the package name the repository publishes — or from an install spec the listing declares — so it cannot drift from what the repository actually ships. This listing was last checked on 2026-09-17.
Is it a notifier or a remote control?
Both, and the split is clean. Outbound is a notifier: 27 channels, level routing, retries, segmentation, anti-disturb rules, a ledger. Inbound is a remote control for six of those channels: approvals, questions, conversation and /stop. You can use the first half and never enable the second — inbound is opt-in.
Does it need a public IP or a port forward?
No. Every channel is reached outbound over a long-lived connection or long polling. The single exception named in the README is the WxPusher callback, which does need to be reachable.
What happens if a channel is misconfigured?
Startup survives. A misconfigured channel is skipped silently with a log line, which is the right failure mode for a notifier — the alternative is a plugin that refuses to boot because one push service changed its API.
Can other plugins send through it?
Yes, and it is a documented contract rather than an accident. Another plugin injects the notifier service (ctx.inject(['notifier'], …)) and shares the config, routing, ledger, rate limits and flush, or subscribes to delivery metadata via ctx.on('dsh-notifier/sent'). Broadcast and directed sends each produce one audited event, and message text is never exposed. Per-source rate limiting is 10 per minute, with a 20,000-codepoint clamp and a never-reject API.
Where do the credentials live?
In the profile and the runtime store, with ${ENV:NAME} references supported so the values can stay in the environment. Secrets are typed role('secret') and redacted wherever they would otherwise be rendered, and the console's credential forms show masked values — untouched masked fields are never resubmitted.

Similar DSH plugins

Browse all

Model-facing Word, Excel and PowerPoint tools that create and read files through the official DSH filesystem service, inside the session workspace.

L3
20 TypeScript

DSH SSH Ops

caoyiwei850

Drive SSH operations from the main conversation with dangerous-command protection and a side terminal.

L3
20 TypeScript

DSH-IM

xmanrui

Bridges ten IM platforms to DSH sessions over persistent outbound connections, with per-channel access policies.

L3
1.4k JavaScript

DSH Mobile

saya-ch

Use DSH from your phone — Android app or browser over paired LAN HTTPS, with optional remote tunnels and in-chat UI customization.

L3
274 TypeScript

DSH Web

zhu1090093659

An aggregation bundle that brings fifteen Web GUI extensions into one DSH install, mounted through the official web profile.

L2
7.7k TypeScript

Three components, three install paths: a restart-free runtime plugin injector, routing agent presets, and a graded task protocol.

L3
7.2k JavaScript
ESC

Type to search the index. Built at deploy time by Pagefind.