npm package: @runplane/runplane-sdk
Description: Runtime governance SDK for AI agent actions. Wrap sensitive operations with guard() to enforce ALLOW, BLOCK, or REQUIRE_APPROVAL decisions before execution.
Author: Runplane
Latest version: 1.1.3

# @runplane/runplane-sdk

Control what your AI agents are allowed to do — in real time.

Runplane sits between your AI agents and execution. Every action passes through `guard()`, which enforces a decision before your code runs.

---

## 🚀 Start in 2 Minutes

### 1. Install the SDK

```bash
npm install @runplane/runplane-sdk
```

---

### 2. Get your API key (Free 14-day trial)

👉 https://runplane.ai/

Create your account and copy your API key.

⚠️ **Important:** The SDK will not work without a valid API key.

---

### 3. Run your first protected action

```javascript
require("dotenv").config()
const { Runplane } = require("@runplane/runplane-sdk")

const runplane = new Runplane({
  apiKey: process.env.RUNPLANE_API_KEY,
})

async function main() {
  await runplane.guard(
    "transfer_funds",
    "finance-system",
    { fromAccountId: "acc_1", toAccountId: "acc_2", amount: 400 },
    async () => {
      return await executeTransfer()
    }
  )
}

main()
```

---

## 💡 What Runplane Does

Runplane gives you **real-time control over AI agent actions**.

Before any action runs, Runplane evaluates:

* Policies
* Risk
* Context

And returns a decision:

* **ALLOW** → execution continues
* **BLOCK** → action is stopped
* **REQUIRE_APPROVAL** → human approval required

---

## ⚙️ How It Works

`guard()` calls the Runplane API before executing your handler:

1. Sends action + target + context to Runplane
2. Runplane evaluates policies and risk
3. Returns a decision:

   * **ALLOW** → handler executes
   * **BLOCK** → throws `RunplaneError`
   * **REQUIRE_APPROVAL** → throws `RunplaneError` and waits for approval

---

## 📘 API Reference

### `new Runplane(config)`

```javascript
const runplane = new Runplane({
  apiKey: "your_api_key",
  baseUrl: "https://runplane.ai",
})
```

---

### `guard(action, target, context, handler)`

```javascript
const result = await runplane.guard(
  "delete_record",
  "hr_system",
  { employeeId: "emp_123" },
  async () => {
    return await deleteEmployee("emp_123")
  }
)
```

**Returns:** handler result if ALLOW
**Throws:** `RunplaneError` if BLOCK or REQUIRE_APPROVAL

---

### `decide(payload)`

```javascript
const result = await runplane.decide({
  action: "send_email",
  target: "marketing_list",
  context: { recipients: 1200 },
})

console.log(result.decision)
```

---

## 🧠 Handling Decisions

```javascript
const { Runplane, RunplaneError } = require("@runplane/runplane-sdk")

try {
  await runplane.guard("action", "target", {}, async () => {
    // your code
  })
} catch (err) {
  if (err instanceof RunplaneError) {
    if (err.code === "BLOCK") {
      console.error("Action blocked by policy")
    } else if (err.code === "REQUIRE_APPROVAL") {
      console.log("Waiting for human approval...")
      console.log("Request ID:", err.runplane.requestId)
    }
  }
}
```

---

## 📊 Decision Types

| Decision           | Behavior                     |
| ------------------ | ---------------------------- |
| `ALLOW`            | Handler executes immediately |
| `BLOCK`            | Throws `RunplaneError`       |
| `REQUIRE_APPROVAL` | Requires human approval      |

---

## ❗ Error Object

```javascript
{
  message: "Runplane blocked this action",
  code: "BLOCK",
  runplane: {
    decision: "BLOCK",
    reason: "Policy violation",
    requestId: "req_abc123",
    riskScore: 91,
  }
}
```

---

## ⚠️ Requirements

* Node.js 18+
* Runplane API key 👉 https://runplane.ai/
* Internet access

---

## 💬 Feedback

Got stuck? Something unclear? Want to suggest improvements?

👉 https://runplane.ai/

---

## License

MIT