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

agent-wrapper-sdk

v0.1.0

Published

TypeScript wrapper around @anthropic-ai/claude-agent-sdk with progressive disclosure API

Readme

agent-wrapper-sdk

A TypeScript wrapper around @anthropic-ai/claude-agent-sdk that provides a progressive disclosure API — start with a one-liner, scale to full expert control.

import { agent } from "agent-wrapper-sdk";

const result = await agent("Review this codebase for security issues");

if (result.ok) {
  console.log(result.result);
}

Why?

The official claude-agent-sdk is powerful but low-level. This wrapper adds:

  • Progressive disclosure — 4 levels from zero-config to full control
  • Fluent builderAgent.builder().model("opus").tools([...]).run("prompt")
  • Result pattern — typed { ok: true, result } | { ok: false, error }, never throws
  • Tool tiers — classify tools as observe / confirm / dangerous
  • Hook middleware — composable HookChain with presets for logging, security, audit
  • Skill system — multi-format parser (Claude Code, Cursor, Amp, Codex, YAML, JSON, Markdown, Raw)
  • Session management — create, resume, fork conversations via SessionHandle
  • Subagent factory — scoped child agents with capability restrictions
  • Store interface — persist sessions and events (in-memory or file-based)
  • 100% SDK coverage — every feature accessible, with escape hatches to raw SDK

Installation

# Bun (recommended)
bun add agent-wrapper-sdk @anthropic-ai/claude-agent-sdk

# npm
npm install agent-wrapper-sdk @anthropic-ai/claude-agent-sdk

# pnpm
pnpm add agent-wrapper-sdk @anthropic-ai/claude-agent-sdk

@anthropic-ai/claude-agent-sdk is a peer dependency — you must install it alongside this package.

Set your API key:

export ANTHROPIC_API_KEY=sk-ant-...
# Or use OAuth token:
export CLAUDE_CODE_OAUTH_TOKEN=...

Quick Start

Level 1: One-liner

import { agent } from "agent-wrapper-sdk";

const result = await agent("What files are in this directory?");

if (result.ok) {
  console.log(result.result);
  console.log(`Cost: $${result.usage.cost}`);
}

Level 2: Builder Pattern

import { Agent } from "agent-wrapper-sdk";

const result = await Agent.builder()
  .model("sonnet")
  .tools(["Read", "Glob", "Grep"])
  .permission("acceptEdits")
  .maxTurns(10)
  .run("Analyze the project architecture");

Level 3: Custom Tools & Hooks

import { Agent, defineTool, logging } from "agent-wrapper-sdk";
import { z } from "zod";

const weatherTool = defineTool({
  name: "get_weather",
  description: "Get weather for a city",
  schema: z.object({ city: z.string() }),
  handler: async ({ city }) => ({
    content: [{ type: "text", text: `Weather in ${city}: 25°C, sunny` }],
  }),
  tier: "observe",
});

const result = await Agent.builder()
  .model("opus")
  .addTool(weatherTool)
  .use(logging())
  .run("What's the weather in Bangkok?");

Level 4: Full Power

import { Agent, HookChain, logging, tierBased, InMemoryStore } from "agent-wrapper-sdk";

const store = new InMemoryStore();
const hooks = new HookChain();
hooks.merge(logging());
hooks.merge(tierBased());

const agent = Agent.builder()
  .model("opus")
  .systemPrompt("You are a senior code reviewer.")
  .tools(["Read", "Write", "Edit", "Glob", "Grep"])
  .allowedTools(["Read", "Glob", "Grep"])
  .disallowedTools(["Bash"])
  .permission("acceptEdits")
  .use(hooks)
  .thinking({ type: "enabled", budgetTokens: 10000 })
  .maxTurns(30)
  .maxBudget(2.0)
  .sandbox({ network: { allowedDomains: ["api.github.com"] } })
  .fileCheckpointing(true)
  .store(store)
  .build();

// Streaming
for await (const event of agent.stream("Review all files in src/")) {
  if (event.type === "text") {
    process.stdout.write(event.text);
  }
}

Core Concepts

Result Pattern

Every execution returns an AgentResult<T> — a discriminated union that never throws:

type AgentResult<T> = AgentSuccess<T> | AgentFailure;

// AgentSuccess: ok=true, result, sessionId, usage, duration, durationApi, turns,
//               structuredOutput?, stopReason, permissionDenials, modelUsage
// AgentFailure: ok=false, error (typed), partialResult?, sessionId?, usage,
//               duration, permissionDenials

