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

@runplane/runplane-sdk

v1.2.6

Published

Runplane SDK - Control AI agent execution before it runs. Thin wrapper over the Guard API.

Readme

@runplane/runplane-sdk

Runplane is an execution control layer for AI systems.

It ensures that no protected action executes before it is evaluated and governed.

Runplane does not execute actions.
Runplane decides whether actions are allowed to execute.

Runplane must sit in the execution path to guarantee enforcement.


Core Principle

Every protected action is intercepted before execution and must receive a decision.

shield.guard() blocks execution until Runplane returns a decision.

The SDK is a thin wrapper over the Runplane Guard API:

👉 https://runplane.ai/api/v1/guard

All decisions are made server-side in the Gateway.

The SDK forwards requests and enforces the result locally.

Runplane is gateway-first.

The Gateway is the enforcement boundary.


Architecture

AI Agent
   ↓
shield.guard()
   ↓
Runplane Gateway
   ↓
ALLOW / BLOCK / REQUIRE_APPROVAL
   ↓
Production System

Without vs With Runplane

Without Runplane:

await transferFunds(); // executes immediately

With Runplane:

await shield.guard(...); // execution enforced before running

Runplane sits between your code and execution.


Example

await shield.guard(
  "transfer_funds",
  "banking-system",
  {
    amount: 50000,
    toAccountId: "user_456"
  },
  async () => {
    return await transferFunds();
  }
);

Possible outcomes:

  • ALLOW
  • BLOCK
  • REQUIRE_APPROVAL

Decision Model

Runplane returns one of three decisions.

ALLOW

The action is permitted and executes immediately.

BLOCK

The action is prevented by policy and will not execute.

REQUIRE_APPROVAL

The action is paused until a human approves or denies it.

Policies evaluate:

  • action type
  • target system
  • runtime context
  • risk level

before execution proceeds.


SDK Behavior

The SDK enforces the decision returned by Runplane.

ALLOW

The callback executes normally.

BLOCK

The callback is not executed.

The SDK throws ShieldError with code:

BLOCKED

REQUIRE_APPROVAL

The SDK pauses execution until a human decision is made.

If approved:

  • the callback executes

If denied:

  • the SDK throws ShieldError with code:
DENIED

Important Concept

A blocked action is not a system failure.

These are valid enforcement outcomes:

  • BLOCK = policy decision
  • DENIED = human decision

Errors only represent unexpected operational failures:

  • network failures
  • timeouts
  • invalid configuration
  • infrastructure issues

Why Runplane

AI agents and automations can trigger real-world side effects:

  • transferring funds
  • deleting data
  • modifying infrastructure
  • sending messages
  • changing production systems

Runplane adds a runtime execution control layer before those actions execute.

Use it to:

  • Prevent destructive actions
  • Require human approval for risky operations
  • Enforce policies in real time
  • Add a verifiable decision layer before execution
  • Create an execution boundary around AI systems

Installation

npm install @runplane/runplane-sdk

Quick Start

ESM (Recommended)

Add this to package.json:

{
  "type": "module"
}

Then create index.js:

import { Shield } from "@runplane/runplane-sdk";

const shield = new Shield({
  baseUrl: "https://runplane.ai",
  apiKey: process.env.RUNPLANE_API_KEY,
});

async function main() {
  const result = await shield.guard(
    "transfer_funds",
    "banking-system",
    {
      amount: 1000,
      toAccountId: "user_456",
    },
    async () => {
      console.log("Executing transfer...");
      return { success: true };
    }
  );

  console.log("Result:", result);
}

main();

CommonJS

const { Shield } = require("@runplane/runplane-sdk");

const shield = new Shield({
  baseUrl: "https://runplane.ai",
  apiKey: process.env.RUNPLANE_API_KEY,
});

Get Started

Create an account and get an API key:

👉 https://runplane.ai/auth/sign-up?mode=developer

Includes free trial access and limited free usage for testing.

A valid API key is required.


Set Your API Key

macOS / Linux

export RUNPLANE_API_KEY=your_api_key_here
node index.js

Windows CMD

set RUNPLANE_API_KEY=your_api_key_here
node index.js

Windows PowerShell

$env:RUNPLANE_API_KEY="your_api_key_here"
node index.js

What Happens When You Call guard()

ALLOW

The callback executes immediately.

Expected output:

Executing transfer...
Result: { success: true }

BLOCK

The action is prevented by policy.

The callback never executes.

import { ShieldError } from "@runplane/runplane-sdk";

try {
  await shield.guard(
    "transfer_funds",
    "production",
    {},
    async () => {
      // never executes
    }
  );
} catch (err) {
  if (err instanceof ShieldError && err.code === "BLOCKED") {
    console.log("Action blocked by policy");
  }
}

REQUIRE_APPROVAL

The SDK pauses execution until a human decision is made.

Flow:

  1. Action sent to Guard API
  2. Decision = REQUIRE_APPROVAL
  3. SDK polls approval endpoint
  4. Human approves or denies
  5. Execution continues or is prevented

Where Approvals Happen

Pending approvals are reviewed in the Runplane dashboard:

👉 Approvals tab

If your script appears to be waiting, it is likely pending approval.


Outcome Codes

Runplane outcomes are surfaced through ShieldError.

Enforcement Outcomes (Expected)

| Code | Meaning | |---|---| | BLOCKED | Action prevented by policy | | DENIED | Action rejected by human |


Operational Errors (Unexpected)

| Code | Meaning | |---|---| | TIMEOUT | Approval process timed out | | NETWORK_ERROR | API or network failure | | UNKNOWN | Unexpected failure |


Fail-Closed Behavior

Default:

failMode: "closed"

Meaning:

If Runplane cannot return a decision, execution is blocked.

Examples:

  • invalid API key
  • network failure
  • approval timeout
  • unreachable Gateway

This is a safety guarantee.


Troubleshooting

Script appears to be waiting

Most likely:

  • Decision = REQUIRE_APPROVAL
  • Waiting for human approval

Check:

  • Runplane Dashboard
  • Approvals tab

invalid_key

Possible causes:

  • missing API key
  • malformed API key
  • wrong environment
  • expired key

Cannot use import statement outside a module

Your project is likely running CommonJS.

Fix one of these:

  • Add "type": "module" to package.json
  • Rename the file to .mjs
  • Use the CommonJS example with require()

API Reference

guard()

guard(actionType, target, context, fn): Promise<T>

Intercepts an action before execution.

| Parameter | Type | Description | |---|---|---| | actionType | string | Canonical action name | | target | string | Target system identifier | | context | object | Runtime context for policy evaluation | | fn | function | Callback to execute if allowed |


decide()

Request a decision without executing a callback.

const response = await shield.decide({
  actionType: "transfer_funds",
  target: "banking-api",
  context: { amount: 50000 },
});

if (response.decision === "ALLOW") {
  // proceed
}

Final Principle

Runplane must sit in the execution path to guarantee enforcement.