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

@webmate-studio/cli

v0.5.0

Published

Webmate Studio CLI - Build and manage your Webmate components

Readme

@webmate-studio/cli

Command-line tool for Webmate Studio component development and synchronisation.

npm install -g @webmate-studio/cli

Command overview

| Command | Purpose | |---|---| | wm init [dir] | Bootstrap a new component project | | wm generate [type] [name] | Scaffold a new component or island | | wm dev | Run the local preview server | | wm install | Install npm deps in the project and per-component package.jsons | | wm login / wm logout / wm whoami | CLI authentication | | wm components ls | List the components of the current website | | wm versions [component] | List published versions of a component | | wm status [dir] | Sync state — one component, or the whole workspace | | wm diff [dir] | What changed locally, line by line | | wm pull [dir] | Download a component version from the CMS | | wm push [dir] | Upload local changes as a new version | | wm stash | Park local changes without pushing (shared with the preview UI) | | wm reset [dir] | Unlink components after copying them into another workspace | | wm recovery [dir] | List or restore the safety snapshots taken before overwrites | | wm doctor [dir] | Check the workspace setup for common problems | | wm build [dir] | Run the cloud build locally to validate before pushing |

wm status, wm push --all and wm pull --all work across a whole workspace; everything else takes one component.

Cloning moved into the CMS component library (gallery → clone, also across websites in one organisation). Bring the copy down with wm pull --id <uuid>.

Exit codes

Scriptable, so a pipeline does not have to parse output.

| Code | Meaning | |---|---| | 0 | Success — and for wm status, nothing needs a decision | | 1 | Command failed, or wm status/wm doctor found something to act on | | 2 | Usage problem: bad flag, or a confirmation is needed with no TTY | | 3 | wm pull --strategy merge wrote conflict markers that need resolving | | 130 | Cancelled with Ctrl-C |

Authentication

Most sync commands require a Webmate session. The CLI looks for credentials in this order:

  1. WEBMATE_TOKEN environment variable (with optional WEBMATE_BASE_URL)
  2. ~/.webmate/auth.json (created by wm login)
  3. .webmate/config.json in the current workspace (with apiToken)

wm login itself resolves the target baseUrl in this order:

  1. --base-url flag
  2. WEBMATE_BASE_URL environment variable
  3. baseUrl field in the nearest .webmate/config.json (workspace default)
  4. The built-in default

A workspace-level .webmate/config.json with just { "baseUrl": "https://app.webmate-studio.com" } is enough to pin all subsequent wm login calls in that directory to the right environment.

Interactive login (recommended)

wm login

Opens your browser at the active Webmate instance, shows a verification code, and waits while you click Authorize. The resulting token is saved to ~/.webmate/auth.json with 0600 permissions.

wm login --base-url https://app.webmate-studio.io   # switch environment
wm login --force                                     # overwrite an existing session

Non-interactive (CI/CD)

export WEBMATE_TOKEN="wms_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxx"
export WEBMATE_BASE_URL="https://app.webmate-studio.io"
wm push ./my-hero

Create tokens under Settings → API Tokens in the CMS.

The sync workflow

A typical component lifecycle:

# Start from an existing component
wm components ls                          # find the UUID you want
wm pull ./my-hero --id <uuid>             # download it
# … edit files …
wm status                                 # see what changed
wm push                                   # publish a new version

Or from scratch:

wm init my-components
cd my-components
wm generate my-hero                       # scaffolds component.json with a fresh UUID
wm dev                                    # iterate locally
wm push --force                           # first push needs --force (no baseVersion yet)

.webmate.json — local manifest

After wm pull or wm push the CLI writes a .webmate.json next to your component:

{
  "componentId": "f97e376c-f8bd-42e4-9b9a-c2d62d4dcc9a",
  "baseVersion": "cmn7b9r7p00014i013dk007hw",
  "version": "1.0.5",
  "pulledAt": "2026-05-20T18:31:46.791Z",
  "fileHashes": {
    "component.html": "c2689e…",
    "component.json": "088e8d…"
  }
}

The CLI uses baseVersion for optimistic locking on push and fileHashes for change detection. The Workbench desktop app shares the same file format.

Conflict handling

wm push checks the remote head before uploading. If the remote moved since your last pull, the push is refused:

[ERROR] Remote moved: your baseVersion is cmABC… but remote latest is cmDEF… (1.0.6).
  Run wm pull first, then push again.

Resolve by pulling, merging locally, and pushing again.

wm pull warns about uncommitted local changes and prompts before overwriting, unless --force is given.

Git snapshot

If the component directory is a git repo, wm pull and wm push automatically git add . && git commit a snapshot of the synced state. This is purely a local backup — nothing is pushed to a remote. Disable with --no-git.

Commands

wm login

wm login [--token <wms_...>] [--base-url <url>] [-f|--force]

Default flow opens the browser and waits for a verification click — no copy/paste needed. With --token it accepts a pre-generated token directly (useful when scripting or behind firewalls).

wm whoami

wm whoami [--local]

Shows the active token source, base URL, user, and organisation. --local skips the /api/auth/me round-trip.

