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

@bgub/helm

v0.2.0

Published

A typed TypeScript framework for AI agents — call typed functions instead of parsing CLI stdout

Downloads

46

Readme

npm CI Codecov

A typed TypeScript framework for AI agents. Call typed functions instead of parsing CLI stdout.

Install

npm install helm

Quick start

import { createHelm, fs } from "helm";

const agent = createHelm({
  permissions: {
    "fs.read": "allow",
    "fs.write": "ask",
    "fs.remove": "deny",
  },
  // operation is a qualified name like "fs.write"; args are the call arguments
  onPermissionRequest: async (operation, args) => {
    console.log(`${operation} requested with args:`, args);
    return true; // or false to deny
  },
}).use(fs());

// Typed inputs and outputs — no string parsing
const { content } = await agent.fs.read("./package.json");
const { entries } = await agent.fs.list("./src", { glob: "*.ts" });

Why helm?

Agents today shell out and parse strings. That means no type safety, no structured errors, and no way to control what operations are allowed.

helm gives agents typed functions with structured inputs and outputs:

// Instead of this:
const output = bash("git status --porcelain");
const files = parseGitStatus(output); // hope the format doesn't change

// Agents do this:
const { staged, unstaged } = await agent.git.status();

Features

  • Typed everything. Inputs, outputs, errors. The types are the docs.
  • Builder pattern. .use() chains accumulate skills; TypeScript infers the full type at each step.
  • Permissions are first-class. Every operation has a permission level (allow, ask, deny). Policies are set per-skill or per-operation.
  • Search the registry. A single search(query) lets agents discover operations without loading the full skill set into context.
  • Extensible. Define custom skills that get types, search, and permissions for free.

Defining custom skills

import { defineSkill } from "helm";

const weather = defineSkill({
  name: "weather",
  description: "Weather forecast operations",
  operations: {
    forecast: {
      description: "Get the forecast for a city",
      signature: "(city: string) => Promise<{ temp: number; sky: string }>",
      defaultPermission: "allow",
      tags: ["weather", "read"],
      handler: async (city: string): Promise<{ temp: number; sky: string }> => {
        // call your weather API here
        return { temp: 72, sky: "sunny" };
      },
    },
  },
});

const agent = createHelm().use(weather);
const { temp, sky } = await agent.weather.forecast("Seattle");

Permissions

Resolution order (first match wins):

  1. Exact match in policy — "git.status": "allow"
  2. Wildcard match — "git.*": "ask"
  3. Operation's own default — set by the skill author
  4. Global default — defaultPermission option (defaults to "ask")
const agent = createHelm({
  permissions: {
    "fs.read": "allow",
    "fs.*": "ask",
    "dangerous.*": "deny",
  },
  defaultPermission: "ask",
  // Called when an operation's resolved permission is "ask".
  // operation: qualified name like "fs.write"
  // args: the arguments passed to the operation, e.g. ["./out.txt", "hello"]
  onPermissionRequest: async (operation, args) => {
    console.log(`${operation} requested with args:`, args);
    return true; // return false to deny
  },
});

Search

Agents can discover operations without knowing what's available upfront:

const results = agent.search("file read");
// [{
//   qualifiedName: "fs.read",
//   description: "Read a file and return its content as a string",
//   signature: "(path: string) => Promise<{ content: string }>",
//   ...
// }]

// The agent now knows exactly what to call:
const { content } = await agent.fs.read("./package.json");

Project structure

src/
  index.ts              — public API re-exports
  types.ts              — all type definitions
  create-helm.ts        — createHelm() factory
  define-skill.ts       — defineSkill() helper
  permissions.ts        — permission resolution
  search.ts             — text search over the registry
  skills/
    fs.ts               — built-in fs skill

Development

pnpm install
pnpm lint        # biome check
pnpm test        # vitest with coverage
pnpm build       # tsdown

License

MIT © bgub