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

@scribe-platform/cli

v0.7.0

Published

Command-line interface for Scribe CMS — scaffold sites, edit content, and triage form submissions from the terminal

Downloads

1,503

Readme

@scribe-platform/cli

The scribe command line interface for Scribe CMS — provision sites, edit content, manage schemas, and triage form submissions from a terminal.

Scribe stores every site's content in its own GitHub repo as Markdown plus a .scribe.yml schema. The CLI talks to a Scribe admin instance, which does the GitHub work on your behalf.

Install

npm install -g @scribe-platform/cli

Requires Node.js 20 or newer.

Log in

You need an API key from a Scribe admin instance: sign in to the admin UI → account menu → API Tokens → New token.

scribe login --token <key>

This writes ~/.scribe/config.json (mode 600); every other command reads it. It defaults to the hosted admin at https://scribe.weaverdigital.io — pass --api-url (or set SCRIBE_API_URL) to point at a different one:

scribe login --token <key> --api-url http://localhost:3000

Update

scribe update

Installs the latest @scribe-platform/cli and copies the bundled scribe-site-builder Claude Code skill into ~/.claude/skills/, so the CLI and the instructions Claude reads move together. Restart Claude Code afterwards — it only discovers skills at session start.

Requires a global npm install; it refuses to guess for a checkout, npx, or another package manager. A symlinked ~/.claude/skills/scribe-site-builder is left untouched, so a dev checkout's live skill isn't replaced by a copy.

Commands

Run scribe <group> --help for the full options on any of these.

Sites

scribe site list [--archived] [--json]
scribe site add --slug <slug> [--domain <domain>] [--name <name>]
                [--turnstile-key <key>] [--form-collection <name>]
scribe site update <slug> [--domain <domain>] [--turnstile-key <key>]
scribe site clone <slug> [directory]
scribe site deploy <slug> [--skip-verify] [--timeout <minutes>]
scribe site verify <slug> [--json]
scribe site archive <slug>
scribe site restore <slug>
scribe site delete <slug> [--yes]

site add creates the GitHub repo, pushes a minimal valid scaffold, and registers the site with the admin in one step. There is no starter template to fill in — the site is authored against the recipes in the scribe-site-builder skill. site clone is a plain git clone of the resulting repo, so you can work on the design locally.

site deploy dispatches the build, waits for GitHub Pages to finish, then checks what actually shipped. site verify runs those checks on their own against whatever is live, and exits non-zero if any fail — so it works in a script. The five things they check are a contract between a site and Scribe, and every one of them fails silently:

| Check | What it costs when it's missed | |---|---| | analytics | No visitor data, and it cannot be backfilled | | turnstile | The endpoint rejects real submissions, or the form is open to abuse | | retry | A visitor is told their enquiry sent when it didn't. A lost lead | | dispatch | An editor publishes, the admin says saved, the site never updates | | basepath | Every link and asset 404s |

Forms are optional: a site with none skips turnstile and retry rather than failing them. A site with nothing deployed yet skips everything and exits zero. --skip-verify exists and prints what it gave up.

site archive is how a site comes down: it turns GitHub Pages off and makes the repo read-only, and deletes nothing. site restore brings it back and starts a deploy. site list shows live sites, and site list --archived shows only the archived ones. Both need a key belonging to Agency staff.

site delete permanently removes the repo and every record of the site, and only works on a site that is already archived. It cannot be undone, and prompts for confirmation unless you pass --yes. With no terminal to prompt on, it exits instead.

Content

scribe content list <site> [--collection <name>] [--json]
scribe content read <site> <path> [--json]
scribe content publish <site> <file>
scribe content delete <site> <path>
scribe content versions <site> <path> [--json]
scribe content revert <site> <path> --sha <commitSha>

Paths are repo-relative (e.g. content/posts/hello.md). content publish reads the identically-named file from your working directory and commits it to that path.

Schema

scribe schema show <site> [collection-name] [--json]
scribe schema apply <site> --file <spec|->
scribe schema add <site> <collection-name> [--path <path>]
scribe schema remove <site> <collection-name>

schema show prints the site's collections and their fields; --json gives the raw schema, for piping into another tool.

schema apply creates or replaces one whole collection from a YAML or JSON spec, matched by name. It validates before committing anything, so a reserved field name, an image field on a form collection, or a malformed workflow comes back as an error rather than a broken site. Pass --file - to read from a pipe.

# rsvps.yml — then: scribe schema apply my-site --file rsvps.yml
name: rsvps
label: Event RSVPs
path: content/rsvps
format: yaml
form: true
fields:
  - { name: fullName, type: string, required: true }
  - { name: email,    type: string, required: true }
  - { name: guests,   type: number }
  - { name: attending, type: boolean, label: I'll be there }
workflow:
  states:
    - { name: pending,   label: Awaiting reply, kind: needs-you }
    - { name: confirmed, label: Confirmed,      kind: closed }

A site can have as many form: true collections as it likes; each gets its own inbox and workflow. schema apply replaces the collection wholesale, so include every field you want to keep.

schema add appends a bare collection stub with no fields — use it to start a content collection interactively. For anything with fields, prefer schema apply.

Form submissions

scribe submission list <site> <collection> [--status <status>] [--page <n>] [--json]
scribe submission update <site> <collection> <id> [--status <status>] [--note <note>]
scribe submission export <site> <collection> [--format csv|json] [--status <status>] [--out <file>]
scribe submission delete <site> <collection> <id> [--yes]

<id> is the submission's id as printed by submission list. --note appends to the submission's history; notes are an append-only log, so nothing overwrites an earlier one.

export writes to stdout unless --out is given, so it pipes:

scribe submission export daves-exotic-cars inquiries > leads.csv

CSV is for a spreadsheet and is lossy on purpose — its columns come from the collection's schema (so the header row is identical between exports, even when a batch left a field blank), and it carries no history and no visitor IP or user agent. --format json is the lossless one: every field, with each submission's events nested under it.

delete is permanent and cascades the submission's history. It needs a staff role — a site user's API key gets a 403 — and it prompts for the id unless you pass --yes. There is no equivalent in the admin UI, on purpose.

Builds

scribe build trigger <site>

Dispatches the site's build workflow and returns immediately. Debounced to once every five minutes. Prefer scribe site deploy, which waits for the build and then checks the result.

Programmatic use

The API client and config helpers are exported for scripting:

import { ScribeClient, ScribeApiError } from '@scribe-platform/cli/client';
import { loadConfig } from '@scribe-platform/cli/config';

const config = loadConfig();
if (!config) throw new Error('Run `scribe login` first.');

const client = new ScribeClient(config);
const sites = await client.listSites();

License

MIT