Error types are exhaustive:

type AgentError =
  | { type: "max_turns"; turns: number; limit: number; errors: string[] }
  | { type: "max_budget"; spent: number; limit: number; errors: string[] }
  | { type: "execution_error"; errors: string[] }
  | { type: "auth_failed"; message: string }
  | { type: "billing_error"; message: string }
  | { type: "rate_limit"; retryAfter?: number }
  | { type: "invalid_request"; message: string }
  | { type: "server_error"; message: string }
  | { type: "max_output_tokens"; message: string }
  | { type: "interrupted" }
  | { type: "aborted" }
  | { type: "unknown"; message: string }

Model Shortcuts

Use convenient aliases instead of full model names:

| Shortcut | Resolves To | |----------|-------------| | "opus" | claude-opus-4-6 | | "sonnet" | claude-sonnet-4-6 | | "haiku" | claude-haiku-4-5 |

Or pass any full model string directly.

Tool Tiers

Tools are classified by risk level for automatic permission management:

| Tier | Risk | Examples | Default Behavior | |------|------|----------|-----------------| | observe | Safe, read-only | Read, Glob, Grep, WebSearch | Auto-allow | | confirm | Side-effects | Write, Edit, NotebookEdit | Ask user | | dangerous | Destructive | Bash | Deny by default |

import { defineTool } from "agent-wrapper-sdk";

const myTool = defineTool({
  name: "deploy",
  description: "Deploy the app",
  tier: "dangerous",
  schema: z.object({ env: z.enum(["staging", "production"]) }),
  handler: async ({ env }) => { /* ... */ },
});

Modules

The package provides 14 importable modules via sub-path exports:

Tools — agent-wrapper-sdk/tools

Define, register, and manage custom tools with type-safe Zod schemas.

import { defineTool, ToolRegistry, DEFAULT_TOOL_TIERS } from "agent-wrapper-sdk/tools";

const registry = new ToolRegistry();
registry.register(myTool);
console.log(registry.names()); // ["my-tool"]
console.log(registry.size);    // 1
console.log(registry.has("my-tool")); // true

Events — agent-wrapper-sdk/events

25+ typed events with monotonic sequence envelopes.

import { TypedEventBus, EnvelopeFactory } from "agent-wrapper-sdk/events";

const bus = new TypedEventBus();
bus.on("text", (event) => process.stdout.write(event.text));
bus.on("tool_start", (event) => console.log(`Tool: ${event.toolName}`));
bus.on("done", (event) => console.log(`Done: ${event.totalTurns} turns`));
bus.once("error", (event) => console.error(event.error));
console.log(bus.listenerCount("text")); // 1
bus.clear();

const envelope = new EnvelopeFactory("session-id");
const env = envelope.next(); // { id, seq, timestamp, sessionId }

Event types: text, text_delta, thinking, thinking_delta, tool_start, tool_end, tool_progress, tool_input_delta, tool_use_summary, turn_complete, done, error, session_init, status, auth_status, compacted, files_persisted, task_started, task_progress, task_completed, hook_started, hook_progress, hook_response, rate_limit, prompt_suggestion, raw

Hooks — agent-wrapper-sdk/hooks

Middleware chain for intercepting 18 agent lifecycle events.

import { HookChain, logging, tierBased, auditLog, allowAll } from "agent-wrapper-sdk/hooks";

const hooks = new HookChain();
hooks.merge(logging());    // Console log all tool usage
hooks.merge(tierBased());  // Allow/deny based on tool tiers

// Custom hook handler
hooks.add("PreToolUse", async (input) => {
  console.log(`Tool: ${input.toolName}`);
  return { decision: "allow" };
});

// Use with builder
Agent.builder().use(hooks).build();

Hook events: PreToolUse, PostToolUse, PostToolUseFailure, Notification, UserPromptSubmit, SessionStart, SessionEnd, Stop, SubagentStart, SubagentStop, PreCompact, PermissionRequest, Setup, TeammateIdle, TaskCompleted, ConfigChange, WorktreeCreate, WorktreeRemove

Built-in presets:

  • logging() — Console log all tool usage (Pre+PostToolUse)
  • tierBased() — Route Bash to confirm tier
  • allowAll() — Bypass all permission checks
  • auditLog(path) — Write tool usage audit trail to JSONL file

Permissions — agent-wrapper-sdk/permissions

Fine-grained tool access control.

import { TierPolicy, PermissionManager } from "agent-wrapper-sdk/permissions";

