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

@ddcn/cwcli

v0.1.3

Published

Work on your Cloudways WordPress sites locally with one command.

Readme

Cloudways WP Local CLI

Work on your Cloudways WordPress sites locally with one command.

  • Authenticate to Cloudways
  • List servers and apps
  • Create clones on Cloudways
  • Pull files + DB from Cloudways
  • Spin up locally with Docker (Nginx, PHP-FPM, MariaDB, WP-CLI)
  • Optionally push back to Cloudways

Quick Install (npm)

# Global install (scoped)
npm install -g @ddcn/cwcli

# Verify
cwl --help

Notes:

  • The command is cwl (primary). An alias cwcli is also available.
  • Default sites root is your current working directory. Override with CWL_SITES_ROOT.

Authentication

You can authenticate interactively or via environment variables.

# Interactive re-auth (prompts for email + API key)
cwl auth

# View current auth status (email, storage method, token validity)
cwl auth status

# Logout (clears stored email/key/token)
cwl auth logout

Environment variables override stored values when set (useful for CI or temporary sessions):

export CW_EMAIL="[email protected]"
export CW_API_KEY="<your-api-key>"

Sites root override:

export CWL_SITES_ROOT=/absolute/path/to/sites

Easiest Path (Single Command)

# Authenticate once (email + API key)
cwl auth

# One-step: pick the app → pull → start Docker → import DB → open admin (logged-in)
cwl quick

The first run asks you to pick the Cloudways app. It creates the site under your current directory as ./<slug> and opens http://localhost:8080 (or the port shown in the site’s .env).

Tip: need speed? Pull live (read-only) to skip server-side cloning:

cwl quick --live

Simple Workflow (Explicit Steps)

# 0) Check prerequisites (Docker Desktop, rsync, ssh)
cwl doctor

# 1) Authenticate (stores Cloudways API credentials)
cwl auth

# 2) List apps (find an APP_ID; try --sort name or --server <ID>)
cwl apps

# 3) Pull a site (creates ./<slug> in your current directory; omit --app to pick interactively)
cwl pull --app <APP_ID>
# Faster read-only from live (skips clone; exports live DB safely):
# cwl pull --app <PROD_APP_ID> --live

# 4) Start containers (Nginx, PHP-FPM, MariaDB, WP-CLI)
cwl up <site-name-or-path>

# 5) Import DB and rewrite URLs to http://localhost:<port> (from .env)
cwl db import <site-name-or-path>

# 6) Open in browser (add --admin to auto-login to /wp-admin/)
cwl open <site-name-or-path>

Usage

  • Global help: cwl --help (See README.md for full usage instructions)
  • Per-command help: cwl <command> --help
  • Common options used across commands:
    • --dir <dir> (deprecated): Explicit path to the site folder. Prefer positional site name or path.
    • --port <port>: Local HTTP port (defaults to 8080 if not set in .env).
    • --yes: Assume “yes” for prompts where supported.
    • --live: Pull directly from the live app (read-only), where supported.

Site Folder Layout

After pulling or running quick/init, each site lives under your current directory as ./<slug> and contains:

  • wp/: WordPress files (public_html from Cloudways).
  • .cw/: CLI artifacts like db.sql[.gz], nginx.conf, meta.json, temp files.
  • docker-compose.yml: Nginx + PHP-FPM + MariaDB + WP-CLI setup.
  • .env: Values like WP_PORT, SITE_SLUG, DB_NAME.

You can run all cwl commands from anywhere using a positional site argument. If you pass a bare name, it resolves to ./<name> under your current directory (or under CWL_SITES_ROOT if set). You can also pass an explicit path. The legacy --dir still works but is deprecated.

Sites root:

  • Default is your current working directory.
  • Override with CWL_SITES_ROOT:
export CWL_SITES_ROOT=/absolute/path/to/sites

Command Reference + Examples

cwl quick

End-to-end: pull → up → import DB → open /wp-admin/ with auto-login.

# Let me pick an app interactively, use defaults
cwl quick

# Target a specific app, custom port, and auto-login as a user
cwl quick --app 123456 --port 8085 --user admin

# Fast read-only pull from live
cwl quick --live

# Filter list by server when prompting
cwl quick --server 7890

cwl auth

Authenticate with Cloudways API. Credentials are stored securely when possible.

cwl auth
cwl auth --email [email protected] --key <API_KEY>
# Clear stored credentials
cwl auth --clear

cwl servers and cwl apps

cwl servers
cwl apps
cwl apps --sort name           # A→Z by app label
cwl apps --server 12345        # Filter to a specific server

cwl pull

Pull files + DB for an app and scaffold Docker locally.

# Prompt to pick an app, create ./<slug>
cwl pull

# Explicit app and directory with custom port
cwl pull --app 123456 --dir ./my-site --port 8082

# Pull directly from live (read-only; exports live DB)
cwl pull --app 123456 --live --yes

# Use a single tar.gz stream (faster when master SSH is available)
cwl pull --app 123456 --archive

cwl up / cwl down / cwl status

cwl up my-site           # Start containers (resolves to ./my-site)
cwl up my-site --port 8090  # Change the local port and restart
cwl status my-site       # Show URL and docker compose ps
cwl down my-site         # Stop containers
# Explicit paths still work
cwl up ./my-site
cwl status ./my-site
cwl down ./my-site

cwl sites

List local sites under the default sites root. A directory is considered a site if it contains markers like docker-compose.yml, .cw/, or wp/.

cwl sites

