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

@volter/twin-sendblue

v0.1.37

Published

Local SendBlue twin for the iMessage/SMS messaging surface (send-message + media_url, HMAC-SHA256-signed sb-signature status callbacks with a deterministic QUEUED->SENT->DELIVERED/ERROR lifecycle, evaluate-service lookup, message history) built on @volter

Readme

@volter/twin-sendblue

Legacy connector helpers: this package still has callable helpers using the retired v1 syncPull API. Those paths require migration before use on the current kernel; older helper descriptions below do not establish current compatibility. Check the generated index for protocol standing and use the shared model for current state semantics.

Local SendBlue twin for the iMessage/SMS messaging surface: send-message (text + media_url + send_style) behind sb-api-key-id/sb-api-secret-key header auth, a deterministic QUEUED→SENT→DELIVERED status lifecycle (fail-pattern numbers → terminal ERROR) advanced as a poll-fold — one step per read of the message history — whose transitions deliver sb-signature-signed (HMAC-SHA256 hex over the raw JSON body) status callbacks through an injected deliverer, an evaluate-service iMessage/SMS lookup (pure deterministic derivation), a message-history read surface, and the GET /twin/store/messages store door — built on the shared @volter/world-core kernel. API-first vendor (no product UI to mirror — the real SendBlue surface an integration touches is the REST API; the SendBlue dashboard is a config/analytics console, not an agent navigation target).

bun packages/twin/sendblue/src/cli.ts

Coverage

