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

sgiant-ai-agent-bridge

v1.4.2

Published

Make any web page AI-operable over postMessage — same-origin or cross-origin. Framework-agnostic, zero dependencies.

Readme

sgiant-ai-agent-bridge

Make any web page AI-operable: let an assistant see the controls on a page and drive them — highlight, scroll, focus, fill, click — while the user watches each action happen.

Zero dependencies. No React, no framework, ~1,570 lines of TypeScript across two entry points. Works same-origin or cross-origin.

npm install sgiant-ai-agent-bridge

The idea

An AI that can only talk is stuck describing where a button is. This library lets it press the button — without ever handing the model a CSS selector.

There are two halves, and they talk over postMessage:

| half | runs in | job | | --------------------------- | ---------------------- | -------------------------------------------- | | mountAiAgent() | the page being driven | publish what's operable, execute the actions | | createFrameTransport(el) | the parent embedding it | read the catalog, send actions |

Mark what the AI may touch

One attribute. That's the whole authoring surface:

<button data-ai-target="save-profile">Save</button>
<input data-ai-target="hotel-name" aria-label="Hotel name" />

Anything without data-ai-target is invisible to the bridge and cannot be acted on.

In the page

import { mountAiAgent } from "sgiant-ai-agent-bridge";

mountAiAgent();

That's it. It re-scans as the DOM changes and republishes the catalog.

It is a no-op when the page is not framed — it returns an inert handle and installs nothing — so it is safe to call unconditionally at startup rather than guarding it behind "am I embedded?".

By default only the page's own origin may drive it. To let an external embedder in, say so explicitly:

mountAiAgent({ allowedOrigins: ["https://app.example.com"] });

In the parent

import { createFrameTransport } from "sgiant-ai-agent-bridge";

const bridge = createFrameTransport(iframeEl, {
  targetOrigin: "https://site.example.com",
  onTargets: (targets) => console.log("operable now:", targets),
});

await bridge.act("fill",  { target: "hotel-name", value: "Seaside Inn" });
await bridge.act("click", { target: "save-profile" });

act() resolves with { ok, message? } — the agent's own result, not a guess — so a model can be told whether what it tried actually worked.

The five actions

highlight · scroll-to · focus-field · fill · click

Navigation is deliberately not one of them: the parent owns the frame's URL, so it changes the page itself rather than asking the page to move.

Security

The design assumption is that the driven page does not trust the embedder, and the embedder does not trust the page.

  • Selectors never cross the wire. A parent sends a data-ai-target id and nothing else. There is no message that can express "click the third div" — so a compromised parent, or a model that has been talked into something, cannot reach a control the page never marked.
  • Origins are allow-listed on both sides, and default to same-origin. An external embedder is opt-in, and granting it is granting page control.
  • Every message is channel- and version-tagged, so unrelated postMessage traffic is ignored rather than parsed.

Using it without an iframe

If your parent is same-origin, you can skip the postMessage hop entirely and call the DOM primitives directly — scanAiTargets(), runUiControl(), runOperateAction(), clearHighlight(). They are exported for exactly that.

Describing a surface (sgiant-ai-agent-bridge/manifest)

A second entry point, deliberately separate: a page that only wants to DESCRIBE itself has no use for the transport or the postMessage protocol, and pulling those in to read a type is how a dependency-light package stops being one.

import { generateManifest, verifySurface, canAct, hashManifest }
  from "sgiant-ai-agent-bridge/manifest";

generateManifest walks the DOM and produces the manifest a surface publishes; hashManifest gives it a stable identity; verifySurface reports drift between a published manifest and the live page; canAct answers whether a given control may be driven. sgiant-ai-widget/manifest re-exports these, so a host already loading the widget need not add this dependency.

Browsers

The published ESM carries fully-extensioned relative imports, so it loads in a browser directly from dist/index.js with no bundler and no import map. It also works as an ordinary npm dependency in Vite, Next, webpack, or esbuild.

Licence

MIT © Vedat Aydın Uğur