Skip to content

Releases: ltao0829/dsh-task-notify

v0.3.0 — notification customization, coverage gate, downloads badge

Choose a tag to compare

@ltao0829 ltao0829 released this 02 Oct 07:38

The first feature release on the DSH 0.2 line: notification customization, a coverage regression gate, and an npm downloads badge. No peer range changed, so a 0.2.x install upgrades in place.

Install

# from npm — name the range, see the cooldown note below
dsh plugin --profile <name> add @ltao0829/dsh-task-notify@^0.3.0

# or from Git, pinned to a release tag
dsh plugin --profile <name> add git+https://github.com/ltao0829/dsh-task-notify.git#v0.3.0

Then restart dsh web and refresh the page. The settings page appears under Settings → Plugins → 任务完成提醒.

Naming a version matters. pnpm 11 defaults minimumReleaseAge to 24 hours, so a release published less than a day ago is invisible to version resolution. Measured on 2026-10-02, four minutes after this release published, the bare dsh plugin add @ltao0829/dsh-task-notify resolved to 0.1.0 — the newest release older than 24 hours, which is not necessarily the immediately previous one — and the compatibility gate refused it. The refusal is explicit, and DSH restores package.json, the lockfile, and node_modules rather than leaving a half-installed profile. An explicit version or range is recorded in minimumReleaseAgeExclude and installs immediately; both directions were verified against this release.