// TierPolicy presets
const policy = TierPolicy.default();    // observe=allow, confirm=ask, dangerous=deny
const lax = TierPolicy.permissive();    // everything allowed
const tight = TierPolicy.strict();      // only observe allowed

// PermissionManager with block/allow sets
const manager = new PermissionManager({
  mode: "default",
  allowedTools: new Set(["Read", "Glob", "Grep"]),
  blockedTools: new Set(["Bash"]),
});

manager.check("Read");  // → "allow"
manager.check("Bash");  // → "deny" (blocked has priority)
manager.check("Write"); // → "ask" (falls through to tier policy)

Sessions — agent-wrapper-sdk/sessions

Multi-turn conversations with SessionHandle.

import { Agent, SessionHandle } from "agent-wrapper-sdk";

const agent = Agent.builder()
  .model("sonnet")
  .permission("acceptEdits")
  .maxTurns(5)
  .build();

const handle = new SessionHandle(agent);
await handle.run("Analyze this codebase");
await handle.continue("Now refactor the auth module");
await handle.continue("Add tests for the changes");

console.log(handle.sessionId); // UUID from first run

Skills — agent-wrapper-sdk/skills

Load and parse skill definitions from 8 different formats.

import { SkillParser, SkillLoader, codingStandards, testing, securityReview } from "agent-wrapper-sdk/skills";

// Parse any format — auto-detected
const skill = SkillParser.parse("# TypeScript Expert\nSpecializes in TS.\n## Rules\n...");
const jsonSkill = SkillParser.parse('{"name":"test","instructions":"..."}');
const detected = SkillParser.detectFormat(content); // → "json" | "yaml" | "claude-code" | ...

// Load from filesystem
const loaded = await SkillLoader.fromDir("./skills/deploy");
const all = await SkillLoader.discover("./skills"); // All subdirs

// Built-in presets
const coding = codingStandards();  // TypeScript best practices
const tests = testing();           // Testing guidelines
const security = securityReview(); // Security checklist

Supported formats: Claude Code (# headings), Cursor (.cursorrules), Amp, Codex, YAML, Markdown (with frontmatter), JSON, Raw text

Subagents — agent-wrapper-sdk/subagents

Create scoped child agents with capability restrictions.

import { SubagentFactory, explorer, reviewer, coder, researcher } from "agent-wrapper-sdk/subagents";

// Factory (instance methods)
const factory = new SubagentFactory();
const readOnly = factory.readOnly({ description: "Reader", prompt: "Read code", model: "haiku" });
const full = factory.fullAccess({ description: "Writer", prompt: "Write code", model: "sonnet" });
const scoped = factory.scoped({
  description: "Scoped worker",
  prompt: "Work in scope",
  model: "haiku",
  tools: ["Read", "Grep"],
  disallowedTools: ["Bash"],
});

// Presets — ready-to-use configs
const exp = explorer();   // Fast, read-only exploration
const rev = reviewer();   // Code review specialist
const cod = coder();      // Full write access
const res = researcher(); // Research specialist

// Use with builder
Agent.builder()
  .subagent("explorer", explorer())
  .subagent("reviewer", reviewer())
  .build();

Sandbox — agent-wrapper-sdk/sandbox

Configure network and filesystem restrictions.

import { sandboxStrict, sandboxPermissive, sandboxNetworkOnly } from "agent-wrapper-sdk";

const s = sandboxStrict();                         // No bash, no unsandboxed, managed network only
const p = sandboxPermissive();                     // Full access, all allowed
const n = sandboxNetworkOnly(["api.github.com"]);  // Only specific domains

// Full custom config
const custom = {
  enabled: true,
  autoAllowBash: false,
  network: {
    allowedDomains: ["api.github.com"],
    allowManagedDomainsOnly: false,
    allowLocalBinding: true,
  },
  filesystem: {
    allowWrite: ["/tmp"],
    denyWrite: ["/etc"],
    denyRead: ["/root/.ssh"],
  },
};

MCP — agent-wrapper-sdk/mcp

Manage Model Context Protocol servers — 5 transport types supported.

Agent.builder()
  .mcp("fs", { command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "."] })  // stdio
  .mcp("api", { type: "sse", url: "http://localhost:3001/sse" })           // SSE
  .mcp("http", { type: "http", url: "http://localhost:3002/mcp" })         // HTTP streamable
  .mcp("proxy", { type: "claude_ai_proxy" })                               // Claude.ai proxy
  .build();

