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

whistle-cli

v0.1.6

Published

AI-friendly CLI facade over Whistle

Downloads

979

Readme

whistle-cli

AI-friendly CLI facade over Whistle.

Prerequisites

  • Node.js >= 20
  • whistle installed (npm install -g whistle) so w2 is available on PATH

Install

# Install from npm (global)
npm i -g whistle-cli --registry=https://registry.npmjs.org/

# Upgrade
npm i -g whistle-cli@latest --registry=https://registry.npmjs.org/

# This repository (dev mode)
npm install
npm run dev -- --help

Quick Start

# Check command surface in dev mode
npm run dev -- --help

# Check Whistle availability
npm run dev -- raw w2 status

# Structured JSON output (default)
npm run dev -- --format json instance status

# Human-readable output
npm run dev -- --format pretty instance status

Skill (for AI agents)

Install from the public GitHub repository with a compatible skills installer:

skills add https://github.com/maxjchuang/whistle-cli --skill whistle-cli

Install the repository-distributed skill into the default skills directory:

./scripts/install-skill.sh

Command Structure

whistle-cli provides three layers of commands:

| Layer | Purpose | Example | | ------------ | ------------------------------------------------ | ----------------------------------------- | | raw | Escape hatch, passthrough to w2 | whistle-cli raw w2 status | | resource | Stable resource operations, preferred for agents | whistle-cli rules patch --preview | | shortcut | High-frequency intent-driven commands | whistle-cli rule set-header --match ... |

Resource Commands (v1 target)

  • instance — start / stop / restart / status / list / select
  • rules — rollback / patch / import / export / apply / verify / list / get / enable / disable
  • values — rollback / list / get / set / remove / import / export
  • captures — find / get / tail / diff / export
  • composer — replay / compose
  • frames — list / send
  • runtime — serve the optional __whistle_cli__ backend API
  • certs — status / install / verify / guide
  • proxy — status / set / off / verify
  • plugins — list / install / uninstall / enable / disable / inspect
  • doctor — instance-status / proxy-routing / https-capture
  • raw — w2 passthrough

Shortcut Commands

  • bootstrapstart / prepare
  • ruleset-header / map-local
  • capturefind / find-error
  • plugininstall / remove / inspect / invoke (invoke is out of scope in v1)

Global Flags

| Flag | Description | | ---------------------------------------- | --------------------------------------- | | --format <json\|pretty\|table\|ndjson> | Output format, default json | | --instance <id> | Target instance, defaults to current | | --non-interactive | Fail instead of waiting for user action |

--preview, --apply, --verify, and --rollback are command-level flags on mutating resource commands (not global flags).

Common rollback forms:

  • rules rollback --action-id <id>
  • values rollback --action-id <id>
  • proxy set --rollback <id>
  • plugins install --rollback <id>

Output Envelope

All output is a structured JSON envelope designed for machine parsing:

{
  "status": "ok | warning | error | blocked",
  "resource": "raw | instance | rules | values | captures | composer | frames | runtime | certs | proxy | plugins | doctor",
  "action": "w2 status",
  "data": {},
  "error": {
    "code": "INSTANCE_NOT_RUNNING",
    "message": "...",
    "reason": "...",
    "suggested_fix": "..."
  },
  "next_actions": [{ "action": "...", "reason": "..." }],
  "effective": true
}