cwl db import

Import .cw/db.sql[.gz] into the local DB and rewrite URLs to your local host/port.

cwl db import my-site

cwl open and cwl admin

Open the local site or /wp-admin/ with an auto-login token. You can specify a username and token TTL.

cwl open my-site
cwl open my-site --admin --user editor --ttl 600

# Directly open /wp-admin/ auto-logged-in
cwl admin my-site --user admin --ttl 600

cwl login

Generate a one-click login URL for the local site; print or open it.

cwl login my-site --user admin --ttl 600 --print

cwl push

Push local wp/ and DB to a new or existing Cloudways app. The CLI will not push to your original live app; if the target equals the source (or pull was from live), a new clone is created automatically.

# Create a new clone automatically and push
cwl push my-site

# Push to an existing target app
cwl push my-site --to-app 222222

# Create with a custom label, then push
cwl push my-site --new-label staging-2025-09-12

# Files only or DB only
cwl push my-site --files-only
cwl push my-site --db-only

Deleting local sites

Delete one site (stops Docker and removes volumes, including DB data), then removes the folder:

cwl rm my-site            # prompts for confirmation
cwl rm my-site --yes      # skip confirmation

Delete all sites under the sites root. This stops Docker for each site, prunes volumes, and deletes the folders:

cwl rm-all                # prompts for confirmation
cwl rm-all --yes          # skip confirmation

cwl ssh

Test SSH/SFTP connectivity for an app/server. Helpful for diagnosing rsync/SSH issues.

cwl ssh            # pick an app
cwl ssh --app 123456

cwl info

Prints raw Cloudways server/app info for debugging.

cwl info               # servers overview
cwl info --app 123456  # details + credentials payloads (redacted upstream)

Requirements

  • macOS with Docker Desktop
  • Node.js 18+
  • SSH access to the Cloudways application user (password or SSH key). The CLI fetches the credentials via API.

How it works

  • Auth: Exchanges your email + API key for a short-lived token; stored securely.
  • Pull: Uses API to resolve SFTP/MySQL creds, rsyncs public_html to ./wp, dumps the DB to .cw/db.sql.
  • Local run: Generates docker-compose.yml and wp-config.php, starts Nginx/PHP/MariaDB/WP-CLI.
  • DB import: Loads .cw/db.sql into MariaDB and rewrites the site URL to http://localhost:<port>.
  • Push: Never pushes to live. If the target is missing or equals the source (or your pull was from live), the CLI auto-creates a new clone on Cloudways and pushes there. It then runs a serialized-safe URL rewrite to the target domain.

Deauth/Reauth

  • Reauth with new credentials: cwl auth and provide a different email/API key.
  • Deauth fully: cwl auth logout (clears stored credentials and cached token).
  • Inspect current state: cwl auth status.
  • Env override: CW_EMAIL and CW_API_KEY take precedence over stored values.

Troubleshooting

  • If rsync asks for a password and fails, install sshpass (or copy your SSH key to the app user).
  • Start Docker Desktop before running cwl up or cwl quick.
  • Re-auth with cwl auth --clear then cwl auth.

Redis object cache drop-in locally

If your pulled site includes a persistent object cache drop-in (e.g., wp/wp-content/object-cache.php from Redis Object Cache or Object Cache Pro), WordPress may attempt to connect to a Redis server that isn’t present in the local Docker stack.

What we do by default:

  • The CLI writes wp/wp-config-local.php with:
    • define('WP_CACHE', false);
    • define('WP_REDIS_DISABLED', true); These ensure the drop-in stays inactive locally.

If you still see a Redis connection error:

  1. Confirm the defines exist in wp/wp-config-local.php.
  2. Stop and restart containers: cwl down my-site && cwl up my-site.
  3. Optionally delete/rename the drop-in: mv wp/wp-content/object-cache.php wp/wp-content/object-cache.php.bak.

Live pull vs. clone

  • --live always pulls read-only from your production app and exports the live DB. This is fastest and safest when you only need a local copy.
  • Without --live, the CLI can clone your source app on Cloudways first to avoid touching production during pull/push workflows.

Docker folder permissions

  • Symptom: "operation not permitted" or "mount source path ... permission denied" when starting containers.
  • Fix: Allow Docker to access your project folder, then retry cwl quick (or docker compose up -d in the site dir).
  • macOS: System Settings → Privacy & Security → Files and Folders → Docker: enable access for the folder (e.g., Desktop/Documents). Or Docker Desktop → Settings → Resources → File sharing → add your project path → Apply & Restart.
  • Windows: Docker Desktop → Settings → Resources → File Sharing → add your project path → Apply & Restart. If using WSL2: Settings → Resources → WSL Integration → enable your distro.
  • Linux: Ensure your user owns the project directory and has rw permissions. If SELinux is enabled, add :Z to volume mounts (e.g., ./wp:/var/www/html:Z) or run sudo chcon -Rt svirt_sandbox_file_t /path/to/project.

From Source (Contributors)

git clone https://github.com/drewclifton/cwcli.git
cd cwcli
npm install
npm run start -- --help

Publishing (Maintainers)

Two options: GitHub Releases (CI) or manual CLI.

  1. GitHub Releases (CI)
  • Add a repo secret NPM_TOKEN with publish rights.
  • Bump version and push tag:
    npm version patch -m "Release %s"
    git push origin HEAD --follow-tags
  • Create a GitHub Release for the new tag. The workflow publishes to npm.
  1. Manual CLI
npm login
npm publish --access public