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

shlook

v0.2.4

Published

Private-by-default artifact hosting for agents

Readme

shlook

shlook is a reusable, self-hosted Cloudflare package for publishing agent-created HTML, static sites, and raster images. Publications are private by default; public and secret-link sharing require an explicit visibility change.

Security model

A deployment has four browser origins with different trust levels:

| Origin | Purpose | Cloudflare Access | | ------- | ------------------------------------------ | ----------------- | | Owner | Owner UI/API and isolated archive previews | Required | | Private | Owner-authenticated artifact viewing | Required | | Public | Stable public artifact URLs | Not enabled | | Share | Secret capability-link artifacts | Not enabled |

All four must be distinct, pathless HTTPS origins.

Untrusted artifacts can contain active HTML and JavaScript. Normal artifact views must never share an origin with the owner UI or mutation API: same-origin artifact code could send owner-authorized API requests. The archive's authenticated /preview/assets/** route is a narrow exception whose iframe and response policies force an opaque sandbox, deny network and form actions, and block cross-site or passive browser-resource requests to /api/**. For that reason, general one-origin path multiplexing such as /api, /private, and /share on one hostname is not supported. Paths alone are not a browser security boundary.

Deployment modes

Choose one of these secure topologies:

  1. Account with a domain: deploy one Worker with four custom hostnames, for example owner.example.com, private.example.com, public.example.com, and share.example.com. Wrangler routes with custom_domain: true manage custom-domain DNS and certificates during deployment. Disable the workers.dev and preview URLs so they cannot bypass the hostname policies.
  2. Account without a domain: deploy four distinct Worker names. Their production URLs become four origins such as shlook-owner.<workers-subdomain>.workers.dev, shlook-private.<workers-subdomain>.workers.dev, shlook-public.<workers-subdomain>.workers.dev, and shlook-share.<workers-subdomain>.workers.dev. Enable Access separately on the owner and private workers.dev routes; leave public and share unauthenticated.

All four surfaces use the same D1 database and private R2 bucket. D1 stores metadata and lifecycle state; R2 stores artifact bytes and must not have an r2.dev URL or public custom domain. Apply the packaged D1 migrations before serving traffic.

Every deployed Worker must receive these non-secret variables through its operator-owned Wrangler configuration:

SHLOOK_OWNER_ORIGIN=https://<owner-host>
SHLOOK_PRIVATE_ORIGIN=https://<private-host>
SHLOOK_PUBLIC_ORIGIN=https://<public-host>
SHLOOK_SHARE_ORIGIN=https://<share-host>
SHLOOK_OWNER_EMAIL=<owner-email>

The owner Worker also requires a 32-byte base64 encryption key stored as a Cloudflare Worker secret named SHLOOK_SECRET_ENCRYPTION_KEY. It encrypts recoverable capability URLs at rest; never place it in vars, source control, or agent output.

Set these operator-owned values for every CLI or agent environment:

export SHLOOK_API_ORIGIN="https://<owner-host>"
export SHLOOK_PRIVATE_ORIGIN="https://<private-host>"
export SHLOOK_PUBLIC_ORIGIN="https://<public-host>"
export SHLOOK_SHARE_ORIGIN="https://<share-host>"
export CF_ACCESS_CLIENT_ID="<agent-service-token-client-id>"
export CF_ACCESS_CLIENT_SECRET="<agent-service-token-client-secret>"

Do not rely on package defaults for a self-hosted installation. See skills/shlook/references/setup.md for the manual operator checklist. The packaged shlook setup command does not provision Cloudflare resources, DNS, Worker routes, Access applications, policies, or service tokens.

Publish an artifact

Every new publication has a concise display name and may have a description:

shlook publish ./artifact \
  --name "Owner archive refinement" \
  --description "Responsive archive controls and theme study" \
  --json

Names are required by the current CLI and accept 1-80 characters. Descriptions are optional and accept up to 500 characters. Both are stored in D1, returned by the owner API, and shown and searched in the owner archive. Existing assets are assigned their prior eight-character ID prefix when the metadata migration is applied.

The creation API accepts the same metadata as JSON:

{
  "name": "Owner archive refinement",
  "description": "Responsive archive controls and theme study"
}

Route grammar

  • Owner: /, /archive, /health, and /api/assets...
  • Private: /latest[/<artifact-path>] and /assets/<asset-id>[/<artifact-path>]
  • Public: /assets/<asset-id>[/<artifact-path>]
  • Share: /s/<capability>/assets/<asset-id>[/<artifact-path>]

Unknown routes and artifacts unavailable to the requested audience return 404.

Development

Requirements: Node.js 24 and pnpm 11.17.0.

pnpm install --frozen-lockfile
pnpm fmt
pnpm run ci

Oxlint owns linting and Oxfmt owns formatting. pnpm run ci runs lint, format checking, strict TypeScript checking, tests, and a Wrangler dry-run build.

License

MIT. See LICENSE.