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

@getshield/js

v0.5.0

Published

Official Shield SDK for JavaScript/TypeScript

Readme

Shield JS SDK

Official Shield SDK for JavaScript/TypeScript. Provides a typed client for the Shield tamper-proof audit trail API.

Installation

npm install @getshield/[email protected]

Quick Start

API Key Only

import { ShieldClient } from "@getshield/js";

const shield = new ShieldClient("sk_live_your_api_key");

With HMAC Request Signing

import { ShieldClient } from "@getshield/js";

const shield = new ShieldClient("sk_live_your_api_key", {
  hmacSecret: "your_hmac_secret",
});

Usage

Create a Session

const session = await shield.sessions.create({
  title: "Vehicle Purchase ??2026 Honda Civic",
});

console.log(session.id); // "ses_abc123..."

Create an Event

import { ShieldEventType } from "@getshield/js";

const event = await shield.events.create({
  session_id: session.id,
  event_type: ShieldEventType.PartyJoined,
  actor: "[email protected]",
  data: {
    role: "buyer",
    name: "Jane Doe",
  },
});

Record AI Agent Evidence

import { createHash } from "crypto";
import { ShieldEventType } from "@getshield/js";

// Hash content locally — never send raw prompts or outputs to Shield
const promptHash = createHash("sha256").update(myPrompt).digest("hex");
const outputHash = createHash("sha256").update(agentOutput).digest("hex");

const event = await shield.agent.logAction(session.id, {
  event_type: ShieldEventType.ContentSubmitted,
  agent_id: "agt-unique-identifier",
  agent_name: "gpt-4o",
  agent_provider: "OpenAI",
  principal_user_id: "[email protected]",
  prompt_hash: promptHash,   // bare 64-char lowercase hex
  output_hash: outputHash,
});

At least one of agent_id or agent_name is required. Hash fields (prompt_hash, input_hash, output_hash) must be bare 64-character lowercase SHA-256 hex digests (no prefix). Providing raw content or an incorrectly formatted hash throws a ShieldError.

Record Agent Action Evidence

For browser-automation and tool-call agents, use the typed action helpers. These record what the agent did — Shield does not judge whether the decision was correct.

import { createHash } from "crypto";
import { AgentActionEventType, ActionEvidenceParams } from "@getshield/js";

// Hash screenshots/DOM locally — never upload raw images or HTML
const screenshotBeforeHash = createHash("sha256").update(screenshotBytes).digest("hex");
const screenshotAfterHash  = createHash("sha256").update(afterBytes).digest("hex");

// Record a click
await shield.agent.actionClicked(session.id, {
  agent_id: "agt-browser-001",
  principal_user_id: "[email protected]",
  target_url: "https://app.example.com/checkout",
  element_selector: "#confirm-order",
  element_text: "Confirm Order",
  screenshot_before_hash: screenshotBeforeHash, // bare 64-char hex — do not include the sha256 prefix plus colon
  screenshot_after_hash: screenshotAfterHash,
  risk_level: "medium",
});

// Record a tool call
await shield.agent.actionToolCalled(session.id, {
  agent_id: "agt-001",
  tool_call_id: "call_abc123",
  action_type: "search_web",
  result: "success",
});

// Record a confirmed payment (amount + currency + approval required)
await shield.agent.actionPaymentConfirmed(session.id, {
  agent_id: "agt-001",
  principal_user_id: "[email protected]",
  amount: 299.99,
  currency: "USD",
  human_approval_event_id: "evt-approval-abc",  // or use authority_scope
});

Action helpers available:

| Method | Event type | |---|---| | agent.actionNavigated | shield.agent.action.navigated | | agent.actionClicked | shield.agent.action.clicked | | agent.actionSubmitted | shield.agent.action.submitted | | agent.actionToolCalled | shield.agent.action.tool_called | | agent.actionPaymentConfirmed | shield.agent.action.payment_confirmed |

All helpers accept AgentEventParams & ActionEvidenceParams. The SDK validates that screenshot_before_hash, screenshot_after_hash, dom_before_hash, and dom_after_hash are bare 64-character lowercase SHA-256 hex digests. Values beginning with the sha256 prefix plus colon are rejected client-side before any request is made.

Payment actions (actionPaymentConfirmed, and shield.agent.action.payment_initiated via logAction) additionally require amount, currency, and either human_approval_event_id or an authority_scope array containing a payment permission string ("payment" or "pay:"). Validation is enforced server-side; the SDK passes all fields through.

