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

@spoolis/accept

v0.1.1

Published

Turn acceptance policy and delivered work into a verified Spoolis Outcome in one call.

Readme

Accept work with Spoolis

@spoolis/accept turns your acceptance policy and delivered work into a verified Spoolis Outcome. It is a small, dependency-free client for the canonical agreement, judgment, and Outcome path.

Install

npm install @spoolis/accept

Node 20 or later is required.

Make one call

import * as spoolis from '@spoolis/accept'

const criteria = 'Every row must have status done'
const evidence = { rows: [{ id: 1, status: 'done' }] }
const judge = {
  meta: {
    evaluator_id: 'my-evaluator',
    kind: 'buyer_owned',
    evaluator_version: '1',
    proof_requirement: 'declared',
  },
  async run({ evidence }) {
    return { pass: evidence.rows.every((row) => row.status === 'done') }
  },
}

const outcome = await spoolis.accept({ criteria, evidence, judge }, {
  baseUrl: 'https://spoolis.com',
  apiKey: process.env.SPOOLIS_API_KEY,
})

console.log(outcome.status, outcome.receiptId)

Use policy when you need pricing, thresholds, or uncertainty behavior:

import * as spoolis from '@spoolis/accept'

const outcome = await spoolis.accept({
  policy: {
    criteria: [{
      description: 'Every row includes status',
      check: { checker: 'completeness', required_fields: ['status'] },
    }],
    units: 100,
    unitValueCents: 500,
  },
  evidence: { rows },
}, {
  baseUrl: 'https://spoolis.com',
  apiKey: process.env.SPOOLIS_API_KEY,
})

console.log(outcome)
// {
//   status: 'partial',
//   accepted: 82,
//   rejected: 18,
//   uncertain: 0,
//   earnedCents: 41000,
//   spoolId: 'spl_example',
//   receiptId: 'ocr_example',
//   receiptUrl: 'https://spoolis.com/r/ocr_example',
//   receipt: { id: 'ocr_example', result: 'partial', amounts: { earned_cents: 41000 } }
// }

The API response uses earned_cents. The SDK exposes the same server-authored value as earnedCents; it does not recompute economics.

Request options

Every request has a 30-second timeout. Set timeoutMs to a positive integer to choose a different timeout.

Set retry: true to allow one retry after a short delay for requests that are safe to repeat. The SDK retries network errors, HTTP 429 responses, and HTTP 5xx responses. It never retries other HTTP 4xx responses, Spool creation, or evidence submission.

For the one-shot accept() path, set idempotencyKey to a stable string of 1–128 characters. The SDK sends it as idempotency_key. Supplying this key makes one-shot retries safe, so the SDK retries that request only when both retry: true and idempotencyKey are set. Reuse the same key when replaying the same operation across process restarts.

Accept purchased work

Use acceptPurchase({ criteria | policy, purchase, result, judge? }, options) when a result came from a paid tool or service. The optional purchase context is carried with the evidence, not added to the canonical Outcome. The returned nextAction maps accepted-only work to continue, rejected work to retry, and any uncertain work to hold.

evidenceFromLangSmithRun(run) converts a plain LangSmith run object without fetching or adding a dependency. spoolisAcceptanceNode(config) returns a plain async LangGraph-compatible node. It writes acceptance data to state.spoolis; a rejected Outcome is returned as data rather than thrown.

Define a policy

An AcceptancePolicy has these fields:

  • criteria: A nonempty description or 1–50 descriptions paired with deterministic checks.
  • units and unitValueCents: Optional positive integers that must appear together. Their product is the maximum amount unless you also provide the same value as maxAmountCents.
  • maxAmountCents: An optional positive integer cap.
  • acceptIf: Optional quality and consensus thresholds from 0–100. These are for an external scored judge.
  • onUncertain: Optional and currently limited to hold.

Evidence must provide exactly one of rows, payload, or url. Every call requires exactly one of top-level criteria or policy. The criteria shorthand is equivalent to policy: { criteria }; use policy for all other policy fields.

Bring your own judge

Use your own evaluator without computing agreement or evidence hashes, as shown in the first example.

For per-unit evaluation, add units and unitValueCents in policy, then return { units: [{ id, pass }] }. Spoolis passes the exact unitIds to judge.run. For scored evaluation, set acceptIf and meta.schemaId, then return either { quality, consensus } or scored units. acceptWithJudge exposes the same lifecycle directly and accepts either { criteria, evidence, judge } or { policy, evidence, judge }.

The helper creates a unilateral Spool, submits evidence, reads the server-authored binding, runs your evaluator, submits its normalized result, verifies the Spool, and returns the same AcceptOutcome shape as accept. Server binding checks remain mandatory.

Fail safely

An uncertain result never becomes accepted. Missing fields, contradictory counts and receipt status, unknown receipt status, or any nonzero uncertain count map to status: 'uncertain'. Rejected and uncertain units do not become earned value. The SDK preserves the server's earned_cents value and does not author a replacement.

Verify the receipt

Use @spoolis/receipt-verifier to verify the signed Outcome Receipt offline before a consequential next action.

Exports

The package exports accept, acceptWithJudge, acceptPurchase, nextActionFor, evidenceFromLangSmithRun, spoolisAcceptanceNode, acceptancePolicySchema, AcceptancePolicyError, ExternalJudgeLifecycleError, JudgeAdapterError, toOneShotBody, deterministicChecker, scoredJudge, binaryJudge, toExternalJudgeDeclaration, and version. TypeScript users also receive AcceptancePolicy and the related input, outcome, judge, and check types.