Skip to main content

v0.0.108

Released Oct 10, 2026


Release Notes

Audits now come in three sizes, called levels: quick, surface and full. A level is one name for a whole set of settings (pages, crawl strategy, cloud checks, rendering, external link checks and probing), defined once and shared by the CLI, the local MCP server and the dashboard, so a surface audit means the same thing wherever you start it. A signed-in cloud audit costs credits at every level, quick included: 50 for the audit plus 2 per audited page. Signed out or with --offline, the audit runs on your machine and costs nothing. The Audit levels guide has what each level reads, checks and costs. Also in this release: the local MCP audit_website tool now bills a signed-in audit the way squirrel audit does, a dev server on localhost stops getting marked down for having no HTTPS, squirrel self uninstall is safe for package managers to call, and a pile of rule fixes.

Added

  • Audit levels: --level quick|surface|full. A level is a named set of audit settings (pages, crawl strategy, cloud checks, rendering, external link checks and probing), defined once and read by squirrel audit, squirrel crawl, the local MCP tools, the config and the shell completions. Quick reads up to 25 pages from the URL and its sitemaps (it follows links only when the sitemaps give it nothing to crawl), surface up to 100 pages with one page per URL pattern first, and full every page it can reach, up to 500. Without --level or [crawler] coverage, squirrel audit runs surface when you are signed in and quick when you are signed out or your session has expired, and squirrel crawl runs quick. --coverage/-C and [crawler] coverage keep working as the older names and fast still means quick. An unknown level, a repeated --level or -C, or two flags naming different levels stop with an error before the crawl starts. Picking a level fills in every setting; the flags and config values you already use (--max-pages, --render-mode, --http, --probe, [external_links] enabled = false and the rest) change single settings, and an audit whose settings differ from its level becomes custom. The run banner says which: Level surface · max 100 pages, or Level custom (surface + max_pages 200). See Audit levels.
  • Reports say which level they ran at. The JSON report has meta.auditLevel (level, basedOn, changes, settings), the LLM report an <audit-level> element, and the text, Markdown and HTML reports an Audit level: line. A JSON report loaded back with squirrel report keeps it. No existing field changes.
  • The local MCP audit_website tool takes level (coverage still works) and defaults to surface. It applies the project config's page limit, rendering, external link and probing settings the way squirrel audit does, including [crawler] max_pages.
  • After the crawl, the audit lists the pages whose response could not be decoded, with each URL and its declared content-encoding: the first five, then a count of the rest.

