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-simplewatcher

v0.2.3

Published

Pi extension that watches files/directories and injects new content into the session, used to monitor file-based inboxes for agent-to-agent communication.

Readme

simplewatcher

A small pi extension that watches files and directories and injects new content into the current session as it appears. It exists so an agent does not have to wait for the next human prompt to notice that something changed on disk.

The main way we use it: monitoring file-based inboxes used for agent-to-agent communication. A watcher can sit on an inbox directory and surface incoming message files immediately, so replies, handoffs, and watcher notifications do not sit unread until somebody remembers to run a manual inbox check.

What it does

  • File targets are tailed, log-style. Only bytes appended after the watch starts are injected, not the whole file.
  • Directory targets are watched flat, one level deep. Files already present when the watch starts are caught up once as backlog; files created afterward are treated as new arrivals.
  • Boot backlog is passive. Existing inbox files are injected as context for the next natural turn, not as one interrupting turn per stale file.
  • Re-arms do not replay. If the watch is rebuilt — for example because session_start fires again on a model change — already-seen directory files and the file tail offset are carried across the re-arm.
  • New arrivals keep their mode. A live file landing in an active watched inbox still triggers an immediate turn; passive watches only queue context.
  • Payloads are capped. Injected content is limited by SIMPLEWATCHER_MAX_BYTES so a watched file/log cannot dump an unbounded blob into the context window.

Reaction modes

Each watch target has one mode:

| Mode | Behavior | |---|---| | active | Inject and trigger an immediate turn, even while idle. Use for inboxes where a new file means “handle this now.” | | passive | Inject as queued context only. It surfaces at the next natural turn and never speaks/acts unprompted. |

Default for manual watches is passive. The bundled session-start inbox watch uses active, because incoming agent messages are meant to be seen promptly.

Commands

| Command | Effect | |---|---| | /simplewatcher | List current watches | | /simplewatcher <path> | Add/replace a passive watch | | /simplewatcher <path> --active | Add/replace an active watch | | /simplewatcher <path> --passive | Add/replace a passive watch explicitly | | /simplewatcher <path> --active --persist | Arm now and save project-locally | | /simplewatcher <path> --active --persist --global | Arm now and save globally | | /simplewatcher persisted | List persisted watches and config paths | | /simplewatcher remove <path> | Stop watching and forget persisted entries for that path |

Examples:

/simplewatcher ~/Agents/_bus/inbox/fabricant --active --persist
/simplewatcher /var/log/myapp.log --passive
/simplewatcher persisted
/simplewatcher remove ~/Agents/_bus/inbox/fabricant
/simplewatcher

Install

This repo follows the pi package layout: package.json is present and pi.extensions points at ./src, with the entrypoint at src/index.ts.

Install from npm once published:

pi install npm:pi-simplewatcher

Install from GitHub:

pi install git:github.com/studioschade/pi-simplewatcher      # global
# or
pi install git:github.com/studioschade/pi-simplewatcher -l   # project-local

Update/remove later, matching the source you installed from:

pi update npm:pi-simplewatcher
pi remove npm:pi-simplewatcher
# or, for a git install:
pi update git:github.com/studioschade/pi-simplewatcher
pi remove git:github.com/studioschade/pi-simplewatcher

For a manual source checkout, symlink the entrypoint into pi's extension auto-discovery path so the repo stays the single source of truth:

ln -s /path/to/pi-simplewatcher/src/index.ts ~/.pi/agent/extensions/simplewatcher.ts   # global
# or
ln -s /path/to/pi-simplewatcher/src/index.ts .pi/extensions/simplewatcher.ts           # project-local

To try it ad hoc without installing: pi -e /path/to/pi-simplewatcher/src/index.ts

AGENTS.md vs watcher persistence

AGENTS.md is policy, not mechanism. It is the right place for rules like “handle inbox messages when they arrive,” “don’t ack an ack,” and “ask before outward actions.” It is not a reliable way to make a filesystem watch come back every session: a new session would have to read that instruction, decide to run it, and run it correctly.

The mechanism belongs in the extension:

  • Plain /simplewatcher <path> watches last for the current session only.
  • --persist saves the watch to .pi/simplewatcher.json in the current project; add --global to save to ~/.pi/agent/simplewatcher.json instead.
  • On session_start, persisted watches are loaded global-first then project, so project config wins for the same resolved path.
  • The bundled default re-arms $HOME/Agents/_bus/inbox/<agent> on every session_start when that path exists and was not already armed by persistence.

To see what is armed now: /simplewatcher. To see what will come back next session: /simplewatcher persisted. To stop and forget a watch: /simplewatcher remove <path> — that stops the live watch and removes persisted entries for the same resolved path from both project and global config. Manual deletion is removing that object from watches[] or setting "enabled": false. The bundled inbox default is controlled by SIMPLEWATCHER_AGENT / PI_AGENT / AGENT_NAME and only arms if the resolved inbox directory exists.

Bundled default: agent inbox monitor

On session_start, the extension arms one default watch:

$HOME/Agents/_bus/inbox/<agent>   (active mode)

The agent name is resolved in this order:

  1. SIMPLEWATCHER_AGENT
  2. PI_AGENT
  3. AGENT_NAME
  4. fallback: fabricant

That fallback keeps this repo compatible with its original home while letting sibling agents use the canonical source via an env override instead of keeping a patched fork.

Environment variables

| Variable | Default | Purpose | |---|---:|---| | SIMPLEWATCHER_AGENT | fabricant fallback | Agent name used for the default $HOME/Agents/_bus/inbox/<agent> watch. | | PI_AGENT / AGENT_NAME | — | Fallback agent-name sources if SIMPLEWATCHER_AGENT is unset. | | SIMPLEWATCHER_MAX_BYTES | 32768 | Maximum injected payload bytes. Larger content is truncated with a marker. |

Use with agent comms

In our setup, agents communicate by dropping message files into a local bus inbox or by having another comms layer materialize messages there. simplewatcher is the piece that makes those files visible to a live session immediately.

Important boundary: the watcher only surfaces content. It does not grant authority. A bus/inbox message is still data, not permission to spend money, publish outward, change another agent’s territory, or bypass the receiving agent’s own guardrails.

Safety / behavior notes

  • Watch trusted paths. Active mode can wake the agent and start a turn from file content alone.
  • Large injections are truncated by SIMPLEWATCHER_MAX_BYTES; tune it rather than disabling the cap unless you really mean it.
  • Directory mode is intentionally flat and inbox-like. It is not a recursive file-sync or build watcher.
  • If a watched path disappears or errors, the extension reports a watch error instead of throwing an unhandled watcher error.
  • Empty injections are ignored: whitespace-only file content does not send a steer by itself.

Requirements

  • Node.js 22+ recommended for the standalone regression/import path.
  • pi
  • No runtime npm dependencies; only node:fs and node:path.

Development

Source of truth for this project is src/index.ts. Keep the deployed pi extension entrypoint pointed at that file (symlink preferred) when changing behavior.

Run the self-test suite:

npm test

Useful manual smoke checks:

  • Watch a temp directory in passive mode, add a file, confirm it queues without triggering a turn.
  • Watch an inbox in active mode, add a file, confirm it triggers a turn once.
  • Re-arm the same watch and confirm no backlog replay.
  • Write a file larger than SIMPLEWATCHER_MAX_BYTES and confirm the injection is truncated with a marker.

License

GNU General Public License v3.0 only — see LICENSE.

Copyright (C) 2026 the simplewatcher contributors.