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

@salience/lens-cli

v2.1.8

Published

Salience CLI — server-log intelligence (search crawlers, AI agents, threats, site health) from your terminal

Readme

Salience CLI

Server-log intelligence from your terminal: search crawlers, AI agents, threats and site health, straight from the same logs the Salience dashboard reads.

Install

npm install -g @salience/lens-cli
# or
pnpm add -g @salience/lens-cli

Requires Node.js 18+.

Upgrading from @loglens/cli

@salience/lens-cli is the same tool under its new name. The command is now salience (loglens still works as an alias for this major version). Config moves from ~/.loglens to ~/.salience automatically on first run, and the LOGLENS_* environment variables are still read as fallbacks for SALIENCE_API_KEY, SALIENCE_API_URL and SALIENCE_WEBSITE. The default API host is now api.salience.com; api.loglens.ai keeps working.

npm uninstall -g @loglens/cli && npm install -g @salience/lens-cli

Give your coding agent the Salience skill

CLI 2.1.0+ bundles a versioned skill with bounded investigation workflows, command guidance and evidence limitations. Installing the npm package alone does not register the skill with your agent.

From your project root, choose your client:

# Codex
salience skills install .agents/skills/salience-cli

# Claude Code
salience skills install .claude/skills/salience-cli

The destination is the complete new skill directory. Installation copies the skill and its references locally; it refuses existing files/directories and never edits AGENTS.md or CLAUDE.md. For updates, install to a temporary new directory, compare with your installed copy, then replace it deliberately, preserving local changes. Updating npm does not update a copied skill.

Start a new agent session in that project. In Codex, confirm salience-cli appears in /skills or the skill picker and invoke $salience-cli. In Claude Code, confirm /salience-cli appears and invoke it. Ask: “Use the Salience CLI skill to check crawler activity on example.com over the last 24 hours. Start with a small read-only investigation.” Your client must have shell access to salience and separately supplied API credentials; skill discovery does not prove API access.

For installation across projects, pass "$HOME/.agents/skills/salience-cli" (Codex) or "$HOME/.claude/skills/salience-cli" (Claude Code). Choose project or personal installation to avoid duplicate skill names. Client discovery conventions: Codex skills, Claude Code skills. Local skill loading can be restricted by client or organization settings.

For other clients, salience skills path prints the bundled skill directory without fetching documentation. Use the client's documented skill mechanism, or explicitly ask it to read that directory's SKILL.md and relevant references. Do not assume every agent automatically reads AGENTS.md, CLAUDE.md or an npm package's contents.

Authenticate

salience config set-key llapi_xxxxxxxxxxxxxxxx
salience config set-website 23955f93-02cf-4728-b4d2-8022c4a2cc82

API keys are managed under Organization → API Access at app.salience.com/organization/settings?tab=api. Once a default website is set you can omit -w on every subsequent command. Config is stored at ~/.salience/config.json.

salience config show         # print current config (key redacted)
salience config set-url <u>  # override API URL (default: https://api.salience.com)

Commands

Every command that reads a website takes -w <id> (omit it once a default website is set). Unless noted, commands also accept --json and --csv. Time-windowed commands take -h <hours> (default 24 unless shown) and, where marked with --start/--end, an explicit ISO 8601 range instead.

--segment <id> (a saved segment id from salience segments) is accepted by llms, ai-funnel, ai-landing, crawl-report, crawl-audit, crawl-links and url, and filters their log-derived figures to that group of pages. segment-breakdown takes --segments <ids> (comma-separated) instead. Options differ by command; check salience <command> --help.

Config and account

