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

@op-lean/emdash-plugin

v0.2.0

Published

Sandboxed EmDash plugin for scheduled Original Poster AI drafts.

Readme

Original Poster for EmDash

Sandboxed plugin for EmDash 1.0.1 or later. It creates article drafts and separate revision drafts through the paid Original Poster service. It never publishes content.

The plugin is free and MIT licensed. Generation requires a service subscription sold through Stripe. Topics and selected source content leave the site for the private service and its configured AI provider. Disconnecting stops local scheduling and removes credentials. It does not cancel Stripe or undo a provider call already started.

Package installation

Version 0.2.0 uses the sandbox descriptor. For local verification, build and pack the plugin workspace, then install its tarball in a test site.

npm run build --workspace plugin
npm pack --workspace plugin --pack-destination .local
npm install @op-lean/emdash-plugin
import originalPoster from "@op-lean/emdash-plugin";
// In the site's existing emdash(...) configuration:
sandboxed: [originalPoster],

Use the site's standard sandbox runner. On Cloudflare it requires Worker Loader, PluginBridge, plugin code storage, an EmDash encryption key and the EmDash scheduler with a Cron Trigger. These belong to the site host. Open Original Poster in the Plugins menu, connect the paid service, then configure topics and a schedule. Credentials are saved in encrypted EmDash settings; no per-plugin Worker secret is needed.

Generation runs in the private service's Cloudflare Workflow. A plugin cron task retrieves its result and saves a draft after the browser closes. A job the service reports as failed, for example over the spend limit, is cleared and shown as an error; the next Create draft starts a new paid job. A job whose result could not be read or saved stops automatic polling. Check access and the service spend ledger, then check the result again or discard the job.

The destination collection must have title: string and content: portableText. The default is posts. Configure the collection in plugin settings. Revision drafts preserve the source entry.

Interrupted draft saves

A retry of the same generation job uses its stored output. CMS creation is a separate operation. completeContentWrite in src/flow.ts creates the draft, stores its ID in plugin KV, sends that ID to /v1/content-complete, and deletes the KV receipt. finishPendingDraft then deletes the pending job.

An interruption can create a second draft in two cases:

  1. CMS commits the draft, but its bridge reply is lost or execution stops before the KV receipt is stored. Recovery cannot find the first draft's ID and calls CMS create again.
  2. The service confirms completion and the plugin deletes its KV receipt, but execution stops before pending-job deletion. Recovery still sees the job. This polling path does not check the service's completed-write receipt before calling CMS create again.

While the KV receipt exists, recovery reuses its ID, including after a failed completion request. The first gap predates the sandbox migration. The second is in the asynchronous polling path introduced in 0.2.0. Both remain unresolved. They can duplicate a CMS draft using the existing generation output; they do not themselves request another paid generation or publish either draft. These are code-identified failure windows, not an observed production incident. Successful local retry checks do not prove crash-safe CMS creation.

Build and verification

npm ci
npm run check
npm test
npm run build
npm run bundle --workspace plugin

The pinned official @emdash-cms/[email protected] builds dist/plugin.mjs, dist/manifest.json and the default npm descriptor dist/index.mjs. Only the plugin workspace is distributable. The private service, D1 database and provider secrets are excluded.

emdash-plugin.jsonc pins publisher did:plc:ug6xwhbclf7z3hprhpje4gdh, currently originalposter-ai.bsky.social. The official CLI checks that the authenticated publisher matches this identity before registry publication. Manual registry releases upload the bundle to this publisher's PDS. Delegated repository releases require a public plugin-only source repository. npm publication does not add a catalog listing. Hosting and rollout belong to op-lean.

The service must deploy GenerationWorkflow and its GENERATION binding before client rollout. This migration has not deployed either component.