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

@apd-spec/sdk

v0.3.0

Published

TypeScript-friendly SDK for APD procedure definitions, workflow specifications, agent workflows, SOP export, and AER comparison

Readme

@apd-spec/sdk

@apd-spec/sdk is the TypeScript-friendly SDK for creating, validating, summarizing, visualizing, and exporting APD procedure definitions and AER receipts.

Install from npm

npm install @apd-spec/sdk

Then import it in your project:

const { APD, createApdScaffold, validateApd, validateAer, compareAerToApd, toSopMarkdown } = require("@apd-spec/sdk");

Entry points

Use the entry point that matches your environment:

  • @apd-spec/sdk or @apd-spec/sdk/node for Node.js validation, schema loading, CLI helpers, and the full SDK surface
  • @apd-spec/sdk/browser for browser-safe APD parsing, APD types, and SOP markdown export without filesystem or schema-loading dependencies

Example browser-safe import:

import type { APDDocument } from "@apd-spec/sdk/browser";
import { toSopMarkdown } from "@apd-spec/sdk/browser";

If you are working from a local clone of this repo, run:

npm install
npm run build

Primary exports

Builder:

  • APD
  • createApdScaffold
  • createApdGenerationPrompt
  • generateApdDraftFromText
  • normalizeGeneratedApdDraft

Read and validate:

  • parseApd
  • parseAer
  • validateApd
  • validateAer
  • summarizeApd
  • summarizeAer
  • compareAerToApd

Render and export:

  • toMermaid
  • toSvg
  • toSopMarkdown

Schema and diagnostics helpers:

  • loadSchema
  • loadApdSchema
  • loadAerSchema
  • graphDiagnostics
  • provenanceDiagnostics
  • bestPracticeDiagnostics
  • AERRecorder

Node-only integrity helpers from @apd-spec/sdk/node:

  • canonicalizeJson
  • computeAerChainHash
  • sealAer
  • verifyAerIntegrity

Start a new APD scaffold

const fs = require("fs");
const { createApdScaffold } = require("@apd-spec/sdk");

const scaffold = createApdScaffold({
  title: "Refund Review",
  procedureId: "refund-review"
});

fs.writeFileSync("refund-review.apd.json", JSON.stringify(scaffold, null, 2) + "\n");

Normalize a generated APD draft

Provider calls belong in your application or the CLI, but the SDK can create the prompt contract and normalize a provider draft into APD:

const { createApdGenerationPrompt, normalizeGeneratedApdDraft, validateApd } = require("@apd-spec/sdk");

const prompt = createApdGenerationPrompt("Review a refund request, approve high-value refunds, then notify the customer.");
const draft = await callYourModel(prompt);
const apd = normalizeGeneratedApdDraft(draft, {
  producer: "my-tool generate:openai",
  sourceText: prompt.input
});

console.log(validateApd(apd, { strict: true }));

Builder example

const fs = require("fs");
const { APD, toSopMarkdown } = require("@apd-spec/sdk");

const apd = APD.create({
  procedureId: "hello-world",
  title: "Hello World",
  summary: "Minimal APD created with the SDK.",
  entryConditions: ["A simple example is needed."]
});

apd
  .addAction({
    id: "step_1",
    name: "Do the thing",
    instruction: "Perform the step.",
    recovery: {
      strategy: "ask-user",
      instructions: "Pause for review if the step cannot be completed confidently."
    }
  })
  .addTerminal({
    id: "done",
    name: "Finished",
    outcome: "success"
  })
  .connect("step_1", "done");

fs.writeFileSync("hello-world.apd.json", apd.toString());
console.log(apd.validate());
console.log(toSopMarkdown(apd.toJSON()));

Validate an existing APD

Replace the example filename below with any APD file you have locally:

const fs = require("fs");
const { parseApd, validateApd, summarizeApd } = require("@apd-spec/sdk");

const document = parseApd(fs.readFileSync("refund-review.apd.json", "utf8"));
const result = validateApd(document, { strict: true });

console.log(result.valid);
console.log(result.diagnostics);
console.log(summarizeApd(document));

Export an APD to SOP markdown

Replace the example filename below with any APD file you have locally:

const fs = require("fs");
const { parseApd, toSopMarkdown } = require("@apd-spec/sdk");

const document = parseApd(fs.readFileSync("refund-review.apd.json", "utf8"));
const sop = toSopMarkdown(document);

fs.writeFileSync("/tmp/refund-review.sop.md", sop);

toSopMarkdown preserves APD provenance markers as HTML comments so the runtime markdown stays readable while still retaining round-trip debugging hints.

Validate and compare AER

Replace the example filenames below with your local APD and AER paths:

const fs = require("fs");
const { validateAer, compareAerToApd } = require("@apd-spec/sdk");

const apd = fs.readFileSync("refund-review.apd.json", "utf8");
const aer = fs.readFileSync("refund-review.aer-v0.3.json", "utf8");

console.log(validateAer(aer, { strict: true }));
console.log(compareAerToApd(apd, aer));

AER v0.1 remains supported for validation and summaries. AER v0.2 remains supported for comparison. AER v0.3 is the preferred signed receipt for compliance-grade integrity checks.

Seal and verify AER integrity

const fs = require("fs");
const { sealAer, verifyAerIntegrity } = require("@apd-spec/sdk/node");

const aer = JSON.parse(fs.readFileSync("refund-review.aer-v0.3.json", "utf8"));
const privateKey = fs.readFileSync("adapter.pkcs8.b64", "utf8");
const publicKey = fs.readFileSync("adapter.spki.b64", "utf8");

const sealed = sealAer(aer, { privateKey, publicKey, attestExecutor: true });
console.log(verifyAerIntegrity(sealed, { trustedPublicKeys: [publicKey] }));

verifyAerIntegrity requires trusted public keys supplied by the caller to report signatures and recorder attestations as valid. Embedded AER public keys are treated as claimed signer metadata, not as a trust root.

Related docs