AgentActionEventType enum — all 10 types:

AgentActionEventType.Navigated              // "shield.agent.action.navigated"
AgentActionEventType.Clicked                // "shield.agent.action.clicked"
AgentActionEventType.InputFilled            // "shield.agent.action.input_filled"
AgentActionEventType.Submitted              // "shield.agent.action.submitted"
AgentActionEventType.Confirmed              // "shield.agent.action.confirmed"
AgentActionEventType.PaymentInitiated       // "shield.agent.action.payment_initiated"
AgentActionEventType.PaymentConfirmed       // "shield.agent.action.payment_confirmed"
AgentActionEventType.ToolCalled             // "shield.agent.action.tool_called"
AgentActionEventType.HumanApprovalRequested // "shield.agent.action.human_approval_requested"
AgentActionEventType.HumanApprovalGranted   // "shield.agent.action.human_approval_granted"

Playwright Browser Adapter — Auto-log Browser Actions

For agents that control a real browser via Playwright, createShieldPlaywrightAdapter wraps each action and automatically records the corresponding shield.agent.action.* event. Raw screenshots and DOM are never sent to Shield — SHA-256 hashes are captured locally and only the digest is logged.

import { chromium } from "playwright";
import { ShieldClient, createShieldPlaywrightAdapter } from "@getshield/js";

const shield = new ShieldClient(process.env.SHIELD_API_KEY!, {
  hmacSecret: process.env.SHIELD_HMAC_SECRET!,
});

const adapter = createShieldPlaywrightAdapter({
  shield,
  sessionId: session.id,
  agentId:   "agt-browser-001",
  agentName: "playwright-agent",
  principalUserId: "[email protected]",
  // "pay:checkout" satisfies the payment authority gate
  authorityScope: ["read:checkout", "submit:order", "pay:checkout"],
});

const browser = await chromium.launch();
const page    = await browser.newPage();

// Each call records a tamper-evident evidence event with before/after hashes
await adapter.navigate(page, "https://app.example.com/checkout");
await adapter.fill(page, "#email", "[email protected]");   // raw value never sent to Shield
await adapter.click(page, "#submit-btn", { riskLevel: "medium" });
await adapter.submit(page, "#checkout-form");

// Payment gate: requires humanApprovalEventId or authority_scope with "payment"/"pay:"
await adapter.confirmPayment(page, "#pay-btn", {
  amount:    29900,   // in cents
  currency:  "USD",
  riskLevel: "high",
  // or: humanApprovalEventId: "evt-approval-xyz"
});

await browser.close();

The adapter accepts any object that satisfies the PageLike interface — no playwright package import is needed in the adapter itself. Your Playwright version is not pinned by @getshield/js.

Privacy invariant: fill() logs the selector and before/after page hashes but never the typed value. confirmPayment() enforces the payment gate before clicking — calls without humanApprovalEventId or a payment authority_scope throw a ShieldError immediately, before any browser interaction.

MCP Adapter — Auto-log Tool Calls

For agents that call MCP tools, createShieldMcpAdapter wraps each tool call and automatically records a shield.agent.action.tool_called event. Raw input and output are never sent to Shield — only SHA-256 hashes are logged.

import { ShieldClient, createShieldMcpAdapter } from "@getshield/js";

const shield = new ShieldClient(process.env.SHIELD_API_KEY!, {
  hmacSecret: process.env.SHIELD_HMAC_SECRET!,
});

const shieldMcp = createShieldMcpAdapter({
  shield,
  sessionId: session.id,
  agentId: "agt-my-agent",
  agentName: "my-mcp-agent",
  agentProvider: "Anthropic",
  principalUserId: "[email protected]",
});

// Wrap any tool call — input is hashed locally, never sent to Shield
const fileContent = await shieldMcp.recordToolCall({
  toolName: "read_file",
  toolCallId: "call_abc123",
  input: { path: "/tmp/report.pdf" },
  execute: async (input) => fs.readFile(input.path, "utf8"),
});

If the tool throws, Shield logs a result: "error" event with a sanitized error message and re-throws the original error. Shield logging failures are non-fatal by default (throwOnShieldError: false).

Shield records tamper-evident evidence of tool calls; it does not judge whether the tool result or AI decision was correct.

Evidence Artifact References

