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

@mohaa24/agent-iframe-sdk

v1.4.0

Published

SDK for client apps embedding the Seer agent in an iframe: postMessage protocol, app context, and cross-app form routing/handoff.

Readme

Agent Iframe SDK (Seer SDK)

SDK for client apps that embed the agent (Seer) in an iframe. Provides a SeerSDK class that handles postMessage listening, app context passing, and cross-app form handoff via common localStorage (pending actions with 30s expiry).

Integration guide

For full architecture, message protocol, form routing/prefill flow, and onboarding steps for new client apps, see:

  • ./INTEGRATION_GUIDE.md

Build

From repo root:

yarn build:sdk

Or from this folder:

yarn build

Export for client app

From repo root, pack the SDK so the client app can install from the tarball:

yarn build:sdk && cd sdk && yarn pack

In your client app, install from the SDK repo tarball (not a copy stored in the client repo, or you may get a 404 for agent-messaging-types):

yarn add '/path/to/mp-partners-agent-web-1/sdk/package.tgz'

Or copy the new package.tgz from the SDK repo into your client repo, then add it. If you see a 404 for @mp-partners-agent-web/agent-messaging-types, the tarball you're adding is an old one; use the freshly packed tarball from the SDK repo.

Recommended: SeerSDK class

Use the SeerSDK class so the SDK owns the listener, app context, and cross-app handoff. You only pass app name, onFormUpdate, and optionally the iframe ref. App config is shipped inside the SDK. When the SDK finds a pending action on init, it sends window.parent.postMessage({ type: 'toggleAIChat', show: true }, '*') so the parent/host can show the Seer iframe.

'use client';

import { useEffect, useRef, useState } from 'react';
import { SeerSDK } from '@mp-partners-agent-web/agent-iframe-sdk';

export default function Layout({ children }) {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const sdkRef = useRef<SeerSDK | null>(null);
  const [showAIChat, setShowAIChat] = useState(false);

  useEffect(() => {
    const sdk = new SeerSDK({
      appName: 'mp-partner-identity-web',
      onFormUpdate: (formName, formData) => {
        // Handle form in this app: e.g. router.push(...), setFormValues(formData)
      },
      targetOrigin: '*',
    });
    sdkRef.current = sdk;
    sdk.init();
    return () => {
      sdk.destroy();
      sdkRef.current = null;
    };
  }, []);

  useEffect(() => {
    if (iframeRef.current) sdkRef.current?.setIframe(iframeRef.current);
  }, [showAIChat]);

  // Listen for toggleAIChat from SDK (pending action) or from agent iframe
  useEffect(() => {
    const handler = (event: MessageEvent) => {
      if (event.data?.type === 'toggleAIChat' && typeof event.data?.show === 'boolean') {
        setShowAIChat(event.data.show);
      }
    };
    window.addEventListener('message', handler);
    return () => window.removeEventListener('message', handler);
  }, []);

  return (
    <>
      {showAIChat && (
        <iframe ref={iframeRef} src="https://your-agent-url" title="Agent" />
      )}
      {children}
    </>
  );
}

toggleAIChat

The SDK sends { type: 'toggleAIChat', show: true } to window.parent when it finds a pending action on init (so the parent can open the Seer iframe). The agent iframe can also send the same message to show/hide the chat. Your parent/client app should listen for this and toggle iframe visibility. Example:

useEffect(() => {
  const handler = (event: MessageEvent) => {
    if (event.data?.type === 'toggleAIChat' && typeof event.data?.show === 'boolean') {
      setShowAIChat(event.data.show);
    }
  };
  window.addEventListener('message', handler);
  return () => window.removeEventListener('message', handler);
}, []);

Pending actions and 30s expiry

  • When a form belongs to another app, the SDK writes a pending action to common localStorage and redirects to that app. That app’s SDK on init reads the pending action; if it’s not older than 30 seconds, it sends window.parent.postMessage({ type: 'toggleAIChat', show: true }, '*') (so the parent can show the iframe), then runs the handler (e.g. onFormUpdate) and clears storage. Entries older than 30s are ignored and cleared.
  • Pending items are stored as generic actions (e.g. form_update today; more action types can be added later).

Low-level API (optional)

If you prefer to wire things yourself:

  • createAgentIframeListener(options) — returns an unsubscribe function. Options: targetOrigin, onFormUpdate, onRouting.
  • sendAppContext(iframe, appName, targetOrigin?) — posts app_context to the iframe.

You can also import SEER_PENDING_ACTION_STORAGE_KEY and TPendingAction / TPendingActionPayloadFormUpdate if you need to read or extend pending actions.

Message types

  • Agent → Client: { action: 'form_update', payload: { formName, formData } } or { action: 'routing', payload: { app, page, view? } }
  • Client → Agent: { type: 'app_context', payload: { appName } }
  • Agent → Client (toggle): { type: 'toggleAIChat', show: boolean } — implement listener in your app as above.

Types are exported from the SDK (TAgentToClientMessage, TClientToAgentMessage, TFormName, TSeerSDKConfig, etc.).