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

@agentvault/agentvault

v0.21.7

Published

The security infrastructure layer for AI agents -- cryptographic identity, earned trust, and Signal-grade encrypted communications natively integrated with [OpenClaw](https://openclaw.ai).

Readme

@agentvault/agentvault

The security infrastructure layer for AI agents -- cryptographic identity, earned trust, and Signal-grade encrypted communications natively integrated with OpenClaw.

Connect your agent to its owner with XChaCha20-Poly1305 encryption, Double Ratchet forward secrecy, and W3C Decentralized Identifiers (DIDs). No plaintext ever touches the server.

What's New in v0.19.0

  • Message Dedup: Prevents Double Ratchet corruption from duplicate message delivery. Messages received via both direct WebSocket forward and Redis pub/sub are now deduplicated by message ID (500-entry buffer). Applies to 1:1 messages and room messages.
  • Crash-Safe Session Activation: session.activated is now persisted to disk immediately when the first owner message arrives. Previously, a crash between activation and the next _persistState() call would leave the session in a permanently deactivated state, silently dropping all subsequent messages.
  • Room Ratchet Re-Activation: When a room ratchet is re-initialized due to desync, the session is now correctly re-activated after successful retry decrypt. Previously, re-init set activated = false with no recovery path, causing silent message loss in rooms.
  • Trust Gate Integration: Automatic trust token lifecycle management. The plugin fetches a signed JWT from AgentVault every 12 minutes (80% of 15-min TTL) and exposes getTrustHeaders() for attaching trust tokens to outbound HTTP requests. New GET /trust delivery endpoint returns the agent's current trust tier and token expiry.

Upgrade Notes

This is a recommended upgrade for all agents. The message dedup and activation fixes resolve reported issues where agents would stop responding after initial messages, particularly in rooms and A2A channels. No configuration changes required.

Installation

OpenClaw Plugin (Recommended)

openclaw plugins install @agentvault/agentvault

Then enroll your agent with an invite token from the AgentVault dashboard:

npx @agentvault/agentvault setup --token=YOUR_INVITE_TOKEN

Standalone CLI

npx @agentvault/agentvault setup --token=YOUR_INVITE_TOKEN
npx @agentvault/agentvault

The CLI will generate an Ed25519 identity keypair, enroll with the server (anchoring a did:hub identity), wait for owner approval, and establish an E2E encrypted channel.

CLI Commands

| Command | Description | |---------|-------------| | setup --token=TOKEN | Enroll a new agent with an invite token | | create --name=NAME | Create a new agent account in OpenClaw | | send --text="..." | Send a message through the gateway | | status | Check gateway connection and agent status | | skills | List loaded skills from SKILL.md files | | doctor [--fix] | Diagnose and fix LaunchAgent / gateway issues | | version | Print the installed version |

Configuration

const channel = new SecureChannel({
  // Required
  inviteToken: process.env.AGENTVAULT_INVITE_TOKEN,
  dataDir: "./agentvault-data",
  apiUrl: "https://api.agentvault.chat",

  // Optional
  agentName: "My Agent",
  agentVersion: "1.0.0",
  httpPort: 18790,           // Local HTTP port for unified delivery protocol
  enableScanning: true,      // Enable client-side policy scanning
  backupCode: "...",         // Auto-backup encrypted state to server

  // Callbacks
  onMessage: (text, metadata) => {},
  onStateChange: (state) => {},
  onA2AMessage: (msg) => {},
  onA2AChannelReady: (info) => {},
});

The persisted state also tracks:

  • agentRole -- "lead" or "peer" (synced from server, determines workspace file access)

Programmatic Usage

SecureChannel

The core class for establishing an E2E encrypted channel between your agent and its owner.

import { SecureChannel } from "@agentvault/agentvault";

const channel = new SecureChannel({
  inviteToken: process.env.AGENTVAULT_INVITE_TOKEN,
  dataDir: "./agentvault-data",
  apiUrl: "https://api.agentvault.chat",
  agentName: "My Agent",
});

channel.on("message", (text, metadata) => {
  console.log(`Owner says: ${text}`);
  console.log(`Type: ${metadata.messageType}`);
});

channel.on("ready", () => {
  console.log(`Secure channel established: did:hub:${channel.deviceId}`);
});

await channel.start();

Unified Delivery Protocol -- deliver()

All outbound messages should flow through deliver(). It routes based on explicit target and never silently falls back.

// Send to the agent owner
await channel.deliver(
  { kind: "owner" },
  { type: "text", text: "Task complete" },
);

// Send to a multi-agent room
await channel.deliver(
  { kind: "room", roomId: "room_abc123" },
  { type: "text", text: "Ready for review" },
);

// Send to another agent (A2A)
await channel.deliver(
  { kind: "a2a", hubAddress: "did:hub:other_agent" },
  { type: "text", text: "Handoff data" },
);

// Send a decision request
await channel.deliver(
  { kind: "owner" },
  {
    type: "decision_request",
    request: {
      question: "Which database?",
      options: [
        { label: "PostgreSQL", value: "postgres" },
        { label: "SQLite", value: "sqlite" },
      ],
      urgency: "medium",
    },
  },
);

Delivery targets:

  • { kind: "owner" } -- Send to the agent owner
  • { kind: "room", roomId: "..." } -- Send to a multi-agent room
  • { kind: "a2a", hubAddress: "..." } -- Send to another agent
  • { kind: "context" } -- Resolve from last inbound room (opt-in only)

Content types: text, decision_request, decision_response, approval_request, approval_response, policy_alert, artifact_share, action_confirmation, attachment

Gateway Send Helpers

Send messages from your agent code without managing the channel directly:

import { sendToOwner, sendToRoom, sendToTarget, listTargets } from "@agentvault/agentvault";

await sendToOwner("Task complete -- 3 files processed");
await sendToRoom("room_abc123", "Ready for review");
await sendToTarget("did:hub:other_agent", "Handoff data");

const targets = await listTargets();

Policy Enforcement

The PolicyEnforcer validates skill invocations against a 5-stage pipeline:

import { PolicyEnforcer } from "@agentvault/agentvault";

const enforcer = new PolicyEnforcer();

enforcer.registerSkill({
  name: "code-review",
  toolsAllowed: ["file.read"],
  toolsDenied: ["shell.exec", "network.raw"],
  modelRouting: { allowed: ["gpt-4", "claude-sonnet-4-20250514"] },
});

const result = enforcer.evaluate({
  skillName: "code-review",
  toolName: "shell.exec",
  model: "gpt-4",
});

if (!result.allowed) {
  console.log("Blocked:", result.violations);
}

const metrics = enforcer.getMetrics();

Skill Management

Define skills using SKILL.md frontmatter:

---
name: code-review
version: "1.0.0"
description: Reviews code for issues
tags: [code-review, typescript]
sla:
  p95_latency_ms: 5000
  max_error_rate: 0.05
agentVault:
  certification: certified
  integrity:
    algorithm: XChaCha20-Poly1305
    hashChain: SHA-256
  requiredPolicies: ["network: agentvault"]
  runtime:
    capabilities: [file.read, web.fetch]
    forbidden: [shell.exec]
  model:
    allowed: [gpt-4, claude-sonnet-4-20250514]
    default: claude-sonnet-4-20250514
---

Telemetry

The plugin auto-instruments all message operations with OTel-shaped telemetry spans. Spans feed the trust scoring engine and observability dashboard.

import { wrapSkillExecution } from "@agentvault/agentvault";

const result = await wrapSkillExecution("code-review", async () => {
  return { issues: 3 };
});

MCP Server (Embedded)

Expose your agent's skills as MCP tools:

import { AgentVaultMcpServer } from "@agentvault/agentvault";

const mcpServer = new AgentVaultMcpServer({
  skills: manifest.skills,
  channel,
  enforcer,
});

Shadow Mode

Runtime Shadow Mode lets agents observe and recommend without executing. When a shadow session is created for an agent's skill, the plugin receives the config via WebSocket and tracks it in persisted state.

Checking Shadow Status

const shadow = channel.getShadowConfig("triage_ticket");
if (shadow) {
  // Skill is in shadow/supervised mode — send recommendation instead of executing
  const recommendation = await runLLMPipeline(input);
  await channel.deliver({
    type: "shadow_recommendation",
    recommendation: {
      sessionId: shadow.sessionId,
      skillName: "triage_ticket",
      decisionClass: shadow.decisionClass,
      recommendedAction: recommendation,
      observationId: observationId, // from POST /shadow/sessions/{id}/observations
    },
  });
} else {
  // Normal execution
  await executeAction(input);
}

Shadow Events

| Event | Description | |-------|-------------| | shadow_config_sync | Full shadow config received on WS connect | | shadow_session_created | New shadow session for this agent | | shadow_session_graduated | Session autonomy level changed | | shadow_session_deleted | Shadow session removed |

Autonomy Levels

| Level | Behavior | |-------|----------| | shadow | Recommend only — never execute | | supervised | Recommend + wait for approval (future) | | autonomous | Normal execution (config removed from plugin) |

Events

The SecureChannel emits the following events:

| Event | Payload | Description | |-------|---------|-------------| | ready | -- | Channel established and encrypted | | message | (text, metadata) | Decrypted owner message | | room_message | { roomId, text, ... } | Decrypted room message | | a2a_message | A2AMessage | Agent-to-agent message | | a2a_channel_approved | { channel_id, ... } | A2A channel approved | | a2a_channel_activated | { ... } | A2A channel ready for E2E | | a2a_channel_rejected | { ... } | A2A channel request rejected | | a2a_channel_revoked | { ... } | A2A channel revoked | | hub_identity_assigned | { ... } | DID hub identity assigned | | hub_identity_role_changed | { agent_role } | Agent role changed (lead/peer) | | hub_identity_removed | { ... } | Hub identity removed | | room_joined | { roomId, name } | Joined a multi-agent room | | room_left | { roomId } | Left a room | | room_participant_added | { roomId, deviceId } | Participant joined room | | room_participant_removed | { roomId, deviceId } | Participant left room | | policy_blocked | { ... } | Message blocked by policy | | message_held | { ... } | Message held for review | | policy_rejected | { ... } | Policy rejected message | | scan_blocked | { direction, violations } | Client-side scan blocked message | | resync_requested | { conversationId, reason } | Ratchet resync needed | | resync_completed | { conversationId } | Ratchet resync completed | | state | ChannelState | Connection state change | | error | Error | Error occurred | | http-ready | port | Local HTTP server started | | webhook_registered | { ... } | Webhook registered with backend |

OpenClaw Integration

When installed as an OpenClaw plugin, AgentVault registers as the agentvault channel:

{
  "channels": {
    "agentvault": {
      "accountId": "your-agent-account-id"
    }
  }
}

The plugin hooks into OpenClaw's lifecycle:

  • Channel gateway -- routes inbound/outbound messages through the E2E encrypted channel
  • Heartbeat wake -- keeps the agent alive via OpenClaw's heartbeat system
  • Agent events -- listens for session start/end and transcript updates
  • Managed HTTP routes -- /send, /status, /targets, /action, /decision
  • MCP serving -- exposes skills as MCP tools via /mcp route

Security Architecture

AgentVault is a zero-knowledge platform. The server routes ciphertext and NEVER sees plaintext.

| Layer | Technology | |-------|-----------| | Identity | Ed25519 keypairs linked to did:hub identifiers | | Encryption | XChaCha20-Poly1305 with 192-bit nonces | | Forward Secrecy | Double Ratchet protocol + X3DH key agreement | | Group Crypto | Sender Key distribution with automatic force rekeying | | Audit | BLAKE2b hash-chained entries with W3C TraceContext | | Policy | 5-stage pipeline: Parse, Validate, Enforce, Log, Report |

Related Packages

| Package | Description | |---------|-------------| | @agentvault/sdk | SDK for third-party agent integration (API key auth + E2E) | | @agentvault/mcp-server | Standalone MCP server for any MCP-compatible host | | @agentvault/crypto | Cryptographic primitives (Double Ratchet, X3DH, XChaCha20, telemetry) | | @agentvault/verify | Lightweight agent verification SDK |

License

MIT