R&D·11 ·SHIPPED·2026

Omnis Watchtower: a supply-chain tripwire for coding agents

A Claude Code plugin that checks every npm and PyPI install an agent tries to run, before it runs. Invented names, malware and typosquats are refused, brand-new releases are pinned, and anything in between gets a read-only subagent to investigate. The whole fleet runs on a demoscene mission control in your terminal.

Shippedsecuritysupply-chainagents
The Watchtower cracktro theme: a rainbow ring with packages flying in, copper bars across the top, a held package flashing at the edge and a rainbow scroller along the bottom.

I don't read the names of the packages my coding agents install. Nobody does. There are too many of them, they scroll past in a terminal I'm not looking at, and the agent sounds so confident about it. Which is fine, right up until it isn't.

Agents are brilliant at three particular mistakes. They invent package names that don't exist, and attackers now register exactly those names and wait (it's got a name, slopsquatting). They fall for typosquats, reqeusts for requests. And they grab a release that went up an hour ago, which is precisely the window when a hijacked release is live and nobody's noticed yet.

So Omnis Watchtower stands between the agent and the install. It's a Claude Code plugin that reads every shell command any agent (or subagent) tries to run, picks out the npm and PyPI installs, and checks each package against live data before anything is downloaded. Then one of three things happens:

  • Refused. Invented names, known malware, typosquats, dependency confusion. The agent gets the evidence and nearly always picks the right package on its own.
  • Pinned. A brand-new release of a popular package gets rewritten to the newest one that's at least 72 hours old. npm i zod quietly runs as npm i zod@4.6.5, and the agent is told why.
  • Held. Anything dodgy but not conclusive gets a Sentinel: a hidden, read-only subagent that goes off and reads the registry page, the repository and the install scripts, then rules on it. The agent carries on with other work and the verdict lands when it retries.

Why it has a cracktro

Because I grew up on 8-bit demos, and a security tool nobody opens protects nobody. The whole fleet runs as mission control in the terminal: agents orbit, packages fly in and turn green, amber or red at the ring, Sentinels fly out to scan. The default theme is a radar. The other one, at the top of this page, is a full cracktro, copper bars and a rainbow scroller included, with greetings to every agent that didn't install malware today.

The Watchtower radar theme: a phosphor-green radar with the event log on the left, fleet and intercept counts on the right, a held package and two refusals on the board.
The radar theme, mid-demo: four packages passed, one held for a Sentinel, two refused.

It's all drawn with half-block characters into a terminal pane, so it works over SSH and in any decent terminal. The rasteriser is kept separate from the scene, so a desktop renderer can slot in later without touching the rules.

Measured, not claimed

Every number here has a write-up in the repository:

  • 1,000 popular packages (the top 500 on npm, the top 500 on PyPI) scored against the live registries: 998 passed, 59 of them pinned, 0 refused, 2 held. Each of the two held had two genuine warning signs.
  • 1.06 s to decide at the 95th percentile for a package it hasn't seen before, and instant from cache.
  • 20 out of 20 live Sentinel investigations reached a verdict, in 43 to 116 seconds.
  • Zero runtime dependencies. A supply-chain tool with its own supply chain would be a bit rich.

What broke on the way

Plenty, and it's all in the changelog:

  • My first malware rule matched the word "malicious" in advisory summaries. Ordinary vulnerability advisories say things like "via a malicious website", so it refused pnpm, undici and vitest. It now only counts advisories that say the package itself is malware.
  • It ignored OSV's version ranges, so litellm's advisory for two hijacked releases condemned every version ever published. It now asks about the exact version that would install.
  • The Sentinel refused three perfectly good releases because I'd told it to block when unsure. It took me literally. It works from a rubric now: block on a concrete red flag, allow releases that continue the package's history.
  • A code review found an agent could add --registry https://anything and walk straight past the lot. Registries given on the command line are never trusted now.
The agent never reads the name. So something has to.

What it isn't

It isn't a sandbox. It decides whether an install should run, it doesn't run it in isolation, and curl | sh gets flagged rather than analysed. If you want to watch what an install actually does once it's running, that's its sister project, PoisonBox, which runs the install script in a throwaway micro-VM and records everything it touches. And for now it's npm and PyPI only.

It's free and open source. Two commands to install it in Claude Code:

/plugin marketplace add Fortitude-Group/omnis-watchtower
/plugin install omnis-watchtower@omnis-watchtower

Then /watchtower for mission control, or /watchtower demo for a scripted attack that runs offline. Go on, try and get something past it.