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

@pageloop/cli

v0.6.1

Published

The `pageloop` command — the operator + agent CLI for PageLoop. Same dispatch path the web admin uses, but runs without a long-lived server process: one-shot tasks (login, create a project, read a page's tasks), self-host server management, and CI scripts

Readme

@pageloop/cli

The pageloop command — the operator + agent CLI for PageLoop. Same dispatch path the web admin uses, but runs without a long-lived server process: one-shot tasks (login, create a project, read a page's tasks), self-host server management, and CI scripts.

pageloop --help
pageloop <command> --help

The CLI is concise by design: every required value is an optional flag. Anything you don't pass is taken from your config file (below), an env var, or — when you're at a terminal — an interactive prompt. So pageloop login with no flags just asks you what it needs.


Configuration & defaults

How a value is resolved

For every argument, in order (first match wins):

  1. the flag you passed (--endpoint …)
  2. the matching env var (PAGELOOP_ENDPOINT, PAGELOOP_TOKEN)
  3. the merged config file (see below)
  4. a built-in default (e.g. endpoint → https://pageloop.dev)
  5. an interactive prompt (only at a TTY; shows the default in [brackets])

Non-interactive runs (CI, pipes) never prompt — they use the default or exit with a clear "pass it as a flag" error.

The config file

Optional JSON holding your default arguments so you don't repeat them. Layers merge, later overriding earlier:

| Layer | Path | Scope | |---|---|---| | global | ~/.config/pageloop.json (or $XDG_CONFIG_HOME/pageloop.json) | all projects, this machine | | local | ./pageloop.json | the current project directory | | explicit | --config <path> | one invocation |

// ~/.config/pageloop.json
{
  "endpoint": "https://pageloop.dev",   // default server (the global service)
  "projectId": "my-docs",               // default --project for project-scoped commands
  "email": "[email protected]"             // sign-in convenience
}

Anything still missing for the command you run is prompted for, leaning on these as the prompt defaults.

Endpoint

The endpoint defaults to https://pageloop.dev (the hosted service). Override per-command with --endpoint, per-machine with the config file, or pin one with pageloop server default --endpoint <url>. Self-hosters set their own URL during pageloop setup.

Session / login

pageloop login validates and caches a bearer token at ~/.config/pageloop/token (mode 0600), keyed to the endpoint it was issued for. Subsequent commands pick it up automatically. If a token has expired, commands fail with a clear hint to re-run pageloop login --endpoint <url> (your endpoint is retained).


Getting started

pageloop setup                 # wire the current directory to a project (interactive)
pageloop login                 # sign in (prompts for endpoint → defaults to pageloop.dev)
pageloop project create        # create a project (prompts for slug / name / owner)
pageloop go                    # self-host: run setup if needed, then start the server

pageloop setup asks for your default endpoint (offering https://pageloop.dev) and writes it, plus your project details, into a pageloop.json so later commands need no flags.


Server management (self-host)

| Command | Purpose | |---|---| | pageloop server start [-D] | Run the HTTP transport (RPC + WS + SSE). -D/--daemon for background. | | pageloop server init | First-boot bootstrap — DB + default org/project. Idempotent. | | pageloop server default --endpoint <url> | Pin the default endpoint (--clear to forget). | | pageloop server status / stop | Daemon liveness / shutdown. | | pageloop server update | On a server install: git pull → install → build → migrate → restart. |

Projects + organizations

pageloop projects                       # list projects you can see on the server
pageloop project create                 # prompts for slug / name / owner-email
pageloop project create --slug my-docs --name "My Docs" --owner-email [email protected]
pageloop project [--slug my-docs]       # info for one project (defaults to ./pageloop.json)

project create goes over HTTP (auth + policy + audit) by default. Pass --db <url> instead for an operator-direct local write (first-boot bootstrap only) — it never mixes with --endpoint.

Pages + page groups

| Command | Purpose | |---|---| | pageloop page list [--project <slug>] | List a project's pages (remote by default; --db for local). | | pageloop page comments --id <pageId> | Print a page's comments as JSON — see below. | | pageloop page rename --project <s> --page <id-or-key> --to <key> | Rekey a page. | | pageloop page migrate --project <s> --root <dir> --strategy <s> | Bulk rekey. | | pageloop page move-to-group --project <s> --page <id> [--group <n>] [--create] | Re-parent a page. | | pageloop group list / create / rename / move / trash --project <s> … | Page folders. |

Reading comments + tasks (for agents)

Pull a page's comments as raw JSON. The short way is just the page id — the server resolves the project and checks your read access:

# Every unresolved task on a page (an agent's open to-do list):
pageloop page comments --id <pageId> --unresolved

--unresolved is shorthand for --task --task-status unresolved. Drop it to get all comments; use --task for all tasks regardless of state, or --task-status resolved for completed ones. Output is a JSON array, ready to pipe into jq or an agent.

| Flag | Effect | |---|---| | --id <pageId> | The tracked page id (prompted if omitted). | | --unresolved | Only open tasks. Shorthand for --task --task-status unresolved. | | --task | Only comments promoted to tasks (resolved or not). | | --task-status <unresolved\|resolved> | Narrow tasks to a completion state. | | --endpoint <url> / --token <jwt> / --config <path> | Standard resolution (defaults to your session). |

Under the hood this hits the convenience REST endpoint, which also accepts the pageId form directly:

curl -s -G "https://pageloop.dev/api/v1/comments" \
  -H "Authorization: Bearer $PAGELOOP_TOKEN" \
  --data-urlencode "pageId=<pageId>" \
  --data-urlencode "taskStatus=unresolved"

The older projectId=<slug>&pageKey=<key> form still works. Response is { "comments": Comment[] }. Mutate a task via the RPC comments.setTask({ commentId, isTask?, resolved? }).

Authentication

pageloop login                  # interactive: prompts for endpoint, opens a browser (loopback OAuth)
pageloop login --github         # force a provider
pageloop login --no-browser     # copy-paste fallback (headless / SSH)
pageloop login --token <jwt>    # accept a token directly (CI)
pageloop whoami                 # endpoint + user (never prints the token)
pageloop logout

Repositories

# Connect an existing repository to a project.
pageloop repo add --project my-docs --remote-url https://github.com/me/docs
pageloop repo list --project my-docs
pageloop repo sync --repo-id <repo-id>

# Scout paths, then import files as tracked pages (folders → page groups).
pageloop repo browse my-docs docs/api --branch develop
pageloop repo import my-docs docs/ --include md,html
pageloop repo import my-docs docs/ --include md --flatten      # everything at root
pageloop repo import my-docs docs/ --include md --dry-run      # preview only

Import flags:

| Flag | Meaning | |---|---| | --branch <name> | Read from this branch instead of the repo's default. | | --flatten | All files at project root; clashes auto-rename name (2).ext. | | --include <ext,…> / --exclude <ext,…> | Whitelist / blacklist extensions (no dot). Exclude wins. | | --exclude-path <frag,…> | Skip paths containing any substring. | | --conflict <skip\|overwrite\|rename> | Already-tracked path behaviour (default skip). A trashed match is always restored. | | --dry-run | Preview bucket counts; write nothing. |

repo import writes directly via the persistence adapter as a synthetic superadmin — anyone with shell access to the DB can run it.

Static-site injection

# From your site root — patches every .html, no snippet to paste.
pageloop inject --project my-docs --endpoint https://pageloop.dev
pageloop inject "blog/**/*.html" --project my-docs --channel 0.3   # scope + pin a track
pageloop uninject --root . "**/*.html"                             # byte-clean removal

inject appends one self-contained loader <script> that pulls the current widget bundle + CSS and auto-updates (rolling back on a bad release). Re-running is idempotent. pageloop setup --inject does register-then-inject for a new project in one step. SPAs skip this — import the widget once at the app root.

Other

| Command | Purpose | |---|---| | pageloop admin --email <e> | Promote a user to platform-superadmin (direct DB; first-boot). | | pageloop token --email <e> | Issue a long-lived JWT for testing / CI (direct DB). | | pageloop project list / page list --db <url> | Operator-direct local-DB reads (bypass the server). | | pageloop migrate-data --from <url> --to <url> | Bulk-copy rows between backends (SQLite ⇄ Postgres). Idempotent. | | pageloop publish [--root <p>] [--version <v>] [--channels <list>] [--dry-run] | Publish a widget bundle to a CDN root + channels. |

Operator-direct commands accept --db <url> (default sqlite:./.pageloop/pageloop.db) and --secret <jwt-secret> ($PAGELOOP_JWT_SECRET). They share the running server's handlers + DB locking, so a concurrent server + CLI mutation is safe.