Highlights

  • Title / body templates with {title} (task title), {session} (session ID), and {kind} (localized event type) placeholders. Empty templates keep the built-in localized copy, unknown placeholders stay as written, and output is rendered as plain text — a template cannot inject markup.
  • Four sound styles — none / single tone / the classic two-tone / a custom audio URL — plus a 0–100% volume control. A custom mode with an empty URL falls back to the two-tone; an unloadable URL degrades to silence.
  • Toast placement and duration — any of the four screen corners, and 3–15 seconds on screen (previously fixed at bottom-right for 5 seconds).
  • Quiet hours and per-session mute — a local-time window that may cross midnight (e.g. 22:00 → 08:00) suppresses every reminder, and named sessions never trigger one.
  • A raise-only coverage gate over src/**, plus an npm downloads badge backed purely by npm's public download API. No client-side reporting was added — the privacy guarantee is unchanged.

What changed

Added

  • Notification customization. The eight boolean switches gained user-facing configuration: templates, sound style and volume, toast corner and duration, quiet hours, and a per-session mute list.
  • Test coverage measurement and regression gate. @vitest/coverage-v8 (pinned to the exact vitest version), a pnpm run coverage script, and V8 coverage over src/** with text + lcov reporters. CI runs coverage after the build on both Node legs and uploads coverage/lcov.info from the Node 24 leg as an artifact.
  • npm downloads badge in both READMEs. Caveat to keep attached to the number: it counts npm tarball downloads per month (CI installs and registry mirrors included), not active users.

Changed

  • Settings storage upgraded to dsh.taskNotify.v3. A leftover v2 record is migrated once — every toggle is kept, and the retired sound boolean maps to soundMode: 'double' (off maps to 'off') — after which the v2 key is removed. Every stored field is sanitized on load: junk values degrade to their defaults, and volume / toastSeconds are clamped into 0–1 / 3–15. Upgrading therefore preserves your existing switches; nothing needs re-configuring.
  • The body-template box is its own labelled field rather than a second box under the title label — a placeholder is not an accessible name.
  • The install-cooldown note is now written from a measured run rather than from the documentation of pnpm's behaviour.

Fixed

  • Corrected the DSH 0.1.x install path. Earlier documentation told DSH 0.1.x users to install 0.1.2, but npm has only ever carried 0.1.0 and 0.2.0, and no v0.1.1 / v0.1.2 tag exists, so the instruction could not be followed. The 0.1.x line is now documented as discontinued.

Verification

Verified against a real DSH 0.2.0-rc.2 in an isolated, disposable DSH_HOME (see docs/verification-evidence.md):

Stage Result
pnpm pack tarball packed from the tagged commit
dsh plugin --profile web add <tarball> accepted by the 0.2 compatibility gate
dsh --profile web --dump-config task-notify present in the composed bundle tree
dsh web boot boot document fetched at HTTP 200 (token redirect followed) and it references this plugin in the client module graph
Shipped bundle package/lib/client.js carries the __ModuleLoader__.load handoff; externals are only react and react/jsx-runtime, both in the frozen platform module table
dsh plugin remove plugin and its entry removed cleanly

Local pipeline: typecheck ✅ · 97 tests passing (9 suites, 1 skipped — a describe.skipIf pair, not a disabled test) ✅ · coverage ✅ · build ✅ · pnpm pack --dry-run ✅ · package metadata check ✅

Published artifact integrity: npm's shasum for 0.3.0 (3d0e8080f49e06e0ad14aad67b82baaef8386a58, 36 files, 299,295 bytes unpacked) is byte-identical to the tarball this verification ran against.

Also verified end-to-end from the public registry into a throwaway profile: @^0.3.0 installs 0.3.0 immediately and the installed lib/client.js contains the v3 settings store; the tagged Git install (#v0.3.0) installs 0.3.0 as well.

Not covered by automation: the script does not drive a real browser, so in-page behavior (notification permission, Web Audio unlock, React rendering, template expansion) is covered in jsdom by tests/notification.spec.ts and tests/settings-card.spec.tsx rather than end-to-end.

Full changelog: CHANGELOG.md

v0.2.0 — re-target at DeepSeek Harness 0.2

Choose a tag to compare

@ltao0829 ltao0829 released this 01 Oct 17:55

⚠️ Breaking re-target: this release supports DeepSeek Harness 0.2 only

The 0.1.x line was built on @deepseek-ai/dsh-client-runtime and the settings.plugin.item seat, both removed in DSH 0.2. DSH 0.2's install gate (which checks peerDependencies on @deepseek-ai/dsh*) refuses 0.1.x outright, and the plugin would not load even if it were forced in. Stay on v0.1.2 if you are still running DSH 0.1.x.

Re-targets the plugin at DeepSeek Harness 0.2 (0.2.0-rc.2).

Install

# from npm - name the range, see the cooldown note below
dsh plugin --profile <name> add @ltao0829/dsh-task-notify@^0.2.0

# or from Git, pinned to a release tag
dsh plugin --profile <name> add git+https://github.com/ltao0829/dsh-task-notify.git#v0.2.0

Then restart dsh web and refresh the page. The settings page appears under Settings → Plugins → 任务完成提醒. On the first click or keypress the browser asks for notification permission — allow it to receive OS-level notifications.

Naming a version matters. pnpm 11 defaults minimumReleaseAge to 24 hours, so a release published less than a day ago is invisible to version resolution: dsh plugin add @ltao0829/dsh-task-notify silently resolves to the previous version (0.1.0) and is then refused as incompatible. An explicit version or range is recorded in minimumReleaseAgeExclude and installs immediately. The bare name resolves to 0.2.0 once the release is a day old.

Highlights

  • Detection now folds three independent DSH 0.2 client sources instead of the retired single sessions.list store: ctx.sessions.list (catalog + Host baseline), ctx.uiSession.sessionStatus (live running state and the pending interaction), and ctx.jobs.state (per-Session job rosters).
  • Background jobs are watched per Session via IJobs.watchRows. The default opens one job.list stream per Session observed running since page load; a new "Watch every session" setting switches to the whole catalog.
  • A pending interaction is tracked by its opaque request key, so a replacement request (approval, then a question) reminds again while a reconnect replay of the same request stays silent.
  • Settings moved to the settings.plugins.tab seat — a page in the Plugins section rather than the retired settings.plugin.item card.
  • Toast copy is now localized (zh / en) through the plugin's own namespace instead of hard-coded Chinese.

What changed

Changed

  • Client context types come from @deepseek-ai/cordis plus each domain package's declaration merges; @deepseek-ai/dsh-client-runtime is no longer referenced anywhere.
  • Host half is now inert — the schemastery Config schema was dropped along with the dependency; the host half is a loader anchor and holds no settings.
  • Build externals track the 0.2 platform module table (@deepseek-ai/dsh-client-store and -ui-dockkit in; dsh-client-runtime, dsh-client-web-react, and dsh-client-schema-form out).
  • Theme tokens refreshed for the 0.2 alias table: the toast uses --dsw-alias-bg-overlay, and the settings page no longer uses the removed --dsw-alias-label-tertiary.
  • Node.js floor raised to >=22 (DSH 0.2's toolchain requires it); CI matrix is now Node 22 and 24.

Added

  • Manifest contract tests (tests/manifest.spec.ts): manifestVersion, the web client platform, the engines.dsh range, per-peer range pinning, and patch/plugin identity agreement.
  • tests/client-apply.spec.ts: drives apply(ctx) end-to-end against a fake client context — the seat the 0.1.1 keyed-slot regression escaped through.
  • tests/bundle.spec.ts and a new verification stage asserting the shipped lib/client.js requires platform modules only (a require the frozen module table cannot answer is a boot-time throw in the browser).
  • A "Watch every session" setting with zh / en copy.

Fixed

  • Installation is accepted again by DSH 0.2's compatibility gate. The retired dsh.compatibility block and the 0.1.x peer ranges are gone; every DSH peer and engines.dsh are pinned to ^0.2.0-rc.2.

Removed

  • The dsh.compatibility manifest block (dsh and dshReleases tables), which DSH 0.2 no longer reads.
  • The schemastery runtime dependency and the host Config schema.
  • The dsh.taskNotify.v1 storage key in favour of dsh.taskNotify.v2, so a DSH 0.2 install starts from clean defaults rather than inheriting a record written by the 0.1.x line.

Verification

Verified against a real DSH 0.2.0-rc.2 in an isolated, disposable DSH_HOME (see docs/verification-evidence.md):

Stage Result
pnpm pack tarball packed from the tagged commit
dsh plugin --profile web add <tarball> accepted — not refused by the 0.2 compatibility gate
dsh --profile web --dump-config task-notify present in the composed bundle tree
dsh web boot boot document fetched at HTTP 200 (token redirect followed) and it references this plugin in the client module graph, so the browser half really is served
Shipped bundle package/lib/client.js carries the __ModuleLoader__.load handoff; externals are only react and react/jsx-runtime
dsh plugin remove plugin and its entry removed cleanly

Local pipeline: typecheck ✅ · 62 tests passing (8 suites) ✅ · build ✅ · pnpm pack --dry-run ✅ · package metadata check ✅

Not covered by automation: the script does not drive a real browser, so in-page behavior (notification permission, Web Audio unlock, React rendering) is covered in jsdom by tests/client-apply.spec.ts and tests/notification.spec.ts rather than end-to-end.

Note on DSH 0.2's built-in reminders

DSH 0.2 ships its own scheduled reminder feature (dsh-schedule + a Schedules page, exposed to the model as the schedule_* tools). That is a different mechanism — a timer that fires a prompt. DSH still has no built-in OS-level notification when a turn or background job finishes (the session row only shows a small "done" dot), which is what this plugin provides.

Full changelog: CHANGELOG.md

v0.1.0

Choose a tag to compare

@ltao0829 ltao0829 released this 01 Oct 18:03

Added

  • Turn-completion reminder: fires when an agent turn (thinking or tool use) finishes.
  • Background-job reminder: fires when a background command or subagent job settles (completed / failed / killed).
  • Review-needed reminder: fires when a running task waits for approval, plan review, or a question answer.
  • Failure reminder: fires when an agent turn errors (lastAgentError) or a background job fails / is killed.
  • Three notification channels: OS-level browser notification, in-page toast, optional two-tone beep.
  • Per-event configuration with seven independent toggles, persisted in localStorage (dsh.taskNotify.v1).
  • Host half (src/index.ts) registering the task-notify settings section.
  • Pure snapshot-diff detector (src/detect.ts) with Vitest unit tests (tests/detect.spec.ts, 15 tests).
  • CI workflow (.github/workflows/ci.yml): typecheck + test + build on push and pull request.
  • English README.md and Chinese README.zh-CN.md documentation.

Security

  • No external server, telemetry, analytics, or API key. Notifications are generated locally; settings live in localStorage only; conversation content is never uploaded.