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

@wavegrid/cli

v1.5.0

Published

wavegrid CLI — scaffold a layout config and run an installation (server + receiver, in-process) from a single command

Readme

@wavegrid/cli

The wavegrid command-line tool — create a laser installation as a project in a centralized store, and run it (server + receiver, in-process) from a single command. New physical arrangements are pure configuration: no shape-specific code. The CLI bakes in the server and receiver as dependencies, so a fresh npm i -g @wavegrid/cli is all an operator needs — no monorepo checkout, no pnpm.

Projects, secrets, users, runtime state, and logs live in a per-user store at ~/.wavegrid (via appstash). Set APPSTASH_BASE_DIR to relocate the whole store; the config layer resolves the same way, so the store and config never diverge.

Install

npm i -g @wavegrid/cli
wavegrid projects create      # create a project + generate its secrets
wavegrid projects users add   # add a UI login (prompted)
wavegrid start                # run server + receiver

Run any command group bare (wavegrid, wavegrid projects, wavegrid settings, wavegrid projects users, …) and it prompts an interactive menu of what you can do next; stop short of any required argument and it prompts for that too. With no TTY it prints usage instead of hanging.

Commands

Project management and everything that edits a project live under projects; global store setup lives under settings; start and doctor are top-level.

| Command | Purpose | | --- | --- | | wavegrid projects list | List projects, marking the active one. | | wavegrid projects create [name] | Create a project in the store; generates secrets once; optionally add a first user. | | wavegrid projects use <name> | Set the active project (alias: set). | | wavegrid projects config | Print the resolved config + provenance (secret values masked). | | wavegrid projects config set <k> <v> | Update a project config field without re-creating it or editing JSON. Keys: layout/preset (a built-in preset id), mode (auto/simple/distributed), port, host, ui-port. | | wavegrid projects secrets list | List required secrets and whether each is set (never values). | | wavegrid projects secrets init | Generate any missing secrets (--force rotates). | | wavegrid projects users list | List UI usernames. | | wavegrid projects users add [name] | Add/replace a UI login user (password hashed). | | wavegrid projects users rm <name> | Remove a UI login user. | | wavegrid projects keys ls | List named access keys with role, state and last use. | | wavegrid projects keys new <name> | Mint an access key (passphrase printed once); --admin for an admin key. | | wavegrid projects keys enable\|disable <name> | Turn one key's logins on/off, keeping its passphrase. | | wavegrid projects keys rm <name> | Revoke one key (--all revokes every key). | | wavegrid projects routing show | The project's unified routing spec, plus what each registered device would be given (global slice → local re-base → zones). | | wavegrid projects routing import <file> | Adopt a global routing JSON as the unified spec. Zone numbers are regenerated per device unless --keep-zones pins them as installed. | | wavegrid projects routing generate | Write the per-device routing files (--device <name> for one, --out <dir> to place them). Refuses on shard gaps/overlaps. | | wavegrid projects routing clear | Forget the unified spec. | | wavegrid projects env export | Write a .env for the current project (--file to override). | | wavegrid settings environment | Show the store location + environment (paths, active project, base override). | | wavegrid settings initialize | Create/ensure the global store scaffold. | | wavegrid settings clear | Clear all — wipe every project, secret, user, access key, session, device record, light map and log. Asks you to type clear all; --yes for scripts, --keep-device to keep this machine's identity. Irreversible: secrets are generated once and cannot be recovered. | | wavegrid start | Load the active project and run server + receiver in-process. | | wavegrid doctor | Diagnose this laptop (env hijacks, ports, secrets, users, shard) and — if a server is reachable — the whole installation: connected receivers + shard coverage (gaps/overlaps). --json for scripting, --server ws://host:port to point at a remote server. |

init, config, secrets, users, keys, and env remain as top-level shortcut aliases for the projects … forms. Every command acts on the active project unless you pass --project <name> (or set WAVEGRID_PROJECT).

Secrets & setup are explicit and one-time

Secrets (jwtSecret, receiverKey) are generated only during wavegrid init / wavegrid secrets init, stored 0600 in the project. Runtime never invents or defaults a secret: wavegrid start and the UI fail with an actionable error if a required secret is missing. Re-running init/secrets init preserves existing values unless --force is given.

wavegrid start

Runs the server and receiver together in a single Node process. In simple mode (auto-selected when the cannon count is under the single-laptop threshold) this is the whole installation on one machine — LAN-only, no internet required. In distributed mode it runs the same pair but the receiver shards via the project's receiver.shard (SHARD_START / SHARD_END). The artist UI is a separate app that reads the same store; it is not launched here.

Multi-laptop routing is generated, not hand-written

A show with more than one machine keeps one spec — every cannon in global logical order, with an explicit BEYOND zone base. Each laptop's routing file is derived from it: the shard slice re-bases grid indices to 0 for that machine, and zones restart per machine too. wavegrid receiver regenerates this laptop's file into the project state dir on start, so no config is ever copied between machines, and a config that would light the wrong fixture (shard gap or overlap, duplicate zone, or a device-local file fed back in as global) is refused rather than emitted. See docs/light-indexing.md.

A one-laptop show skips all of it — wavegrid projects osc points straight at BEYOND or FB4.

wavegrid config (or wavegrid --print-config)

Resolves the configuration and prints it with per-key provenance so it is obvious which layer supplied each value (defaults → store → file → env → flags), plus a set/unset status for each required secret. Secret values are never printed.

Configuration

Configuration is discovered by confstash via walk-up search (wavegrid.json, .wavegridrc, package.json keys, …) and layered with environment variables:

| Variable | Maps to | | --- | --- | | WAVEGRID_LAYOUT | layout.preset | | WAVEGRID_MODE | mode (auto | simple | distributed) | | WAVEGRID_SIMPLE_MAX | simpleModeMax | | PORT / SIM_PORT | server.port | | HOST | server.host | | UI_PORT | ui.port |

Example wavegrid.json

{
  "layout": { "preset": "ring-6" },
  "mode": "auto",
  "simpleModeMax": 40,
  "server": { "host": "0.0.0.0", "port": 3000 },
  "ui": { "port": 3003 }
}

Built-in presets: grid-7x7, grid-7x2, ring-6, ring-25-filled.