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

@frockbot/plugin-web

v0.5.0

Published

The Web Package. It contributes one runtime Contribution (`./agent`) carrying one tool, **`web_fetch`**, and one provider-neutral contract (`./contract`) that a search provider Package implements.

Readme

@frockbot/plugin-web

The Web Package. It contributes one runtime Contribution (./agent) carrying one tool, web_fetch, and one provider-neutral contract (./contract) that a search provider Package implements.

Row 47 of the parity register (docs/research/grokbot-computer.md) names web search, web fetch and image generation as first-class tools, but cites a section that is not in the register: no input schema, bound, or error shape was ever measured for any of them. Everything here is FrockBot's own contract, defined from first principles. No schema parity is claimed.

web_fetch

| | | | -------------- | ---------------------------------------------------------------------- | | Capability | web-fetch, kind tool, connectionTypes: [] | | Input | url, max_bytes ≤ 1 MiB, format: "text" \| "markdown" | | Durable result | {"url","finalUrl","status","contentType","bytes","truncated","text"} | | Refusal | isError: true with a stable reason code | | Effect class | read-only, idempotent: true | | Turn types | all four (manifest v4 admission) |

web_fetch needs no Connection: reading a public page needs no credential. The Account-wide Package enablement is the fence — the Contribution mounts nothing unless web-fetch is in the User's enabled capability set.

It is a plain outbound request, so it works while the User's Computer is hibernated and never wakes it. A page that needs a real browser is the Computer's job, not this tool's.

The outbound trust boundary

The Bot's Durable Object can reach anything workerd can reach. ./ssrf.ts is a pure classifier — a string in, a verdict out — and it runs before every hop and again on every redirect target:

  1. https: only. No http:, data:, file:, blob:, ftp:.
  2. The default port, or 443 stated explicitly.
  3. No localhost, *.localhost, *.internal, or bare label with no dot.
  4. No IP literal outside the public ranges. Literals are normalized first, so 0177.0.0.1, 2130706433, 0x7f000001, 127.1 and ::ffff:127.0.0.1 are the same refusal as 127.0.0.1. 169.254.169.254 — the cloud metadata address — is inside 169.254.0.0/16.
  5. No credentials in the URL. A fixed User-Agent and Accept; no Cookie, no Authorization, and no header the model chose.
  6. redirect: "manual", at most three hops, rules 1–5 re-run on each one.
  7. The response must declare a media type on the allow list (text/html, text/plain, text/markdown, application/json, application/xhtml+xml), and a declared length over max_bytes is refused outright; the body is then read under a streaming cap and reports truncated when it was cut short.
  8. A refusal carries a stable reason code — ssrf-blocked-private-address, web-fetch-blocked-content-type, … — and never names what a host resolved to.

Known limitation: DNS rebinding

workerd exposes no resolve-then-connect hook, so a hostname cannot be pinned to the address the request will actually reach. A name that resolves to a public address at classification time and to 127.0.0.1 at connection time defeats every rule above. Classification is therefore exact for IP literals and for the known-internal name shapes, and best-effort for everything else. Closing the gap needs a platform primitive FrockBot does not have; it is recorded here rather than papered over.

./contractWebSearchV1

The web_search tool definition, its bounds, its DTO and its decoder live here so that a provider Package contributes the tool by supplying transport alone. @frockbot/plugin-provider-ollama-cloud is the first implementation (POST {apiBaseUrl}/api/web_search); this Package holds no transport and depends on no provider.