DSH Plugins Marketplace

DSH Plugins

Plugins

/

Security & Audit

/

dsh-tab-watchdog

a

dsh-tab-watchdog

Manifest valid

Tab Watchdog for DeepSeek Harness Web: when a workspace finishes a work round (green) or needs attention (error, question, approval) the tab title blinks with a badge. Persistent two-half plugin (host + browser).

UI (client)hasBundlePatch

dsh-tab-watchdog

A persistent plugin for DeepSeek Harness Web: when one of your workspaces/sessions finishes a work round, errors out, or needs your input, the browser tab signals it — a little whale (the DeepSeek Harness logo) blinks green or yellow in the favicon, and the tab title shows the overall pending counter.

This is the "bundle" version (persistent, installable, shareable) of the Tab Watchdog dynamic plugin originally developed in Creator mode. Unlike a dynamic plugin it survives dsh restarts and browser reloads (F5).

How it works (architecture)

Two halves in a single npm package, like the official plugins:

  • Host half (index.js) — profile composition row (cordis.patch.yml + dsh.bundle.patch). It makes the package a Loader entry: that row is what pulls the browser half into the boot manifest. No business logic here.
  • Browser half (lib/client.js, served via dsh.client + the ./client export) — a bundle in the window.__ModuleLoader__.load({ id, factory }) format. It subscribes to the Host events forwarded to the browser (ctx.remote.$on) and handles everything (state, watermark, blink). No UI is added to the harness.

Triggers (what makes it blink)

The browser only receives the events on the dsh-api-remotes allowlist. The watchdog uses:

EventLevelLabel
api-session/status(sessionId, running=false)🟢 green whale"Finished a work round"
api-session/error(sessionId, message)🟡 yellow whale"Error…"
pending approval interaction🟡 yellow whale"Requires approval"
pending question / plan-review interaction🟡 yellow whale"Asking for a response"

Green/errors use the forwarded emit events (ctx.remote.$on). Yellow for questions and approvals does not rely on the user-questions/request/approval/request waterfall events: those are single-consumer and claimed in registration order by the official UI answerers, and the forwarded request does not carry a stable session id. Instead the watchdog polls the state the official UI publishes while it waits on you: ctx.uiSession.pendingInteractions.getSnapshot() — a Map<sessionId, interaction> with kind ∈ approval | question | plan-review. The poll runs in the existing 1s tick; entries are re-bumped while pending and removed when the interaction clears, so an answer stops the blink by itself. This covers every session in the app, not just the one in view.

Note: workflow/end, agent/status, and goal/changed are not forwarded to the browser in this version's allowlist; observing them would require host-side aggregation over a custom channel (out of scope by design). The yellow path depends on the app's own pending-interaction UI (ui-approval/ui-user-questions) publishing its wait state; if a third-party answerer claims a request without going through that UI, that interaction cannot be seen from the browser.

Blink model (watermark)

  • Events only arrive while the page is open (even on another browser tab — that is exactly the intended use case).
  • New events stay "pending" until you come back to the page.
  • While the page is not focused and at least one item is pending, the favicon whale blinks (alternating with the original favicon) and the title alternates between N · <title> and <title>, where N is the overall pending count across sessions and levels.
  • Whale color: green when only finished rounds are pending, yellow when there is any error/question/approval, and it alternates green↔yellow when both kinds are pending at once.
  • The original favicon is captured on load and always restored when you come back (or when pending clears) — nothing is permanently altered.
  • An event that arrives while you are focused is marked read immediately (no leftover blinking).
  • When a session restarts (running=true), its pending entries are removed.
  • An error on a session "freezes" its entry in yellow: a later running=false does not downgrade it to green.

Installation (local web profile)

From the plugin checkout:

# from the directory that contains dsh-tab-watchdog/
npx @deepseek-ai/dsh@latest plugin --profile web add ./dsh-tab-watchdog

Then restart dsh web. The browser half activates on the next reload/startup. The added row is the tab-watchdog entry in the profile's cordis.yml.

Removal:

npx @deepseek-ai/dsh@latest plugin --profile web remove dsh-tab-watchdog

dsh plugin forwards to pnpm inside the profile. If pnpm is not installed: corepack enable or npm i -g pnpm.

Development

The browser half source is src/client.js (a CJS fragment living inside the loader factory). The lib/client.js artifact is committed (no build step at git-install time).

npm run build   # regenerates lib/client.js from src/client.js
npm test        # verify (bundle structure) + smoke (blink/watermark logic)

No prepare/monorepo toolchain needed: out-of-tree plugins cannot use the internal clientBundle preset, so the loader format is reproduced by hand (scripts/build.mjs).

Sharing with the community

The package declares dsh.bundle.patch, so it installs as a profile bundle. Because lib/client.js and index.js are committed artifacts, a git install works without prepare:

npx @deepseek-ai/dsh@latest plugin --profile web add github:andreagosto/dsh-tab-watchdog

For discoverability, the GitHub repository carries the dsh-plugin topic (see the official deepseek-harness README, "Community and support"). Alternatively: npm publish, then dsh plugin --profile web add dsh-tab-watchdog.

Notes and limitations

  • Tested against runtime @deepseek-ai/dsh 0.1.2-rc.1 (mind the "breaking changes" notice on rc prereleases).
  • The browser half is hand-written against the APIs observed in the installed bundles; the structure is validated by npm test, but verify it live in your own profile.
  • No settings namespace: the plugin does not appear in Settings → Plugins. To disable it use dsh plugin remove (or set disabled: true on the row in the profile patch).

License

MIT

Comments

Loading…

Similar plugins

dsh-web-attention-badge

by Luaphes

Attention reminders for the DeepSeek Harness Web UI: frame badge, (N) tab title and whale-favicon recolor for sessions waiting for input or finished unopened.

UI & ExperienceManifest valid

★ 6

↓ 319/wk

MIT

JavaScript

Sep 9, 2026

dsh plugin --profile web add dsh-web-attention-badge

by houlain

DeepSeek Harness plugin: workspace file browser + code viewer + session change diff + per-hunk partial revert (Trae-style). Windows verified only; Linux/macOS untested — use with caution.

Development & InfrastructureManifest valid

★ 1

MIT

TypeScript

Aug 16, 2026

dsh plugin --profile web add dsh-workspace-studio

by The-latest-one

DeepSeek Harness (DSH) sidebar plugin: stack-safe fork tree, two-track indentation, marquee title, leading/hover slots, and cascade purge.

UI & ExperienceManifest valid

★ 5

MIT

TypeScript

Oct 3, 2026

dsh plugin --profile web add dsh-branch-workspace-folders

by baifagg

DeepSeek Harness (dsh) Web GUI plugin: highlight running sessions and pin busy workspaces to the top of the sidebar. Theme-adaptive, zero-config.

Development & InfrastructureTerminal & ClientsUI & ExperienceManifest valid

★ 0

MIT

JavaScript

Sep 28, 2026

dsh plugin --profile web add dsh-plugin-busy-workspace

by bigfurma-bot

Approval attention watcher for DeepSeek Harness: bell sound + tab-title flash whenever an approval needs the owner's decision

Manifest valid

★ 0

JavaScript

Aug 23, 2026

dsh plugin --profile web add @deepseek-ai/dsh-attention

by gorban

DeepSeek Harness (dsh) plugin: stop a running background job from the session-header job list, behind a confirmation dialog.

Development & InfrastructureTerminal & ClientsUI & ExperienceManifest valid

★ 1

↓ 276/wk

MIT

TypeScript

Sep 20, 2026

dsh plugin --profile web add @gorban/dsh-job-stop