npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pi-unipi/watchdog

v3.0.3

Published

Jev watchdog for long-running tool calls and background tasks — judges stuck work via TypeSafe System One and kills or warns

Readme

Watchdog

Watchdog is on by default for bash calls; a stuck-looking call is handed to the background, never killed by default.

@pi-unipi/watchdog · part of UniPi

What it does

  • Watches running bash calls by default; background tasks and other tools are opt-in.
  • Asks jev, the UniPi Decision Model, if each item is progressing, waiting, stuck or looping.
  • Acts only after 2 checks in a row agree, using a stop score of 0.5 (bash) or status confidence of 0.5 (other items).
  • Protects dev servers, file watchers and daemons that run normally.
  • Gives the agent the background task ID, captured output and reason, so it can use bg_logs, bg_kill, or carry on.
  • Never automatically judges or kills a task it moved to the background.
  • Is on by default for bash only. With no watched calls, the heartbeat makes no jev requests.

Quick start

Watchdog ships in @pi-unipi/unipi. To install it alone:

pi install npm:@pi-unipi/watchdog
  1. Type /unipi:settings.
  2. Open the Watchdog group.
  3. Adjust the defaults if needed; bash watching is already enabled.
  4. Start a new session. Watchdog starts its timer at session start.

/unipi:bg-detach [reason] manually moves the most recently started foreground bash call to the background. It works independently of the automatic watchdog setting. Watchdog has no agent tools.

What it watches

| Item | Setting | Action | |---|---|---| | bash tool calls | watchBash | Returns the call early and adopts its process as a background task by default. | | Background tasks | watchBgTasks | Stops the task through the background task registry. | | Other tools (web, image, MCP, subagents) | otherTools | Warns, or aborts the turn. |

Watchdog never watches read, write, edit, grep, find, ls, ask_user, read_subagent, bg_kill or bg_tasks. It also skips a background task that has no completion trigger, because that task is a server.

Settings

Open /unipi:settings → Watchdog. The namespace is watchdog.

| Key | Default | What it does | |---|---|---| | enabled | true | Turns the watchdog on. | | intervalMin | 3 | Minutes between two checks of one item. | | firstCheckMin | 2 | Minimum age of an item, in minutes, before its first check. | | confidence | 0.5 | Stop score for bash; status confidence for background tasks and other tools. Range 0 to 1. | | agreeChecks | 2 | Number of checks in a row that must agree. | | action | background | background returns bash early without killing; kill stops it; warn leaves it running and queues a warning. | | watchBash | true | Watches bash calls. | | watchBgTasks | false | Watches background tasks. | | otherTools | off | off, warn or abort-turn for tools that Watchdog cannot stop. |

The group also has a Decision model section. Set decisionModel.source to inherit or custom.

action applies to bash calls only. Ordinary stuck background tasks retain the existing stop behavior even when action is warn; watchdog-adopted tasks are excluded entirely.

How a bash call is judged

Bash calls use Linux process activity plus jev's stop question. A call triggers when:

  • Two checks are idle with no CPU, disk or output activity, and no sleeping process.
  • The stop score meets the threshold for the configured consecutive checks.
  • Jev expects the command to finish within seconds, but it has reached its first watchdog check.

An explicit timeout, chained sleep, or bounded seq/sleep loop vetoes every trigger until its declared time bound expires. Missing process samples never count as idle. Background tasks and other tools retain the existing status-based decision path.

How it works

  1. A timer runs every 15 seconds or less. It does not call jev until an item is due.
  2. For each due item, Watchdog sends jev the command and its run time. It also sends the time since new output, and the last 3,000 characters of output.
  3. jev answers two questions. status is one of progressing, waiting, stuck or looping. persistent scores if the item is a service that runs normally.
  4. Watchdog acts when all of these are true:
    • status is stuck or looping.
    • The confidence is at or above confidence.
    • The item is not a normal service. A looping item is never a normal service.
    • agreeChecks checks in a row agree.

Utility wraps pi's local bash operations in every render style. When detaching, the background-task registry takes ownership of the same child, output stream and original start time. The tool returns normally; completion later sends the normal background notification and wakes the agent. Esc after detachment does not stop the adopted command. Background-task shutdown cleanup and bg_kill still apply.

If adoption is unavailable (for example, background-tasks is disabled), automatic background falls back to the existing kill path: it stops the process group only when exactly one child matches the command. With zero or many matches, or on Windows, it queues a warning. Explicit kill uses that same path.

The tool result of a stopped call starts with a line like this:

⚠ Killed by unipi watchdog after 410s: jev judged it judged stuck; stuck (confidence 0.92) on 2 consecutive checks — no new output for 300s. Do not blindly re-run; investigate or change approach.

The original output follows. The result has isError: true. Warnings go to the agent at the start of the next turn. While Watchdog watches items, the status bar shows watchdog: N.

Debug log

For action-path testing, UNIPI_WATCHDOG_FORCE_ACT=1 forces an act decision at a due check; normal decision prompting and thresholds are otherwise unchanged. Do not enable this in normal sessions.

Set UNIPI_DEBUG_WATCHDOG=1 to write a log to ~/.unipi/logs/watchdog.log. Each check writes one line with the status, the confidence and the streak.

See also