// Runtime control
await agent.reconnectMcp("fs");
await agent.toggleMcp("api", false);
await agent.setMcpServers({ /* new config */ });
const status = await agent.mcpStatus();

Output — agent-wrapper-sdk/output

Get structured, typed responses via Zod schemas or raw JSON Schema.

import { Agent, resolveOutputFormat } from "agent-wrapper-sdk";
import { z } from "zod";

// Zod schema (auto-converted to JSON Schema)
const schema = z.object({ summary: z.string(), score: z.number() });

const result = await Agent.builder()
  .model("sonnet")
  .outputFormat(schema)  // Accepts Zod directly
  .run("Analyze code quality");

if (result.ok && result.structuredOutput) {
  const data = result.structuredOutput as z.infer<typeof schema>;
  console.log(data.summary, data.score);
}

Stores — agent-wrapper-sdk/stores

Persist sessions and events.

import { InMemoryStore, FileStore } from "agent-wrapper-sdk/stores";

const mem = new InMemoryStore();  // Ephemeral (testing)
const file = new FileStore("/path/to/data");  // JSON + JSONL persistence

// AgentStore interface: saveSession, loadSession, listSessions, deleteSession,
//                       appendEvent, getEvents
Agent.builder().store(file).build();

Presets — agent-wrapper-sdk/presets

Pre-configured agents for common tasks:

import { codeReviewer, researcher, fileProcessor, devops } from "agent-wrapper-sdk/presets";

const review = await codeReviewer("Review src/ for security issues");

Builder Reference

The AgentBuilder provides 45+ methods. See the full reference above and CLAUDE.md for details.

| Category | Methods | |----------|---------| | Core | model, fallbackModel, cwd, systemPrompt, systemPromptPreset | | Tools | tools, toolPreset, tool, addTool, toolTier, allowedTools, disallowedTools | | Permissions | permission, canUseTool, permissionPromptTool, dangerouslySkipPermissions | | Thinking | thinking, effort | | Limits | maxTurns, maxBudget | | Hooks | hook, use | | Subagents | subagent, mainAgent | | MCP | mcp, strictMcpConfig | | Skills | skill, skillInline | | Sessions | sessionId, persistSession | | Files | fileCheckpointing | | Sandbox | sandbox | | Output | outputFormat | | Store | store | | Plugins | plugin | | Runtime | executable, executableArgs, cliPath, spawnProcess, abortController, extraArgs | | Debug | debug, debugFile, onStderr | | Options | promptSuggestions, includePartialMessages, settingSources, additionalDirectories, env, betas | | Execute | build, run, stream |

Agent Methods

// Execution
agent.run<T>(prompt)                           // → Promise<AgentResult<T>>
agent.stream(prompt)                           // → AsyncGenerator<AgentEvent>
agent.step(prompt)                             // → Promise<TurnOutcome>

// Session
agent.continue<T>(prompt)                      // Continue current session
agent.resume<T>(sessionId, prompt)             // Resume a past session
agent.fork<T>(sessionId, prompt)               // Fork from a session
agent.resumeAt<T>(sessionId, messageId, prompt)

// Runtime control
agent.interrupt()                              // Stop execution
agent.close()                                  // Clean up
agent.setPermissionMode(mode)                  // Change permissions
agent.setModel(model)                          // Change model
agent.stopTask(taskId)                         // Stop a task

// Introspection
agent.skills()                                 // → SkillInfo[]
agent.models()                                 // Available models
agent.mcpStatus()                              // MCP server status
agent.accountInfo()                            // Account info

// File management
agent.rewindFiles(messageId, opts?)            // Revert file changes

// MCP management
agent.reconnectMcp(name)
agent.toggleMcp(name, enabled)
agent.setMcpServers(servers)

// Escape hatches
agent.toSdkOptions()                           // Raw SDK Options
agent.getQueryInstance()                        // Raw SDK Query

Requirements

  • Node.js >= 18.0.0 or Bun >= 1.0.0
  • TypeScript >= 5.7.0 (for development)
  • @anthropic-ai/claude-agent-sdk >= 0.2.0 (peer dependency)
  • ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN environment variable

Contributing

See CLAUDE.md for detailed development guidelines, architecture, and coding standards.

git clone https://github.com/piyanggoon/agent-wrapper-sdk.git
cd agent-wrapper-sdk
bun install && bun test  # 106+ tests

License

MIT

Credits

Built by @piyanggoon. Wraps @anthropic-ai/claude-agent-sdk by Anthropic.