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

@sinm/kai-embed-sdk

v0.2.1

Published

Host-page SDK for KAi embed mode. Zero-dependency, framework-agnostic.

Readme

KAi Embed SDK

Host-page SDK for KAi embed mode. Zero-dependency, framework-agnostic.

Quick Start

Floating mode (default)

SDK creates a floating button at bottom-right and an overlay drawer.

import { createKaiEmbedHost } from '@sinm/kai-embed-sdk';

const kai = createKaiEmbedHost({
  // Optional: pre-fill the address bar
  src: 'https://your-kai-server/?embed=true',

  host: {
    name: 'My App',
    instructions: 'Read the page before making changes.',
  },
});

If src is omitted, the user inputs the KAi server address in the address bar shown in the drawer. The address is persisted to localStorage by default.

Custom trigger

Use your own button to toggle the drawer:

const kai = createKaiEmbedHost({
  trigger: document.querySelector('#my-kai-button'),
  src: 'https://your-kai-server/?embed=true',
});

Inline mode (embed in your layout)

Mount the drawer inside a container element — no floating overlay:

const kai = createKaiEmbedHost({
  container: document.querySelector('#kai-slot'),
  src: 'https://your-kai-server/?embed=true',
});

Register Custom Commands

kai.registerCommand({
  command: 'read_issue',
  description: 'Read current issue details',
  whenToUse: 'Use when the user asks about the current issue',
  sideEffects: 'reads_page_state',
  parameters: {
    type: 'object',
    properties: {
      issueId: { type: 'string' },
    },
  },
  handler: async ({ issueId }) => {
    const res = await fetch(`/api/issues/${issueId}`);
    return res.json();
  },
});

Built-in Page Commands

Only page.snapshot is enabled by default. Mutating/dangerous commands are locked and must be explicitly enabled:

// Enable specific commands
createKaiEmbedHost({ container, pageCommands: { 'page.fill': true, 'page.click': true } });

// Disable all built-in commands (including snapshot)
createKaiEmbedHost({ container, pageCommands: false });

| Command | Implementation | Default | |---------|---------------|---------| | page.snapshot | querySelector(selector ?? 'body').innerHTML | enabled | | page.click | HTMLElement.click() | locked | | page.fill | Set form field value + dispatch input/change | locked | | page.evaluate | Evaluate JS expression in host page | locked | | page.apiRequest | fetch() from host page context (carries cookies) | locked |

Locked commands are advertised in capabilities with status: 'locked' and return permission_denied if called.

Custom Fetch (Dynamic Auth)

page.apiRequest uses the global fetch by default, which sends requests with the host page's cookies — allowing the agent to act as the authenticated user.

For dynamic token injection or custom request handling, pass a fetchFn:

const kai = createKaiEmbedHost({
  container,
  pageCommands: { 'page.apiRequest': true },
  fetchFn: async (input, init) => {
    const token = getAuthToken(); // your dynamic token logic
    const headers = new Headers(init?.headers);
    headers.set('Authorization', `Bearer ${token}`);
    return fetch(input, { ...init, headers });
  },
});

API

createKaiEmbedHost(options)KaiEmbedHost

| Option | Type | Description | |--------|------|-------------| | container | HTMLElement | Mount inline inside this element (no overlay/FAB) | | trigger | HTMLElement | Custom trigger button (floating mode only, replaces FAB) | | src | string | Default KAi server URL (user can override in address bar) | | hostId | string | Stable host identity for multi-host routing | | host | HostManifest | Name, description, instructions for the agent | | context | HostContext | Initial page context (url, title, selection, meta) | | pageCommands | PageCommandOptions | Built-in command config; snapshot enabled, others locked | | fetchFn | typeof fetch | Custom fetch for page.apiRequest (auth tokens, interceptors) | | title | string | Drawer header title (default: "KAi") | | persistAddress | boolean | Persist user-entered address to localStorage (default: true) | | onError | (error) => void | Error callback for command handler failures |

Methods

| Method | Description | |--------|-------------| | registerCommand(options) | Register a custom command; returns unregister function | | unregisterCommand(name) | Remove a command by name | | listCommands() | List all registered commands | | updateContext(ctx) | Push updated page context | | updateManifest(manifest) | Update host capability guidance | | announceCapabilities() | Re-send capability declaration | | open() / close() / toggle() | Control drawer visibility (no-op in inline mode) | | isOpen() | Check if drawer is open | | destroy() | Clean up DOM, listeners, and state |

Exported Utilities

| Function | Description | |----------|-------------| | isValidKaiUrl(url) | Check if URL is a valid KAi embed URL (has ?embed=true) | | ensureEmbedParam(url) | Append ?embed=true to URL if missing |

Security

  • Origin is derived from the iframe URL — no manual targetOrigin needed
  • Messages are validated: event.source === iframe.contentWindow && event.origin === iframeOrigin
  • Commands are looked up by name — no eval of raw input
  • page.snapshot returns raw DOM HTML; it is not a privacy filter
  • page.evaluate executes arbitrary JS in the host page context — only enable when you trust the KAi agent
  • page.apiRequest sends fetch with the host page's cookies by default — use fetchFn to customize auth behavior