wm components ls

wm components ls [--category <cat>] [--search <q>]

Lists the components of the website this workspace targets. Components live per website, so there is no organisation-wide list. --category and --search are substring filters over the returned list.

wm versions [component]

wm versions [<uuid> | <dir>] [--limit <n>]

Lists all published versions, newest first. The positional argument can be a UUID, a directory containing component.json or .webmate.json, or omitted to use the current directory.

wm status [component]

wm status [<dir>] [--offline]

In a component folder, the detailed view. In a workspace root (a folder with a components/ subfolder), one row per component with a summary — which is how you answer "is there anything to push?" without visiting every folder.

States:

  • in sync — local files match the manifest, and the manifest matches what the CMS serves
  • local changes — edits that have not been pushed
  • newer in CMS — the CMS moved past your baseVersion
  • local + CMS changed — both sides moved; may still merge cleanly
  • not pushed yet — the CMS has never seen this component
  • local only (gone in CMS) — it was deleted there
  • not linked — no .webmate.json yet

--offline skips the network call and only reports the local diff. Exit code is 0 when nothing needs a decision, 1 otherwise.

wm pull [component]

wm pull [<dir>] [--id <uuid>] [--version <ver|cuid|latest>]
                [--strategy replace|merge|keep-extra] [--force] [--no-git]

Downloads the source bundle of the requested version and rewrites .webmate.json. Defaults to latest.

| --strategy | Effect | |---|---| | replace (default) | The folder ends up matching the CMS version 1:1 | | merge | 3-way merge; lines both sides changed get <<<<<<< markers, everything else resolves silently | | keep-extra | Like replace, but files the CMS version does not contain stay |

With local changes and no strategy given, the CLI asks. After a merge that left markers, wm status keeps reporting local changes and the exit code is 3 — resolve the markers, then push.

--merge used to mean keep-extra while the preview UI used "merge" for the 3-way merge, so the same word meant opposite things and the CLI one discarded local edits. The flag now errors and names both successors.

wm push [component]

wm push [<dir>] [-m|--message <msg>] [--force] [--no-git]
wm push --all [--dry-run] [-y|--yes] [-m <msg>]

Uploads the current file tree as a new patch version. The server bumps SemVer automatically (e.g. 1.0.5 → 1.0.6). The CLI:

  • runs a pre-flight GET /versions to detect a moved remote and refuses to upload on mismatch
  • skips uploads when nothing changed since the last pull/push (override with --force)
  • treats HTTP 409 as a late-conflict signal and HTTP 422 as a build failure

wm diff [component]

wm diff [<dir>] [--stat] [--path <file>] [--version <ver>]
                [--context <n>] [--no-color]

Line-by-line changes against the version the workspace last pulled — the same baseline push locks against, so the diff is what a push would send. --version compares against any published version instead.

wm stash

wm stash                              list backups for this component
wm stash save   [-m <msg>] [--name <name>] [--force]
wm stash apply  [<id>] [--keep] [--force] [-y]
wm stash drop   <id> [-y]

Named local backups, stored under <workspace>/.webmate/stash/. The preview UI calls them "Sicherungen" and reads the same store, so a backup made in either place shows up in both.

apply defaults to the newest and accepts a list number, an id, an id prefix or a name. It takes a recovery point first and refuses over uncommitted work without --force; the backup is consumed unless you pass --keep.

Distinct from wm recovery: recovery points are written automatically before something destructive and live on git refs. Stashes are deliberate, named, and work without git.

Batch operations

wm status                             every component, one row each
wm push --all [--dry-run] [-y]        everything with local changes
wm pull --all [--dry-run] [-y] [--strategy merge]

Run from a workspace root. Both scan first, print what they intend to touch and ask. Components that need a decision are skipped and named rather than guessed at — a diverged component is neither pushed (it would overwrite the CMS) nor pulled (it would overwrite local work) unless --strategy merge says how.

Cloning

wm clone is gone. It was built on the organisation-component API, which the CMS removed when components moved to living per website.

Clone in the CMS component library instead — gallery → clone, including across websites in the same organisation. The CMS mints a fresh UUID and rebuilds the artefacts. Then bring the copy down:

wm pull --id <new-uuid>

Where things live

  • Token store: ~/.webmate/auth.json (chmod 0600)
  • Workspace org config: <your-apps-root>/.webmate/config.json
  • Per-component manifest: <component>/.webmate.json

Troubleshooting

Not logged in. → Run wm login, or check WEBMATE_TOKEN is set.

Remote moved: your baseVersion is … → Someone else (or the Workbench, or another machine) pushed a new version. Run wm pull to re-sync, resolve any conflicts, then wm push again.

Build failed (HTTP 422) → The build service rejected the artifact. Check the server logs in the CMS for details; common causes are island files that fail to bundle or invalid component.json.

Token rejected (HTTP 401) → The token has been revoked or expired. Run wm login --force to refresh it.

No .webmate.json found (wm push) → The directory has not been linked to a component yet. Either run wm pull --id <uuid> first, or push with --force to skip the safety check (useful right after wm generate).