@salience/lens-cli
v2.1.8
Published
Salience CLI — server-log intelligence (search crawlers, AI agents, threats, site health) from your terminal
Maintainers
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-cliRequires 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-cliGive 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-cliThe 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-8022c4a2cc82API 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 ExampleTraffic 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 unverifiedSEO 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 noindexSearch 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 tojq.--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.csvWatch 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]