Changed

  • The local MCP audit_website tool bills a signed-in audit the way squirrel audit does, at every level: it registers the run (50 credits) and settles it on its audited pages (2 each), renders pages in the cloud browser as the level says (quick only the pages that need JavaScript, surface and full every page), and runs the cloud checks at surface and full. Before, it could run the cloud checks without registering an audit. A tool call cannot prompt, so when the estimate is above [cloud] confirm_threshold (50 by default, as in the CLI) the call returns it as confirmation_required, and the agent calls again with confirm: true. The page budget is fitted to the balance and to [cloud] max_credits_per_audit; an audit that cannot pay for even one page is refused with the cost and the balance, and so is one the server will not register. An audit that errors asks the server to mark its run failed, and stopping the server with Ctrl-C or a termination signal asks it to mark the run cancelled, so both settle like a failed or cancelled squirrel audit. Signed out, with offline: true, against a local or private host, and in quick_check, the tools still run on your machine with no cloud call.
  • A level's settings are now the defaults. Quick no longer checks external links and probes passively, while surface and full check external links and probe actively, signed in or not. Before, external links were checked at every level and probing followed sign-in instead of the level. A signed-out audit with no flags runs quick, so it now skips external link checks. Explicit flags and config values win as before. max_pages = 100, which squirrel init writes into every config, still reads as unset, and so does [external_links] enabled = true, which it also writes, so a generated config no longer turns external link checks on at quick. Set --level surface or full to get them back.
  • Hints and locked-check messages point at --level instead of -C, and the quick-level message no longer says "coverage".
  • security/leaked-secrets reports a server-only secret found in a browser-served script (database connection strings, service-role and sk_live_ keys, AWS secret keys and similar) in a new leaked-secrets-critical check, "shipped to every visitor". Publishable keys, DigitalOcean Spaces key ids, tutorial values (AWS's documented example keys, placeholder or localhost database URLs) and hits only in page HTML are unchanged.
  • perf/bad-caching explains a missing ETag behind Cloudflare. Cloudflare drops the ETag from HTML it rewrites (Email Address Obfuscation, Automatic HTTPS Rewrites, Replace insecure JavaScript libraries, and JavaScript Detections, which Bot Fight Mode turns on), sometimes only for requests that ask for a page, so a plain curl -I can show a header browsers never get. When the validators check warns and at least half of the pages missing a validator came through Cloudflare, the finding now says the CDN may be the cause and lists the fixes: no-transform in the HTML Cache-Control, turning those features off, or also sending Last-Modified. The validators check now warns instead of failing, because a page with no lifetime and no validator already counts against the freshness check. A weak ETag (W/"...") still counts as a validator for every content encoding. The rule page shows how to check which side removes it.
  • crawl/pdf-size describes its 60MB failure threshold as squirrel's default, not as Google's limit. Google documents 64MB for PDFs; the rule's messages, description and option text now say so.
  • security/sri, content/meta-in-body and schema/rating-scope use one message wording whatever the count, and schema/rating-scope no longer puts the rated entity's name in its check message, so one defect keeps one finding identity across pages.
  • squirrel self uninstall only deletes what a squirrelscan install created, and is ready for package managers to call. It removes the squirrel link (in the default bin directory and the one recorded by self install --bin-dir) and ~/.squirrel/releases, and keeps settings, credentials and audit data unless you pass --purge, which now also removes the cache directory. Each link is checked against the managed install before anything is removed: a link pointing anywhere else, an unrelated file at the link path, or a symlinked ~/.squirrel is reported and left alone, and a symlink inside the releases is never followed. It will not delete a managed install when run from some other squirrel binary. It asks before deleting, and without a terminal it refuses unless you pass --yes (the new name for --force, which still works). With nothing left to remove, it exits 0. See self uninstall.
  • The install docs cover Homebrew: brew install --cask squirrelscan/tap/squirrel installs a launcher that runs the regular installer on first use, after which squirrel self update owns updates. brew uninstall --cask squirrel runs squirrel self uninstall --yes, and --zap also removes ~/.squirrel. See the quickstart.

Fixed

  • A clean site audited on localhost or a private-network host no longer scores a C or D for being a dev server. The transport and delivery rules (security/https, security/hsts, security/http-to-https, perf/http2, perf/compression, perf/asset-compression, perf/cache-headers, perf/bad-caching) are skipped there and left out of the score, so the same cause (no HTTPS, no compression, no caching policy) is no longer charged by several rules at once. The report says so in one line under the score, and the JSON report as notApplicable. The host is classified from the audit URL by the same check the cloud handoff already used, now shared in @squirrelscan/utils; public hosts score exactly as before. See Transport and delivery rules do not apply.
  • The docs said local audits were free. The agent setup pages, the cloud overview, the setup guides and every rule page now say it plainly: signed-out local audits need no account and cost nothing, and signed-in audits spend credits.
  • squirrel crawl -C fast crawled with no page limit at all: the crawl cast the flag to a level without checking it, the page lookup for fast came back empty and the cap became NaN. The crawl now reads its level through the same parser as audit, so fast is quick (25 pages) and an unknown level stops before the crawl starts. A non-numeric --max-pages is refused too, instead of the same unbounded crawl.
  • The local MCP quick_check tool described itself as a single-page check. It reads the URL and its sitemaps, 25 pages by default, and now says so. It also follows the project's [crawler] max_pages and [security] probe settings.
  • The console report footer counts warnings the same way as its "Total:" line. Before, the footer counted advisory warnings from severity-"info" rules and the score line did not, so one report could show two warning totals.
  • squirrel audit -f json -o <file> prints the "JSON report saved to" line on stderr instead of stdout.
  • A malformed squirrel.toml prints the "TOML syntax error:" line with the parser detail again. The check compared the error name, which the parser never sets, so the labelled message never showed.
  • content/heading-hierarchy does not count an empty heading the markup hides (hidden, inline display:none or visibility:hidden, or a hidden or aria-hidden ancestor). The parser marks those headings, so a cached parse counts the same as a fresh one.
  • A signed-in audit of a localhost, private-network or other non-public host no longer sends the archive-indexing lookup to the cloud, where it could only come back empty.
  • Template fan-out, which lets the pages of one template share a rule's verdict, now groups pages only when the markup those rules read matches too: the same scripts and stylesheets (and whether each carries integrity), the same <meta> tags with the same viewport, geo and refresh values, and the same number of <main> landmarks. Before, a page missing its viewport meta, carrying a second <main> or loading a different per-route bundle could inherit a sibling's result. Fan-out runs when the rule cache is off: in cloud audits, and in CLI audits with SQUIRREL_RULE_CACHE=0. On a recorded 4000-page gymshark.com crawl, 3931 of 3983 pages still group with their template (3946 before).
  • Results replayed from an earlier run ignore an items field that is not a list, so a damaged stored row can no longer crash a smart audit or a publish while it merges results.
  • crawl/all-noindex-pages validates its warnOnPatterns and errorOnPatterns options. A value that is not a list of strings now fails option validation, instead of reaching the matcher and breaking the rule.
  • perf/source-maps ignores <script> and <style> inside <noscript>. A browser with scripting enabled never runs that markup, so a source map referenced there is no longer reported.
  • content/article-toc finds a table of contents ItemList nested in a JSON-LD @graph wrapper, as Yoast, Rank Math and Slim SEO emit. Before, the rule reported a missing TOC schema on those sites.

Update to this version

squirrelscan will auto-update, or run this command to update now:

$

Downloads

macOS

Detected
Apple Silicon (M-series)
squirrel-0.0.108-darwin-arm64 · 69.7 MB
Download
SHA-256
Intel
squirrel-0.0.108-darwin-x64 · 76.2 MB
Download
SHA-256

Linux

x64 (musl/Alpine)
squirrel-0.0.108-linux-x64-musl · 81.4 MB
Download
SHA-256
ARM64 (musl/Alpine)
squirrel-0.0.108-linux-arm64-musl · 80.7 MB
Download
SHA-256
ARM64
squirrel-0.0.108-linux-arm64 · 87.4 MB
Download
SHA-256
x64
squirrel-0.0.108-linux-x64 · 87.4 MB
Download
SHA-256

Windows

x64 (Intel/AMD)
squirrel-0.0.108-windows-x64.exe · 93.4 MB
Download
SHA-256

Audit your site in one command

SEO, performance, security, accessibility and agent experience issues, with exact fixes for your coding agent.

Install
$

No account needed for the CLI. Cloud audits include free monthly credits.