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

@capsule-run/cli

v0.6.5

Published

Secure WASM runtime to isolate and manage AI agent tasks

Downloads

772

Readme

capsule

A secure, durable runtime for agentic workflows

Overview

Capsule is a runtime for coordinating AI agent tasks in isolated environments. It is designed to handle untrusted code execution, long-running workflows, large-scale processing, or even multi-agent systems.

Each task runs inside its own WebAssembly sandbox, providing:

  • Isolated execution: Each task runs isolated from your host system
  • Resource limits: Set CPU, memory, and timeout limits per task
  • Automatic retries: Handle failures without manual intervention
  • Lifecycle tracking: Monitor which tasks are running, completed, or failed

This enables safe task-level execution of untrusted code within AI agent systems.

Installation

npm install -g @capsule-run/cli
npm install @capsule-run/sdk

Getting started

Create hello.ts:

import { task } from "@capsule-run/sdk";

export const main = task({
  name: "main",
  compute: "LOW",
  ram: "64MB"
}, (): string => {
  return "Hello from Capsule!";
});

Run it:

capsule run hello.ts

Use --verbose to display real-time task execution details.

Production

Running source code directly (like .ts) evaluates and compiles your file at runtime. While great for development, this compilation step adds a few seconds of latency. For use cases where sub-second latency is critical, you should build your tasks ahead of time.

# Generates an optimized hello.wasm file
capsule build hello.ts --export

# Execute the compiled artifact directly
capsule exec hello.wasm

[!NOTE] Or from your existing code:

import { run } from '@capsule-run/sdk/runner';

const result = await run({
  file: './hello.wasm', // or `hello.ts`
  args: []
});

console.log(`Task completed: ${result.result}`);

See Integrate Into an Existing Project for details.

Executing a .wasm file bypasses the compiler completely, reducing initialization time to milliseconds while using a natively optimized (.cwasm) format behind the scenes.

Integrate Into an Existing Project

The run() function lets you execute tasks programmatically from your application code, no CLI needed.

You need @capsule-run/cli in your dependencies to use the runner functions in TypeScript.

import { run } from '@capsule-run/sdk/runner';

const result = await run({
  file: './capsule.ts', // or `capsule.wasm`
  args: ['code to execute']
});

Create capsule.ts:

import { task } from "@capsule-run/sdk";

export const main = task({
  name: "main",
  compute: "LOW",
  ram: "64MB"
}, (code: string): string => {
  return eval(code);
});

How It Works

Simply use a wrapper function to define your tasks:

import { task } from "@capsule-run/sdk";

export const analyzeData = task({
  name: "analyze_data",
  compute: "MEDIUM",
  ram: "512MB",
  timeout: "30s",
  maxRetries: 1
}, (dataset: number[]): object => {
  // Your code runs safely in a Wasm sandbox
  return { processed: dataset.length, status: "complete" };
});

export const main = task({
    name: "main",
    compute: "HIGH"
}, () => {
  return analyzeData([1, 2, 3, 4, 5]);
});

The runtime requires a task named "main" as the entry point.

When you run capsule run main.ts, your code is compiled into a WebAssembly module and executed in a dedicated sandbox.

Response Format

Every task returns a structured JSON envelope containing both the result and execution metadata:

{
  "success": true,
  "result": { "processed": 5, "status": "complete" },
  "error": null,
  "execution": {
    "task_name": "data_processor",
    "duration_ms": 1523,
    "retries": 0,
    "fuel_consumed": 45000
  }
}

Response fields:

  • success — Boolean indicating whether the task completed successfully
  • result — The actual return value from your task (json, string, null on failure etc.)
  • error — Error details if the task failed ({ error_type: string, message: string })
  • execution — Performance metrics:
    • task_name — Name of the executed task
    • duration_ms — Execution time in milliseconds
    • retries — Number of retry attempts that occurred
    • fuel_consumed — CPU resources used (see Compute Levels)

Documentation

Task Configuration Options

| Parameter | Description | Type | Default | Example | |-----------|-------------|------|---------|---------| | name | Task identifier | string | required | "process_data" | | compute | CPU level: "LOW", "MEDIUM", "HIGH" | string | "MEDIUM" | "HIGH" | | ram | Memory limit | string | unlimited | "512MB", "2GB" | | timeout | Maximum execution time | string or number | unlimited | "30s", "5m", 30000 (ms) | | maxRetries | Retry attempts on failure | number | 0 | 3 | | allowedFiles | Folders accessible in the sandbox | string[] | [] | ["./data", "./output"] | | allowedHosts | Domains accessible in the sandbox | string[] | ["*"] | ["api.openai.com", "*.anthropic.com"] | | envVariables | Environment variables accessible in the sandbox | string[] | [] | ["API_KEY"] |

Compute Levels

  • LOW: Minimal allocation for lightweight tasks
  • MEDIUM: Balanced resources for typical workloads
  • HIGH: Maximum fuel for compute-intensive operations
  • CUSTOM: Specify exact fuel value (e.g., compute="1000000")

Project Configuration (Optional)

Create a capsule.toml file in your project root to set default options:

[workflow]
name = "My AI Workflow"
version = "1.0.0"
entrypoint = "src/main.ts"  # Run `capsule run` without specifying a file

[tasks]
default_compute = "MEDIUM"
default_ram = "256MB"
default_timeout = "30s"

Task-level options always override these defaults.

File Access

Tasks can read and write files within directories specified in allowedFiles. Any attempt to access files outside these directories is not possible.

Common Node.js built-ins are available. Use the standard fs module:

import { task } from "@capsule-run/sdk";
import fs from "fs/promises";

export const restrictedWriter = task({
    name: "restricted_writer",
    allowedFiles: ["./output"]
}, async () => {
    await fs.writeFile("./output/result.txt", "result");
});

export const main = task({ name: "main", allowedFiles: ["./data"] }, async () => {
    await restrictedWriter();
    return await fs.readFile("./data/input.txt", "utf8");
});

Network Access

Tasks can make HTTP requests to domains specified in allowedHosts. By default, all outbound requests are allowed ([\"*\"]). Restrict access by providing a whitelist of domains.

Wildcards are supported: *.example.com matches all subdomains of example.com.

import { task } from "@capsule-run/sdk";

export const main = task({
    name: "main",
    allowedHosts: ["api.openai.com", "*.anthropic.com"]
}, async () => {
    const response = await fetch("https://api.openai.com/v1/models");
    return response.json();
});

Environment Variables

Tasks can access environment variables to read configuration, API keys, or other runtime settings. Use the standard process.env:

import { task } from "@capsule-run/sdk";

export const main = task({
    name: "main",
    envVariables: ["API_KEY"]
}, () => {
    const apiKey = process.env.API_KEY;
    return { apiKeySet: apiKey !== undefined };
});

Compatibility

Supported:

  • npm packages and ES modules
  • Common Node.js built-ins. If you have any trouble with a built-in, do not hesitate to open an issue.

⚠️ Not supported (inside the sandbox):

  • Native Node.js addons (C++ bindings)

These limitations only apply to the task file executed in the sandbox. Your host code using run() runs in a normal Node.js environment with no restrictions. (see Integrate Into an Existing Project)

Links