Releases: steelyard-dev/steelyard-sdk
Release list
v0.10.0 — @steelyard/psp adapter contract + conformance kit
Steelyard v0.10 turns PSP adapters into a public, contributable contract. The new
@steelyard/psp package owns the protocol-neutral merchant interfaces and
re-exports the buyer-side issuer contract types from @steelyard/core, so adapter
authors can depend on one thin package instead of the full merchant checkout
server. Existing @steelyard/merchant/psp imports continue to work through
compatibility re-exports, and the first-party Stripe, reference, and mock adapters
remain in-repo as reference implementations.
The release also adds a framework-agnostic conformance kit at
@steelyard/psp/conformance, plus a standalone-shaped
examples/psp-adapter-template/ package that external authors can copy into their
own repos. The docs now describe the scoped trust boundary, the additive-only
contract stability policy, and the steelyard-psp-* / steelyard-psp
discoverability convention for third-party adapters.
v0.9.0 — steelyard umbrella package + serveCommerce
Steelyard v0.9 makes the SDK easy to start with. A new steelyard umbrella package
replaces the six-package install and the 500-plus-symbol surface with one install and
a curated front door: the ~15 symbols most integrators actually need, re-exported from
the existing packages. Nothing is hidden — the underlying @steelyard/* packages are
unchanged and still importable directly for the full surface.
The headline is serveCommerce(manifest): one call serves your catalog over every
read surface — commerce.json, the plain HTTP API, MCP, ACP, and UCP — from a single
manifest, read-only by default with no PSP or keys required. It composes the existing
protocol handlers behind one path router (a generalization of the coffee-shop example),
so behavior is identical to wiring each surface by hand. The getting-started guide now
leads with a build-your-own quickstart: install one package, write eight lines, and
curl a live multi-protocol endpoint of your own catalog in under two minutes. This
release is purely additive; every existing import keeps working.
v0.8.0 — ucp-signing extraction + PspCaptureResult dedup
Steelyard v0.8 is a behavior-preserving navigation cleanup. The AP2 mandate and
UCP HTTP Message Signature algorithms now live in the optional
@steelyard/ucp-signing package, with the existing buyer, merchant, and
protocol import paths preserved through compatibility re-exports and adapters.
The wallet vault remains the UCP signing-key custodian; ucp-signing operates
through the public UcpSigner seam and does not take ownership of private key
storage.
The release also collapses the duplicate PSP capture-result unions into one
canonical PspCaptureResult exported by @steelyard/core. AP2 remains opt-in
through UCP capability negotiation, the legacy
net.steelyard.checkout_mandate.v0_1 mandate mode is retained, and the refactor
does not change protocol or checkout behavior.
v0.7.0 — UCP PSP-neutral payment seam
Steelyard v0.7 generalizes UCP payment wiring beyond Stripe-specific Shared
Payment Tokens. Merchant PSP adapters now declare neutral payment capabilities,
UCP discovery derives payment_handlers from those capabilities, and the buyer
matches wallet issuers to advertised available_instruments instead of falling
back to implicit Stripe behavior. Stripe remains supported through
shared_payment_token, but UCP can now complete with another issuer-defined
instrument type.
The release adds a guarded reference PSP and buyer issuer for local interop and
demo validation. The reference path signs delegated_payment_token handles and
verifies merchant, checkout, transaction, amount, currency, handler, instrument,
signature, and expiry before capture. Coffee-shop validation now runs the same
catalog through Stripe-backed and reference-backed UCP checkout configs and
compares receipt shape and order outcome.
ACP is unchanged in scope: it remains intentionally direct Stripe SPT-only in
v0.7 and rejects non-shared_payment_token wallet issuers before minting. The
new docs describe the adapter boundary, the reference PSP guard rails, neutral
Stripe error mapping, and the UCP/ACP split.
v0.2.0 — Wallet façade + policy engine + encrypted local vault
Local-first wallet for autonomous agent buying. Four-method surface for the junior path; full policy + vault primitives underneath for power users.
The 10-line junior path
import { Wallet } from "@steelyard/buyer";
const wallet = await Wallet.open();
if (await wallet.isAllowed(intent)) {
const payment = await wallet.pay(intent);
// v0.3 will charge then call payment.complete()
// v0.2 stops here:
await payment.cancel();
}That's it. No YAML to write, no keystore to pick, no UUID to manage.
What ships in this release
| Package | Purpose |
|---|---|
@steelyard/buyer (root) |
Wallet façade — create, open, isAllowed, decide, pay, plus 12 maintenance methods (cards, limits, billing, recovery, rotatePassword). |
@steelyard/buyer/policy |
YAML policy engine. Deny-by-default. can / cannot rules with glob domains, ISO-4217 currency-explicit limits, project-vs-global overlay (global cannot always wins). |
@steelyard/buyer/vault |
Local encrypted card vault. XSalsa20-Poly1305 via @noble/ciphers. Master key in OS keychain (@napi-rs/keyring) by default; passwordKeystore (Argon2id-derived) for headless / Alpine / NixOS / containers. |
@steelyard/buyer/client |
Unchanged from v0.1 (buyer SDK for MCP/ACP/UCP). |
@steelyard/agent |
Unchanged from v0.1 (LLM CLI). |
@steelyard/protocol |
Unchanged from v0.1 (MCP/ACP/UCP adapters). |
Cross-platform CI matrix (all green)
| Lane | What it proves |
|---|---|
macos-latest / keychain |
@napi-rs/keyring works on hosted macOS without Touch ID prompts |
ubuntu-latest / keychain |
libsecret + gnome-keyring-daemon spun up in a single CI step works for the Secret Service path |
ubuntu-latest / password |
The no-system-deps passwordKeystore path works (Argon2id-derived master key) |
Advisory, not enforced
v0.2 ships advisory primitives. Policy and vault enforce nothing on a misbehaving agent that imports the subpaths directly. A prompt-injected agent could call vault.revealCard() and ignore the policy entirely. v0.3's purchase() will wire policy.decide → vault.pay into a single enforced flow that closes that bypass.
This is documented in the Wallet docs page — juniors using the Wallet API are safe by default; the bypass requires intentional subpath imports.
Test coverage
| Package | Tests | Coverage |
|---|---|---|
@steelyard/buyer |
62 | 96.46% |
@steelyard/core |
11 | 100% |
@steelyard/protocol |
27 | 98.16% |
@steelyard/agent |
8 | 90.06% |
Compatibility
Pre-1.0 minor-match (per the rule we established in v0.1.0).
v0.2.xclient ↔v0.2.xserver → ✅ compatiblev0.2.xclient ↔v0.1.xserver → ❌version_mismatchv0.2.xclient ↔v0.3.xserver → ❌version_mismatch
The read-side capability version on @steelyard/protocol/mcp servers stays at 0.1 until v0.3 ships payment-capable adapters; only the buyer-side package versions bump.
Settled design decisions
The full v0.2 design went through two rounds of adversarial review with Codex. 38 numbered decisions are baked into the implementation, including:
- XSalsa20-Poly1305 over AES-256-GCM (pure JS, no native crypto)
- UUID-bound vault headers (vault survives file moves and machine recovery)
isAllowed(): boolean+decide(): Decisionsplit (kills the truthy-object footgun)- No
wallet.vault/wallet.policyproperties on the root Wallet (forces juniors through the safe path) - Currency-explicit
SimpleLimits(JPY/KRW convert correctly) - Spending ledger uses
proper-lockfile+O_APPEND(atomic across processes) - Recovery via
exportRecovery()is part of setup, not buried in engine docs
Docs
The public mkdocs site is updated:
- Wallet (junior surface) — start here
- Policy (engine)
- Vault (engine)
- Existing protocol pages updated to reflect the v0.1 namespace migration (
@steelyard/protocol/mcp, etc.)
Full changelog: v0.1.0...v0.2.0
v0.1.0 — read-side multi-protocol commerce SDK
The first cut of Steelyard. Define commerce once. Serve it as a real MCP server, a real ACP feed, and a real UCP discovery endpoint, all from the same defineCommerce() config.
What ships
Six packages on npm under MIT:
| Package | What it does |
|---|---|
@steelyard/core |
Schema, types, defineCommerce(), validate(). Runtime dep on zod only. |
@steelyard/mcp |
Emit an MCP server via @modelcontextprotocol/sdk. Tools list_offers, get_offer; resources commerce://manifest, commerce://policies. HTTP + stdio transports. |
@steelyard/acp |
Emit an ACP feed. AJV-validated against the vendored spec at 2026-04-17 at emit time. |
@steelyard/ucp |
Emit a UCP discovery doc and shopping catalog API. AJV-validated against UCP 2026-04-08 schemas at emit time. |
@steelyard/client |
Buyer SDK with MCP/ACP/UCP auto-detect. Steelyard.connect(url) returns the same Merchant handle regardless of which protocol the merchant speaks. |
@steelyard/agent |
LLM-driven CLI (steelyard-agent). Uses Anthropic when ANTHROPIC_API_KEY is set; falls back to a naive regex parser otherwise. Both paths reach an answer. |
The principle
No fake / incomplete stuff. Every package is end-to-end tested against real protocol clients. ACP feeds and UCP catalog responses are AJV-validated at emit time — a bug that would produce non-conformant output throws before the bytes leave the server.
What v1 doesn't do
Read-side only. Payment execution (carts, checkout, receipts, Stripe adapter, wallet delegation) is deliberately deferred to v2. The trust/idempotency/SCA/consent design space needs its own pass — we'd rather ship a complete read-side now.
Compatibility
Pre-1.0 minor-match semver on the read-side capability:
| Client | Server | Result |
|---|---|---|
0.1 |
0.1.x |
✅ Compatible |
0.1 |
0.2.x |
❌ version_mismatch |
0.1 |
1.0.x |
❌ version_mismatch |
Quickstart
npx @steelyard/agent --merchant http://localhost:3000/mcp "what does this shop sell"Or boot the example:
git clone https://github.com/interfacelabs/steelyard-sdk.git steelyard
cd steelyard && pnpm install && pnpm -r build
pnpm --filter @steelyard/example-coffee-shop startSee docs/getting-started.md for the full demo.
Test coverage
@steelyard/core— 100%@steelyard/mcp,@steelyard/acp,@steelyard/ucp,@steelyard/client— ≥ 95%@steelyard/agent— ≥ 90%
PR CI runs mocked unit tests on every PR; a scheduled CI job runs the live protocol-parity test daily and on every release tag.
Full changelog: https://github.com/interfacelabs/steelyard-sdk/commits/v0.1.0