| Command | Description | |---|---| | salience config set-key <apiKey> | Save your Salience API key | | salience config set-website <websiteId> | Set the default website ID (skip -w) | | salience config set-url <url> | Set a custom API URL (default https://api.salience.com) | | salience config show | Print current config (key redacted) | | salience websites | List every website on your account |

$ loglens websites
ID                                    Domain                      Name
────────────────────────────────────  ──────────────────────────  ─────────────
23955f93-02cf-4728-b4d2-8022c4a2cc82  keywordspeopleuse.com       KPU
8c1e09a3-7720-4f01-9921-bb35a0a17f24  example.com                 Example

Traffic analytics

All of these accept -h, --start, --end (except ip-requests and live, which take no --start/--end).

| Command | Description | |---|---| | salience summary | Headline metrics (requests, unique IPs, bot share, error rate) | | salience traffic | Time-series traffic buckets (--interval is sent but not currently applied by the public API) | | salience bots [--split-variants] | Bot/crawler breakdown with verification status; --split-variants shows Googlebot Desktop vs Smartphone | | salience bots-access [--only mixed] | Served vs rejected per bot: status codes used, whether the real bot or impersonators are turned away, and the paths | | salience paths | Top URL paths | | salience geography | Requests by country | | salience status-codes | HTTP status code distribution | | salience ips | Top client IPs | | salience ip-requests --ip <addr> [--page N] [--page-size N] | Per-IP request log (paginated) | | salience requests [filters…] | Raw request-level log (the Log Explorer). Filters, all optional and combinable: --bot-name <name>, --bots-only, --humans-only, --verified true\|false (false = possible impersonation), --ip <addr>, --path <substring>, --status <code>, --status-class 2xx\|3xx\|4xx\|5xx, --method <verb>, --host <hostname>, --country <cc>, --user-agent <substring>. Paging: --limit <n> (default 100, max 500), --cursor <token> from the previous call, or --page <n> on archive-backed sites | | salience referrers | Top referrers | | salience devices | Device type breakdown | | salience live [--type all\|bots\|human\|errors] | Real-time request feed (most recent requests) |

$ loglens bots -h 168
Bot                Requests   Category    Verified
─────────────────  ─────────  ──────────  ──────────
Googlebot            142,318  search      verified
GPTBot                38,221  ai          verified
ClaudeBot             12,907  ai          verified
bingbot                9,144  search      verified
PerplexityBot          4,012  ai          unverified

SEO and crawl (salience seo …)

Time-windowed seo subcommands accept -h <hours> and --bot <name> (e.g. googlebot). Paginated ones accept --page and --page-size (default 50).

| Command | Description | |---|---| | salience seo overview | Crawler analytics summary | | salience seo sitemap [--status never_crawled\|recently_crawled\|stale\|not_in_sitemap] [--sort <col>] [--sort-dir asc\|desc] | Sitemap coverage by URL (paginated) | | salience seo budget-urls [--dir /blog] | Crawl budget per URL within a directory (default /, paginated) | | salience seo url-patterns [--min-urls 3] | Auto-detected URL patterns and crawl frequency (-h defaults to 168) | | salience seo path-explorer | Hierarchical directory tree of crawled paths | | salience seo status-consistency [--min-requests 3] | URLs returning inconsistent status codes | | salience seo requests [--filter all\|errors\|redirects\|slow] | Raw crawler request log (paginated) | | salience seo robots | Robots.txt fetch and disallow analysis | | salience seo url-history --url /blog/post | Crawl history for one URL (-h defaults to 168, paginated) | | salience seo index-coverage | Google index coverage summary: Googlebot crawl recency (last 30 days) × last stored URL Inspection result | | salience seo index-urls --bucket crawled_indexed\|crawled_not_indexed\|not_crawled_indexed\|not_crawled_not_indexed\|pending_inspection | URLs in one coverage bucket (paginated), each with inspected_url, inspected_at, inspection_verdict and google_canonical. pending_inspection = no stored indexed/not_indexed result, including never inspected | | salience seo events | Site events / annotations |

$ loglens seo url-patterns --bot googlebot -h 168
Pattern                       URLs   Requests  % Crawl  Type      Flags
────────────────────────────  ─────  ────────  ───────  ────────  ─────
/blog/{slug}                    412     8,221    34.20  template  -
/keyword/{slug}               1,983     5,107    21.25  template  -
/api/v1/{*}                      14       802     3.34  api       noindex

Search Console (salience search …)

Need the Google Search Console integration connected in the dashboard (gsc_connected: false otherwise). Data lags 2–3 days.

| Command | Description | |---|---| | salience search performance [-h 720] [--start/--end] | Sitewide daily series (impressions, clicks, CTR, position), totals vs the previous equal period, top queries and top pages | | salience search queries <path> | Top queries + 28-day daily series for one page (synced for the top 200 pages by impressions) | | salience search reconcile [-h 720] [--start/--end] | Google index status vs verified Googlebot fetches: indexed & fetched, indexed & not fetched, not indexed & fetched, fetched & never inspected — counts plus example paths |

Google Analytics (salience ga …)

GA4 is a connected source like Search Console, not an ingest path: it adds the human outcomes the logs cannot see (sessions, engagement, key events, revenue) next to the request stream. Connect a GA4 property in the dashboard under Settings → Integrations → Google Analytics (ga_connected: false otherwise). Synced nightly; data lags about a day; aggregates only.

| Command | Description | |---|---| | salience ga overview [-h 720] [--start/--end] | Sessions, users, engagement rate, key events (GA4 conversions), revenue and pageviews vs the previous period; top sources; outcomes per AI assistant; the measurement gap (share of human page requests in the logs that GA never recorded). --csv prints the daily series | | salience ga pages [-h 720] [--start/--end] [-l 100] [-q /blog/] | GA4 landing pages sorted by sessions: engagement, key events, revenue, pageviews, AI and search sessions, average engagement per path |

$ loglens ga overview
Signal Checker - GA4 (123456789) · window 2026-08-06 → 2026-09-04 (30 days, GA lags 1 day)
Sessions 48,210 (+6.2%) · Users 39,880 (+5.1%) · Engagement 61.3% (+1.4pp) · Key events 812 (+11.0%) · Revenue 3,140.50 GBP (+8.9%) · Pageviews 71,004 (+4.7%)
...
Measurement gap: GA recorded 71,004 pageviews against 93,410 human page requests in the logs — 24.0% unmeasured over 30 days.

Page Importance, checks, health, recommendations, insights, reports

| Command | Description | |---|---| | salience importance [--bot google\|bing] [-n, --limit 100] | Page Importance: how often verified crawlers return to each page (0–10, log scale) | | salience checks [status] | Site Safety Checks (status is the default subcommand): a summary of fail / warn / unknown / pass / not_applicable and one row per check with its outcome, final URL, note and evaluation time. unknown = could not be evaluated (not a pass); evaluated: false = no evaluation yet. --json / --csv print the checks list with every evidence field (summary counts are derived from it) | | salience checks history [-d, --days 30] | Daily verdict history (dates YYYYMMDD, UTC) + when checks changed, including into or out of unknown (1–90 days) | | salience health status | Current site + ingestion health (data flowing, error rates, feed misconfig) | | salience health history | Historical hourly traffic trend with its baseline band (the API's default metric over 24 hours; -h is sent but not currently applied) | | salience recommendations list [-h 24] | All current recommendations (404 hotspots, slow paths, unverified bots) | | salience recommendations paths-404 [-h 24] | Top 404 (not-found) paths worth fixing or redirecting | | salience recommendations inbound-broken-links [-h 24] | Inbound broken links from the logs: human 404/410 hits that carried a Referer, grouped by referring host and path (scope external or internal; counts are a lower bound, bots excluded) | | salience recommendations slow-paths [-h 24] | Slowest paths (highest response time) | | salience recommendations unverified-bots [-h 24] | Bots claiming a verified identity whose IP failed verification | | salience recommendations ai-claims [-h 168] | AI crawler claims served without passing IP verification, per claimed bot, with networks, sample IPs and edge rules (--json includes snippets) | | salience recommendations refused-crawlers [-h 168] | Verified search, AI and social crawlers your rules partly refuse (401/403/429), with the status split and top paths (--json includes guidance) | | salience snippet <block_ips\|block_bots\|gone_404s> [--target cloudflare\|cloudfront\|nginx\|apache\|netlify\|vercel\|robots] [--days N] | Ready-to-paste rule from a recommendation for your platform (defaults to the site's platform). Prints the snippet; --json for the full response. --days sets the window the rule is built from. Review before deploying — nothing is applied for you | | salience insights | Cached AI-generated insights (traffic / SEO / anomaly narratives) for the default dashboard page; -h is sent but not currently applied | | salience report [-d, --days 30] [--for <client name>] | Generate a Technical SEO Report (7–90 day window); it lands in exports when ready. --json only |

AI crawlers, crawl join and segments

| Command | Description | |---|---| | salience llms [-h 24] [--start/--end] [--countries US,GB] [--segment <id>] [--intent training\|search\|fetcher] | LLM/AI-crawler analytics (GPTBot, ClaudeBot, PerplexityBot, etc.) — each crawler carries an intent and intent_totals gives the split; --intent prints the ranked URL paths read for one intent | | salience ai-funnel [-h 720] [--start/--end] [--countries US,GB] [--min-impressions 50] [--segment <id>] | Recorded AI requests alongside attributed referral visits (fetches_per_visit), plus Search Console pages without recorded AI requests; not linked conversions or proof of AI use | | salience ai-landing [-h 720] [--start/--end] [--countries US,GB] [--operator OpenAI] [-n 200] [--segment <id>] | AI landing pages: which pages AI assistants (ChatGPT, Perplexity, Claude, Gemini, Copilot) send people to — visits vs the previous period, share of human traffic, per-assistant table, then per page the citing assistants, share of the page, bounce proxy and the pages those visitors went to next | | salience crawls | List crawls (uploads and Salience crawls) with status and audit summary | | salience crawl-report [-h 720] [--start/--end] [--limit 200] [--segment <id>] | Crawl join: latest site crawl crossed with the logs — active / ignored / orphan pages, attention by depth and inlinks (--limit max 1000) | | salience crawl-links [-h 720] [--limit 500] [--prefix /blog/] [--max-depth N] [--segment <id>] | Link graph of the latest Salience crawl crossed with the logs: nodes with PageRank / inlinks / hits, edges, and the linked-but-ignored / fetched-but-barely-linked lists (--prefix and --max-depth are sent but not currently applied by the public API) | | salience url <path> [-h 168] [--start/--end] [--countries US,GB] [--segment <id>] | Every signal for one URL: request/human/bot/verified-search tiles, status mix and timings, Google/Bing fetches, Search Console inspection (status, verdict, inspection date, the exact inspected URL, and Google's canonical — not proof of indexing; a page never inspected is shown as such), crawl (completion date, depth, inlinks, PageRank, declared canonical; missing saved results are reported), sitemap membership (present / removed / not_found after a complete fetch / unknown, which is not proof of absence) with snapshot completeness and dates, and Page Importance, then top bots / referrers / countries. Each source keeps its own date. --json for the full response | | salience urls [query] [-l 15] | Typeahead over the URLs Salience knows for the site (sitemap inventory + crawls): path fragment, prefix or full URL; prints Path, Source (sitemap / crawl_discovered / crawl), Sitemap (membership status), Crawls, Last crawled, Last bot (prefix matches first, then substring, then by crawls), then the sitemap snapshot state. Empty query = most-crawled URLs. --json for the full response. Use it to find the exact path for salience url | | salience crawl-audit [-h 720] [--start/--end] [--limit 100] [--segment <id>] | Crawl audit: broken links, redirects, canonicals, titles, thin/slow pages, hreflang, sitemap hygiene, and broken external links when the crawl checked them (a link that could not be checked is unavailable, never broken) — each crossed with search-bot hits (--limit max 500) | | salience segments | List saved segments (user-defined page groups) | | salience segment-breakdown [-h 720] [--start/--end] [--compare] [--segments id1,id2] | Every segment over the period (requests, humans, search-bot hits, Googlebot, AI, paths, crawl coverage, errors); --compare adds the previous period and deltas |

Alerts and exports

| Command | Description | |---|---| | salience alerts [-h 24] [--start/--end] [--severity critical\|warning\|info] [--alert-type error_spike_5xx] [--incidents] | Fired alert history (anomalies, error spikes, suspicious bot activity). --severity and --alert-type are sent but not currently applied by the public API, so filter the output yourself. --incidents groups repeats into one row per distinct problem (fingerprint, first/last seen, count, active / cleared / snoozed / covered, acknowledged). covered means the site's context says it is by design (see salience context) | | salience context list | The site's context entries: what you have told Salience is by design, each with its scope (alert types, paths, bots, IPs), note, and how many alerts it has covered | | salience context add --note "why" [--type <alert_type>] [--path "/a/*"] [--bot <name>] [--ip <address>] [--review YYYY-MM-DD] | Add an entry (read_write key). With paths, bots or IPs an alert is covered only when every one it names is listed; --type alone covers every alert of that type, and for secret_exposure or hacking_probe needs --confirm-type-only. A note with no scope silences nothing. Covered alerts are still recorded; nothing is sent. Paths may end in * (rest of one segment) or ** (everything below) | | salience context remove <context_id> | Remove an entry (read_write key); alerts it covered are delivered again | | salience alerts-config | Current alert configuration (enabled types, thresholds, recipients) | | salience outcomes [-h 24] [--start/--end] [--valence positive\|negative\|recovered] [--status open\|closed] | What happened over the period and how it went: positive outcomes are "handled well" evidence (a probe storm your firewall rejected at the edge, a bot surge absorbed with visitors unaffected), negative ones are quiet degradations that raised no error (visitor pages slow or missing content while status codes stayed 200, a probe storm the origin served), recovered marks a negative clearing. One row per episode with first/last seen, confidence and the same card sentence the app shows; the header carries positive_count and open_negative_count for the whole window. Window up to 30 days. Positives are only recorded at high confidence, so an empty list means nothing to report. --json keeps the evidence figures | | salience exports | List background export jobs (status, row count, download URL when ready) | | salience create-export -t <type> [options] | Queue a background export job; poll exports for the download URL. --type: requests (request-level, ALL bots — narrow with --bot-scope search\|ai\|all), traffic, paths, status-codes, bots, bot-history, referrers, geography, devices, ips, sitemap-coverage, crawl-budget-urls, seo-requests (search-engine bots ONLY), url-pattern-urls, recommendations-paths-404, recommendations-slow-paths, recommendations-unverified-bots, recommendations-inbound-broken-links. Filters: -h, --start, --end, --countries US,GB, --bot-name GPTBot, --status-code 404, --status-category 4xx, --traffic-type bots\|humans, --user-agent <substring>, --file-type html, --pattern <p> (for url-pattern-urls). Filters the type does not support are ignored and reported back | | salience download-export -j, --job <id> [-o, --output <path>] | Download a completed export job's CSV to a local file (default export-<job>.csv[.gz]) |

$ loglens alerts -h 168 --severity critical
Alert ID                              Type             Severity  Name                       Fired
────────────────────────────────────  ───────────────  ────────  ─────────────────────────  ────────────────────
3f8a-...                              error_spike_5xx  critical  5xx spike on /api          2026-05-09T14:02:11Z
b21c-...                              bot_surge        critical  GPTBot 12x baseline        2026-05-08T03:44:00Z
$ loglens llms -h 168
  Total Requests        184,221
  Unique Bots           7
  Top Bot               GPTBot
  Top Bot Share         42.10%
  Verified Share        91.30%

Write commands — need a read & write API key

Keys default to read-only; create one with the read & write scope under Organization → API Access (app.salience.com/organization/settings?tab=api). Every action is recorded as a site event on the website's timeline. These print the API response (--json/--csv not applicable). Nothing here touches your hosting or CDN — use snippet to get a rule to review and paste yourself.

| Command | Description | |---|---| | salience ack-alert <alert_id> | Acknowledge an alert | | salience event-add --title <text> --date YYYY-MM-DD [--time HH:MM] [--category deploy\|migration\|content\|seo\|marketing\|other] [--description <text>] | Add a site event to the timeline (title ≤80 chars; time defaults to 12:00, category to other) | | salience bot-suppress <bot_name> [--days N] [--reason <text>] | Stop a bot raising SEO error alerts, optionally expiring after N days (1–365; omit for indefinite) | | salience bot-suppress <bot_name> --undo | Remove the suppression | | salience rec-resolve <key> | Resolve a recommendation by key (from recommendations list) so it stops showing | | salience rec-resolve <key> --undo | Re-open a resolved recommendation | | salience segment-create --name <name> [--rule type=value…] [--exclude type=value…] [--parent <segment_id>] [--colour <hex>] | Create a saved segment. Rule types: prefix, contains, exact, regex, query; repeat --rule/--exclude for several, e.g. --rule prefix=/blog --rule 'regex=^/p/[0-9]+$'. --parent nests it inside another segment | | salience segment-delete <segment_id> | Delete a saved segment | | salience crawl-start [--max-pages N] [--check-external-links] | Start a Salience crawl of the site (page cap 100–50000, default 10000); results feed crawl-report / crawl-audit. --check-external-links also checks outbound links to other sites with bounded HEAD requests (at most 200 URLs and 100 robots.txt reads, robots honoured, no redirects followed, no bodies); omitted, the site's own setting applies, which is off unless enabled | | salience crawl-cancel <crawl_id> | Cancel a running crawl |

Output formats

  • default — colourised table, headers bolded, numbers right-aligned. Where it adds signal (traffic time-series, bot trends), a small inline sparkline is rendered. Long string columns are truncated to 50 chars.
  • --json — pretty-printed JSON. Most commands print the upstream API response untouched; SEO list commands (seo sitemap, seo requests, seo index-urls …) print the extracted list without the response envelope. Pipe to jq.
  • --csv — RFC-4180 CSV with quoted headers. Suitable for spreadsheets.

Examples

Top crawlers for the last 7 days as JSON, piped into jq:

salience bots -h 168 --json | jq '.bots[] | select(.category == "ai") | {name, requests}'

Export every 404 from the last 24h as CSV for the SEO team:

salience seo requests --filter errors --page-size 500 --csv > 404s.csv

Watch the live alert feed (re-run every minute):

watch -n 60 'loglens alerts -h 1 --severity critical'

Crawl-budget audit for /blog, sorted/filtered downstream:

salience seo budget-urls --dir /blog --bot googlebot -h 168 --json \
  | jq '.urls | sort_by(-.requests) | .[0:20]'

Daily LLM-traffic snapshot mailed to the team:

salience llms -h 24 --csv | mail -s "Daily AI crawler report" [email protected]