This is a v1 slice of the SendBlue API (single host, api.sendblue.co; JSON request bodies — the inverse of twilio's form-urlencoded surface). Grounding: the PeakHealth backend's production SendBlue consumer (SendblueClient / SendblueWebhookController — the authoritative consumer contract: auth header names, request/response field read set, HMAC-SHA256-hex sb-signature verification) plus SendBlue's public docs (docs.sendblue.com, fetched read-only during this build: endpoints, callback payload field names, the status enum, error-code list, per-line rate limits). SendBlue publishes no machine-readable first-party spec, so specifics neither source pins down — exact HTTP status codes, the error envelope beyond error_message — are annotated ⚠ in the manifest and never claimed beyond what the verify() proves. Errors carry {status:'ERROR', error_message} (error_message is the consumer-grounded field).

Modeled done (31): header auth (accept the world's established pair / 401-reject others, credentials-are-state), send-message (happy path + missing-number/missing-content/invalid-number 400s + JSON-only body parsing + media_url roundtrip + send_style echo + minted uuid-shaped message_handle), the exact QUEUED→SENT→DELIVERED lifecycle as a poll-fold (kernel-folded, deterministic, no wall clock, no timer) with per-transition sb-signature-signed callback delivery over an injected deliverer, the failure-simulation path (a recipient number matching the configurable fail pattern — default ending 0000 — goes QUEUED→ERROR, terminal, with error_code/error_message), signature sign/verify/tamper (consumer parity), evaluate-service (deterministic derivation + 400), message history (GET /accounts/messages), the {error_message} error envelope, readOnly/unmodeled-route safety, kernel-persisted state, the self-referential conformance snapshot, and a list-driven connector pull (idempotent).

Left as todo (honest gaps, not yet modeled — 23): group messages (send-group-message, modify-group), expressive-style catalog validation, history pagination/filters, RCS as a service class, media-object upload + voice notes, typing indicators, inbound message webhooks (+ inbound media), the ACCEPTED intermediate status, was_downgraded/service callback enrichment, callback retry policy, the documented error-code catalog, lines/seats/rate-limits/number-registration lifecycle, lookup rate limits, connector push + lines pull, and a fixtures seed.

The delivery lifecycle is a POLL-FOLD, not a timer

A send answers QUEUED and schedules nothing. Every read of the message history (GET /accounts/messages — the vendor's own read, and the poll) folds each stored message one step from (stored row, the request's world instant) and delivers that transition's sb-signature-signed status_callback as part of the fold, stamped from the same instant. The fold is the pure function foldSendblueStatus(row, at): a step lands only when the world clock has moved past the row's date_updated, so

  • re-serving one read at one instant is byte-identical (serve-path determinism, R9), and
  • a consumer polling a live world walks QUEUED → SENT → DELIVERED one status per read, and
  • a frozen world holds its messages exactly where they are until the clock advances — which is this twin's stated time model (clock-set, seed, clock-advance).

The vendor's async ordering is preserved where a consumer depends on it: the send response carries the message_handle and no callback has fired yet, so the handle is stored before the first callback arrives. There is no setTimeout and no wall-clock read anywhere on the serve path.

The store door: GET /twin/store/messages

GET /twin/store/messages is the twin's own named, read-only, deterministic projection over stored state (the twin programming model's store door; GET /twin names it under stores). The vendor's only read of a message IS the poll, which advances the lifecycle by design — so this is the read that observes a sent message without moving it. It is a twin door, not vendor surface: keyless, never folding, and deliberately absent from the capability manifest (counting scaffolding SendBlue does not have would pad the denominator).

The failure-simulation convention (D2 honesty)

No real send can fail locally, so the twin simulates the vendor's ERROR path deterministically: a recipient number matching the fail pattern (default 0000$, configurable via config.failNumberPattern / SENDBLUE_TWIN_FAIL_PATTERN) folds QUEUED → ERROR (terminal) on the next read, with error_code/error_message set, and its signed callback delivers like any other transition. Real Apple/carrier delivery physics are out of scope — lifecycle semantics and callback signing are the faithful part.

sb-signature

hex(HMAC-SHA256(webhookSigningSecret, rawJsonBody)), sent in the sb-signature header — written FRESH in src/sendblue-signing.ts (never ports twilio's HMAC-SHA1-base64 or the svix v1, scheme). Byte-for-byte what the PeakHealth consumer's verifyWebhookSignature recomputes (case-insensitive hex compare, length-checked timingSafeEqual); ⚠ the public docs don't document the signing algorithm, so the scheme is grounded in the real consumer's verification code rather than a vendor spec.

Credentials are STATE, not a function of the world's path

The accepted sb-api-key-id/sb-api-secret-key pair and the sb-signature signing secret are the root's own persisted credential resource, established exactly once and folded through the kernel action log (so they ride snapshots/hydrate/flush and survive a process restart). A root's pair is established in one of two ways:

  • minted with real entropy — sendblueCredentials(root) / sendblueApiKeyId(root) / sendblueApiSecretKey(root) / sendblueSigningSecret(root) on a virgin world generate one from randomBytes, so two fresh worlds are distinct by construction; or
  • seeded via the wire — the first request to reach a virgin world carries a pair and that pair becomes the world's credentials (the runtime contract's "fake vendor creds an app presents are twin state, seeded via the wire"). Every later request must match it or gets a 401.

They were previously sha256('sendblue-twin-…:' + root) — the world's directory was the credential, so identical worlds in different directories disagreed and moving a world dir rotated its keys. The path now never enters a credential, a signature, or a served byte, and nothing this twin serves ever carries one (the pair is compared, never echoed).

Config (sane local defaults)

apiKeyId/apiSecretKey/signingSecret come from that credential state and can be overridden per request (config) or on the server via the SAME env names the PeakHealth consumer uses (SENDBLUE_API_KEY_ID, SENDBLUE_API_SECRET_KEY, SENDBLUE_WEBHOOK_SIGNING_SECRET), plus twin-only SENDBLUE_TWIN_FROM_NUMBER / SENDBLUE_TWIN_FAIL_PATTERN.

Inspection

GET /twin/store/messages (the store door — observes without folding), GET /accounts/messages (vendor-shaped — the poll, which folds), or the in-process listSendblueMessages(root) accessor behind the door, which adds status_history (every status the lifecycle emitted) and the registered status_callback URL per message — the "message received by SendBlue" assertion surface for tests and pilots.