Reading the Envelope

  • status — success / failure decision
  • error.code — stable machine-readable error classification
  • next_actions — suggested next steps (agent doesn't need to guess)
  • effective — whether a mutation is actually live at runtime

Error Codes

| Code | Meaning | | ------------------------------- | ------------------------------------- | | INSTANCE_NOT_RUNNING | Whistle instance is not running | | INSTANCE_PORT_CONFLICT | Port already in use | | CERT_NOT_INSTALLED | CA certificate not installed | | CERT_NOT_TRUSTED | CA certificate not trusted by system | | PROXY_NOT_ACTIVE | System proxy not pointing to Whistle | | RULE_CONFLICT | Conflicting rules detected | | RULE_VERIFY_FAILED | Rule verification failed | | NO_CAPTURE_MATCH | No captured traffic matched the query | | CAPTURE_BACKEND_UNAVAILABLE | Capture backend not accessible | | PLUGIN_NOT_INSTALLED | Plugin not installed | | PLUGIN_CAPABILITY_UNAVAILABLE | Plugin capability not available | | PERMISSION_REQUIRED | Insufficient permissions | | USER_ACTION_REQUIRED | Manual user action needed | | UNSUPPORTED_OPERATION | Operation not supported |

Agent Integration

Typical Workflow

1. Environment check
   whistle-cli --format json instance status

2. Start instance
   whistle-cli --format json instance start

3. Safe mutation (preview -> apply -> verify)
   whistle-cli rules patch --id main --file ./patch.txt --format json
   whistle-cli rules apply --id main --file ./patch.txt --apply --verify --format json

4. Diagnose issues
   whistle-cli --format json captures find --host api.example.com
   whistle-cli --format json doctor https-capture

5. Handle blocked/error states
   -> Read error.suggested_fix and inform user
   -> Read next_actions for next step

Runtime Backend

whistle-cli includes an optional local runtime backend that serves the __whistle_cli__ API consumed by --backend runtime commands.

# Start a backend in front of a running Whistle Web API
whistle-cli --format json runtime serve \
  --target-url http://127.0.0.1:8899 \
  --host 127.0.0.1 \
  --port 8898

# In another shell, route RuntimeClient calls to it
export WHISTLE_CLI_RUNTIME_URL=http://127.0.0.1:8898

whistle-cli --format json captures find --backend runtime --host example.com
whistle-cli --format ndjson captures tail --backend runtime --host example.com --limit 5
whistle-cli --format json composer compose --method GET --url https://example.com --apply

The runtime backend currently adapts capture data from Whistle's Web API and executes compose/replay with local HTTP requests. Frame routes return UNSUPPORTED_OPERATION until frame-level backend support is implemented.

Whistle Web Capture Retrieval

For browser-driven automation, prefer Whistle Web capture retrieval when the capture was detected with --backend whistle-web:

# Wait for a newly triggered request and keep only a redacted summary in the result
whistle-cli --format json captures assert-request \
  --backend whistle-web \
  --host app.example.com \
  --path /api/ \
  --timeout 90s \
  --poll-interval 2s \
  --fields capture_id,method,status_code,path,referer

Safe Header Handoff

When an agent needs authenticated request headers for a follow-up command, prefer capture-headers so values are written to local files and not printed to stdout:

whistle-cli --format json captures capture-headers \
  --backend whistle-web \
  --host app.example.com \
  --path /api/session \
  --headers cookie,x-csrftoken,x-signature-key \
  --timeout 120s \
  --save-env .devops-headers.env

By default, the command ignores captures that were already present when it started. Use --allow-existing only when reusing a recent matching request is intended. Use --env-map cookie=DEVOPS_COOKIE to override generated env keys such as COOKIE or X_SIGNATURE_KEY.

The command fails unless --save-env or --save-json is provided. Its JSON output reports capture metadata and header presence only; it does not include header values.

# Retrieve the exact capture while it is still in the Whistle Web data window
whistle-cli --format json captures get \
  --backend whistle-web \
  --id <capture_id>

# Extract one request header from the exact capture
whistle-cli --format json captures get-header \
  --backend whistle-web \
  --id <capture_id> \
  --header cookie

# Export filtered Whistle Web captures as JSON
whistle-cli --format json captures export \
  --backend whistle-web \
  --host app.example.com \
  --path /api/ \
  --export-format json

assert-request remains redacted by default for safe agent-facing reporting. Explicit retrieval commands such as get, export, and get-header return captured request header values requested by the user, so avoid logging their output when headers contain credentials.

For continuous human-facing monitoring, use captures watch --watch with NDJSON output:

whistle-cli --format ndjson captures watch \
  --backend whistle-web \
  --host app.example.com \
  --path /api/ \
  --fields capture_id,method,status_code,path,x_tt_logid,request_id,referer \
  --watch

--watch keeps the process running until Ctrl-C or SIGTERM. It performs process-local in-memory de-duplication from the startup baseline and does not persist history across restarts. It still reads Whistle Web's recent capture window, so high-volume traffic can rotate old records out before they are observed.

For a single exact header, get-header remains available. Add --redact, --save-env, --save-json, or --save-value when the value should not appear in stdout.

If direct Whistle Web API fallback is unavoidable, use dumpCount to widen the returned session window, for example: /cgi-bin/get-data?startTime=0&dumpCount=1000.

Error Handling Pattern

result = run("whistle-cli rules patch --apply")

if result.status == "error":
    match result.error.code:
        case "INSTANCE_NOT_RUNNING":
            run("whistle-cli instance start")
            # retry
        case "CERT_NOT_TRUSTED":
            tell_user(result.error.suggested_fix)
        case "PROXY_NOT_ACTIVE":
            run("whistle-cli proxy set")
        case _:
            tell_user(result.error.message)

elif result.status == "blocked":
    tell_user(result.next_actions)

elif result.status == "warning":
    log(result.warnings)

Development

# Build
npm run build

# Dev mode (tsx)
npm run dev -- raw w2 status

# Built binary
node dist/cli/index.js --help

# Test
npm run test

# Lint
npm run lint

Implementation Status

| Command | Status | | --------------- | --------- | | raw w2 [args] | Available | | instance/* | Available | | rules/* | Available | | values/* | Available | | captures/* | Available | | composer/* | Available | | frames/* | Available | | runtime serve | Available | | certs/* | Available | | proxy/* | Available | | plugins/* | Available | | doctor/* | Available | | shortcuts/* | Available |

Current Limitations (v1)

  • captures diff exists in command surface but currently returns UNSUPPORTED_OPERATION.
  • captures tail requires --format ndjson.
  • Runtime backend frame routes return UNSUPPORTED_OPERATION; capture and composer runtime routes are implemented.
  • Certificate trust and some proxy setup steps may return blocked or USER_ACTION_REQUIRED and require manual OS actions.

License

MIT