Record tamper-evident references to externally-stored evidence files (screenshots, DOM dumps, I/O traces) by passing evidence_artifacts to any action event. Shield seals the uri + sha256 into the hash chain.

Shield does not store raw bytes. Upload to your own storage, then pass the resulting URI + SHA-256 hash.

import { createHash } from "crypto";

// 1. Capture and hash the screenshot locally
const screenshotBytes: Buffer = await page.screenshot();
const sha256 = createHash("sha256").update(screenshotBytes).digest("hex");

// 2. Upload to your S3 bucket (your responsibility — Shield does not upload for you)
const uri = "s3://my-company-evidence/session-123/screenshot-before.png";
// ... your upload code ...

// 3. Record the tamper-evident reference in Shield
await shield.agent.actionClicked(session.id, {
  actor: "agt-browser-001",
  agent_id: "agt-browser-001",
  element_selector: "#confirm-order",
  evidence_artifacts: [
    {
      artifact_type:    "screenshot_before",  // required
      sha256,                                  // required — bare 64-char lowercase hex
      uri,                                     // optional
      storage_provider: "customer_s3",         // optional
      content_type:     "image/png",           // optional
      size_bytes:       screenshotBytes.length, // optional
    },
  ],
});

Allowed artifact_type: screenshot_before | screenshot_after | dom_before | dom_after | input | output | trace | receipt | other

Allowed storage_provider: customer_s3 | customer_r2 | customer_gcs | customer_azure_blob | shield_storage | external

Allowed uri schemes: http:// | https:// | s3:// | gs:// | azure:// | r2://

Each artifact's sha256 is committed to the tamper-evident hash chain. Changing the file at the URI breaks chain verification. Shield proves what was recorded — it does not download or re-verify the file itself.

Verify a Session

const result = await shield.verify.session(session.id);

console.log(result.valid);           // true
console.log(result.verified_events); // 12
console.log(result.tsa_status);      // "granted"

Export a Session

// Export as JSON
const jsonData = await shield.sessions.export(session.id, { format: "json" });

// Export as PDF (returns raw Response for streaming)
const pdfResponse = await shield.sessions.export(session.id, { format: "pdf" });

Event Types

Shield Standard Event Taxonomy v1.0 defines 40 event types across 8 categories:

| Category | Events | |---|---| | Party | shield.party.joined, shield.party.left, shield.party.identity.verified, shield.party.identity.failed, shield.party.role.assigned | | Session | shield.session.created, shield.session.opened, shield.session.closed, shield.session.expired, shield.session.archived | | Content | shield.content.uploaded, shield.content.viewed, shield.content.downloaded, shield.content.deleted, shield.content.hash.verified, shield.content.submitted | | Negotiation | shield.negotiation.terms.proposed, shield.negotiation.terms.accepted, shield.negotiation.terms.rejected, shield.negotiation.terms.modified, shield.negotiation.terms.expired, shield.negotiation.message.sent, shield.negotiation.message.read | | Agreement | shield.agreement.drafted, shield.agreement.reviewed, shield.agreement.approved, shield.agreement.signed, shield.agreement.countersigned, shield.agreement.voided, shield.agreement.reached | | Access | shield.access.granted, shield.access.revoked, shield.access.attempted, shield.access.denied | | Disclosure | shield.disclosure.presented, shield.disclosure.acknowledged, shield.disclosure.declined | | Evidence | shield.evidence.exported, shield.evidence.verified, shield.evidence.tampered_detected | | Agent Actions | shield.agent.action.navigated, shield.agent.action.clicked, shield.agent.action.input_filled, shield.agent.action.submitted, shield.agent.action.confirmed, shield.agent.action.payment_initiated, shield.agent.action.payment_confirmed, shield.agent.action.tool_called, shield.agent.action.human_approval_requested, shield.agent.action.human_approval_granted |

Standard event types are available as ShieldEventType enum members. Agent action types are available as AgentActionEventType enum members.

Versioning & API compatibility

This SDK follows Semantic Versioning.

  • Pre-1.0 (current): minor-version bumps may ship breaking changes. Pin the full version in your lockfile.
  • 1.0 and later: the public API is stable within a major version. Breaking changes require a major-version bump.

The Shield HTTP API is versioned at the URL path (/api/v1). This SDK targets /api/v1 and will not transparently follow a server-side version bump — a new server major version will be delivered as a new SDK major version so callers opt in explicitly.

Links