Skip to main content

Releases

Release history and changelogs

All releases up to v0.1 will be in the stable channel.

Release channel

Release History

v0.0.88Aug 27, 2026Latest

Release Notes

Two rules about the difference between a page that is linked and a page that is supported. A site's navigation links every page from every other page, which makes the whole site look evenly connected when most of it is not: a page whose only inbound links are the ones repeated in the header and footer carries no signal about what it is for or why it matters. The same template logic cuts the other way for the site's own assets, where one shared layout should give every page the same favicon and share image, and a page that disagrees is usually running an older template nobody remembers owning.

The engine is now at 278 rules across 21 categories.

Added

  • links/no-contextual-inbound reports pages whose only internal inbound links come from sitewide chrome: the nav, header, footer or sidebar. Those links help discovery, but they are identical on every page, so they say nothing about the page they point at. The fix is a link from the body copy of a related article, hub or category page with anchor text that describes the destination, which is what passes topical relevance. The minimum count is configurable for sites that treat a single contextual link as enough.

  • social/asset-divergence reports pages whose favicon, theme-color or fallback share image differs from the rest of the site. These come from one layout, so every page should carry the same three, and the ones that do not are a section that missed a redesign or a second layout still in service. The visible cost is a tab icon that changes as visitors move around and link previews that do not match. Per-page share images on articles and products are correct and are not reported: the comparison is against the fallback the rest of the site shares.

Changed

  • Custom request headers are available on every plan. Auditing a staging site behind an auth header is how you check work before it ships, and it was gated behind Pro. It is not any more.

Fixed

  • squirrel credits linked to a page that did not exist. The top-up link it printed had never resolved to anything. It now lands on the billing page for your account, and older versions of the CLI that still print the old address are redirected there too.

  • Running out of credits during an audit now says what to do about it. The CLI printed a bare warning with no price and nowhere to go. It now reports the balance, what the audit needed, and where to top up or upgrade.

  • Reinstalling over a stale squirrel symlink no longer fails. If ~/.local/bin/squirrel pointed at a release that had been cleaned up, the installer refused to replace it. It now does. The install script also no longer dies part way through on systems where sh is dash, which is the default on Debian and Ubuntu.

Downloads

Windows
Linux
v0.0.87Aug 21, 2026

Release Notes

A reliability fix for long audits. An audit is not just its crawl: once the last page is fetched there is still link checking, rule evaluation, scoring, rendering and publishing to do, and on a large site that second half can take longer than the first. The CLI reported its progress only while pages were being crawled, so for the whole of that second half it went quiet, and a run that was working normally became indistinguishable from one that had died. Past a point the server concluded it had died and marked it failed, discarding a completed crawl and delivering no report.

The bigger the site, the more likely this was, which is the wrong way round.

Fixed

  • A long audit is no longer given up on while it is still running. The CLI now reports that it is alive for the entire run rather than only during the crawl, so the time spent on rules, scoring and rendering no longer counts against it. Audits of large sites that previously failed near the end, after the crawl had already finished, should now complete and publish. If one of yours did this, re-running it on this version is worth a try.

  • Interrupting a crawl now tells you how to resume it. Crawls have always been saved as they go, and an interrupted one can be picked up where it stopped with --resume instead of started again. Nothing said so, so a cancelled crawl of a few hundred pages looked like lost work. Cancelling now reports how many pages are saved and prints the exact command to continue.

v0.0.86Aug 20, 2026

Release Notes

Three rules about the gap between what your markup claims and what your pages actually show. Structured data is a promise made to a machine that never reads the page, so nothing in a per-page validity check can tell you the promise is false: a rating block is well-formed whether or not anyone can see a rating, and a lastmod is a valid date whether or not anything changed that day. These rules ask the second question.

The engine is now at 275 rules across 21 categories.

Added

  • schema/rating-scope reports AggregateRating markup that is not about the page it sits on. schema/review validates the shape of a rating block, so one sitewide rating emitted by a template passes on every page of a site, including the privacy policy. Two checks: whether a rating is visible anywhere in the page's own text, and whether the rated entity is the subject of a page where a rating could apply at all. A third-party review widget clears the first, since its badge is injected client-side and a raw crawl cannot see it. The finding names the page type and the rated entity, and frames the risk as a structured-data manual action rather than a validation error, because that is what it is.

  • crawl/sitemap-lastmod-drift reports sitemap lastmod values that disagree with the page's own date. Two directions, because they come from different mistakes: a lastmod older than the page's dateModified usually means a stale sitemap or an inverted published/updated precedence, and one newer by more than a month usually means the field is stamped when the site builds. Each finding reports both dates and the gap in days. Pages carrying no date of their own are skipped rather than guessed at.

  • crawl/sitemap-lastmod-churn reports lastmod values that have collapsed onto one or two days across the whole sitemap, which means they are stamped at build time and carry no freshness signal at all. Google News sitemaps are excluded: they hold about 48 hours of articles by design, so their dates are supposed to cluster.

Fixed

  • Anchor text is judged per destination, not per link. A card that links to the same page twice, once from its image and once from its headline, was reported as having empty anchor text for the image link. Only one link in such a group needs to describe the destination, and screen readers announce the group together, so the checks now evaluate links to a target as a unit.
v0.0.85Aug 13, 2026

Release Notes

Five new rules that grade a page against the rest of your own site instead of against a fixed threshold. Every audit rule until now asked the same question of every site on the internet: is this title too long, is this page too thin. That works for the rules where one right answer exists, and it is useless for the much larger class of problem where the only evidence something is wrong is that one page disagrees with the other nine hundred. A 200 word page is thin on a documentation site and normal on a news site. A product page missing Product markup only matters because its siblings have it.

These rules learn the norm from your crawl and report the deviants, which means they need a crawl big enough to have a norm. All five stay silent below 10 crawled pages, and stay silent when no clear majority exists, reporting a skipped check that says which condition was not met rather than guessing. A site that is legitimately heterogeneous should see nothing from them, and that is the intended result, not a failure.

The engine is now at 272 rules across 21 categories.

Added

  • content/thin-vs-site-norm reports pages far shorter than comparable pages on the same site. Pages are grouped by section first, so a terse tag listing is not measured against your long-form posts, and the outlier test uses a robust spread rather than a mean, so a handful of very long pages cannot drag the threshold up and hide the thin ones.

  • content/title-pattern-outlier learns your title template and reports the titles that break it. Most sites settle on one shape, Page | Brand or Brand: Page, usually because a template emits it. The pages that do not match are usually the ones a human wrote by hand or a migration missed: brand missing entirely, brand on the wrong end, a different separator.

  • schema/coverage-outlier reports pages missing the structured-data markup their siblings have. If 90% of your product pages carry Product and a dozen do not, those dozen lose rich results, and nothing in a per-page check can see it because each page is individually valid.

  • url/slug-convention reports URLs that break your site's own conventions: case, word separator, trailing slash, file extension. Mixed conventions usually mean two generations of routing coexisting, which is where duplicate content comes from.

  • core/canonical-form-drift reports canonical URLs that disagree in form across the site, for example some absolute and some relative, or some with the www host and some without. Each one is individually valid, so per-page validation passes while search engines see an inconsistent story about which URL is the real one.

Fixed

  • A site behind a WAF challenge is no longer reported as unreachable. Adding a domain probed it first and accepted only a normal response. A site sitting behind Vercel's Attack Challenge Mode, Cloudflare's, or any similar protection answers that probe with a challenge rather than the page, and the domain was refused as if the site were down. The probe now treats any HTTP response as proof the site is there, because it is.

  • A crawl that lost its handshake no longer disappears. If the network dropped the call that registers a run, the CLI retried and the server treated the retry as a second, unrelated run. The original became an orphan: work that had been done, could not be found, and showed up later as a failed audit. The registration now carries an idempotency key, so a retry resolves to the same run, and an orphaned run is adopted when its report is published.

  • Long crawls are no longer killed while they are working. The job that cleans up abandoned runs measured age alone, so a genuinely slow crawl of a large site could be marked failed while it was still making progress. It now looks at progress before deciding a run is dead, and audits that were reaped and then delivered anyway are repaid.

  • Renders you did not get are no longer charged. A page render that failed was still billed, and a run could spend past the estimate it quoted you when it started. Failed renders are refunded and spend is capped at the run's own quote.

  • Cloud audits run every rule you are paying for. Audits started from a website or from the GitHub integration were dispatched without the flag that enables the paid services the rules depend on, so eight rules quietly skipped while the audit billed in full. Both paths now dispatch with those services enabled and a bounded credit cap.

  • A failed audit refunds the organization that was actually charged. When a run failed after its base charge, the refund was aimed at the organization named in the request rather than the one billed. If you had not named one explicitly, those two were different and nothing was refunded at all.

  • A missing robots.txt is reported as an error, not a warning. No robots.txt means no place to declare a sitemap and no control over crawling. That is not a nice-to-have.

  • Report issues are ordered by severity across the whole report. Sorting happened inside each category, so a critical issue in the last category sat below a warning in the first, and the top of the report was not the worst of the findings.

  • Windows installs no longer fail with a permission error. The installer linked the binary with a symlink, which needs Developer Mode or an elevated shell on Windows, and failed with EPERM otherwise. It now falls back to a copy. A failing squirrel self install also prints what actually went wrong instead of a bare exit code.

v0.0.84Aug 3, 2026

Release Notes

A crawl-correctness release. squirrelscan was requesting URLs your site never links and then reporting the redirects it had caused. On any site whose URLs end in a slash, which is the default on WordPress, Hugo and Jekyll, that invented findings, and on some hosts it also spent part of the page budget on redirect pages instead of your content.

Fixed

  • The crawler no longer asks for a URL your site never linked. URL normalization dropped the trailing slash before the request went out, so a site whose every internal link ends in / was asked for /about when it only publishes /about/. Two things followed from that, and both are fixed.

    First, the origin answered with a redirect, and links/redirect-chains and crawl/canonical-chain reported it: a redirect that existed only because we asked for it. Those findings were wrong rather than merely noisy, and they fanned out, because the check for links pointing at redirecting URLs then blamed nearly every page that linked the correct form. If your report listed pages redirecting to themselves with a slash added, that section should now be empty. Genuine redirects are unaffected: a page you really do link at a URL that really does redirect is still reported.

    Second, and only on some hosts: a few sites answer the no-slash URL with a 200 and a small JavaScript redirect page rather than an HTTP redirect. There is no redirect for the crawler to follow, so that page was stored and graded as though it were your article, and title, charset and word count were judged against a few hundred bytes of redirect script. In one 15 page crawl of a blog hosted this way, 12 of the 15 stored pages were redirect pages rather than posts. Sites that answer with an ordinary HTTP redirect were never affected this way, because the crawler followed it and stored the real page. If your site is in the first group, expect finding counts and scores to move in both directions: some checks stop failing because they had been grading a redirect page, and others start reporting because your content is finally being read.

  • A redirect chain no longer shows a status the hop never returned. When a page is rendered in the cloud, the render service reports the page it landed on, never the statuses of the redirects that got it there. Those unseen statuses were filled in with the landing page's own status, producing chains that read (200) → (200). A first hop that returned 200 did not redirect at all. Hops squirrelscan did not observe are now recorded as unknown and shown without a status, and no chain can claim a hop redirected while also reporting that it returned 200.

  • squirrel auth status explains an organization API key instead of blaming it. An sq_ organization API key works for audits, publishing and credits, but the identity lookup behind squirrel auth status and squirrel auth whoami accepts only the login token that squirrel auth login issues. That rejection was reported as the key being invalid, revoked, expired or from the wrong environment, none of which was usually true. It now says what actually happened, and tells you to unset SQUIRRELSCAN_API_KEY after logging in, since an environment key takes precedence over a session for every cloud call.

Changed

  • A site that links both /about and /about/ now has both crawled. They are different URLs, and only a request can tell you which one redirects, so collapsing them into one meant the answer depended on which form the crawler happened to see first. Sites that link a single consistent form, which is nearly all of them, crawl exactly as before.
v0.0.83Aug 3, 2026

Release Notes

Three new rules, a rebuilt local-SEO check, and a crawl-correctness fix for seeds that redirect off your site. The rule set is now 267.

Added

  • content/hidden-text flags text and links hidden from visitors but left visible to crawlers. Google's spam policies treat this as deceptive, and pages doing it can lose rankings or drop out of search entirely. The rule looks for the techniques that have no innocent explanation: an off-screen text-indent, a zero font size, same-on-same colour, a zero-size clip. It deliberately does not accuse you over display:none or opacity:0 on their own, because that is what every accordion, modal, and scroll-reveal library writes. Content revealed inside a @media block, by a transition on a compound selector, or alongside a transform is read as UI rather than concealment. It is a warning at weight 6, and escalates to a failure only when hidden links are involved, which is the stronger spam signal.
  • a11y/autocomplete-tokens checks that fields collecting a person's own data carry the right autofill token. Name, email, phone, address, and payment fields with the correct WHATWG token fill in one tap, which is the difference between a completed checkout and an abandoned one, and WCAG 2.1 success criterion 1.3.5 requires it. Section and shipping/billing prefixes are understood. A token the browser does not recognise is ignored outright, so a typo like firstname is worse than nothing, and autocomplete="off" on personal data does not stop autofill in modern browsers, it only stops the accurate kind.
  • a11y/input-types checks that fields use the right input type and keyboard hint. type="email", type="tel", type="url", and type="number" each summon the right mobile keyboard and bring free browser validation with them. The rule also flags type="number" on digit strings such as postal codes, phone numbers, and card numbers, where it strips leading zeros and silently discards anything that is not a valid float, and novalidate on a form that still declares required or pattern and ships no replacement validation.

Changed

  • local/nap-consistency now compares your business details across the whole site. It used to judge one page at a time. It now collects the name, address, and phone from every crawled page and reports when the same value is rendered several different ways, which is the drift that actually costs you local citations. Phone numbers declared in tel: links count alongside JSON-LD, so a footer that formats the number differently from your markup is visible. The cross-page half only fires once enough pages declare a signal, and the rule still skips sites with no local-business signal at all.
  • security/form-https now separates a real downgrade from an already-insecure page. Actions are resolved against the page URL, so a relative or protocol-relative action inherits the page's scheme instead of being guessed at, and formaction on submit buttons is read too. An HTTPS page posting to http:// now fails: the padlock tells the user they are safe while the submission travels in the clear. An HTTP page posting to http:// stays a warning, and a page with nothing to submit reports as info rather than passing silently.

Fixed

  • A seed that redirects off-site no longer re-bases the whole audit. If the URL you passed redirected to another site, that target became the audit's base: every root probe (robots.txt, llms.txt, sitemap discovery, the .well-known and agent-manifest sweep) went to a host you never named, and the target's content was stored and reported under your seed's name. A site redirecting to a CDN or a parked domain produced a report describing the target while claiming to describe the seed. The base is now pinned to the seed. A redirect is adopted only when it stays on the same registrable domain and port, so http to https upgrades and apex to www bounces still work; one that leaves is refused, and the refused target is recorded as the report's finalUrl so you can still see it. The same rule applies per page: a page whose redirects landed off-site is dropped rather than filed under your audit, unless your own scope config admits it.
  • Building objects from untrusted keys is hardened. Keys taken from crawled content can no longer reach an object's prototype.
  • The install endpoint always serves the current release. Release channel metadata and the install scripts are now published as part of the release itself and verified against the live endpoint before the run is allowed to finish, so a new version cannot be announced while the installer still hands out the previous one.
v0.0.82Aug 1, 2026

Release Notes

Follow-ups to the v0.0.81 security release, plus two crawl-correctness fixes. Pages listed in a sitemap with query strings are now crawled at the right URL, and a single network blip no longer takes down a whole audit.

Fixed

  • Sitemap URLs with query strings are crawled correctly. XML requires & to be written &amp; inside a <loc>, and that escape was surviving into the URL the crawler enqueued. A sitemap entry for ?a=1&amp;b=2 was fetched literally, so those pages 404'd or were audited as the wrong URL, and on a site that paginates or filters through query strings that can be most of the sitemap. All five predefined XML escapes are now decoded, in a urlset and in the child entries of a sitemap index.
  • A single network blip no longer aborts the audit. The pre-flight reachability probe had no retry, so one transient DNS failure, connection reset, or timeout ended the run before the crawl started. It now makes up to three attempts with a short backoff, inside a 20 second overall budget so a genuinely unreachable site still fails quickly. Only transient failures are retried: a refused connection or an HTTP error is still reported on the first attempt.
  • The bounded-read guard now covers every path. v0.0.81 bounded untrusted response bodies as they stream. On the fallback path taken when a runtime hands back no readable stream, the limit was still applied only once the body was in memory. That path now refuses an over-declared content-length before reading anything, and truncates by bytes rather than characters, so a multi-byte character cannot split at the boundary.
  • Builtin crypto imports are explicit. The crawler and the fetchers imported crypto unqualified. That is an undeclared dependency which can resolve to a deprecated npm stub instead of the runtime builtin, depending on what else is installed. Both now import node:crypto.
v0.0.81Jul 31, 2026

Release Notes

A security release, plus two new content rules. Audits now treat everything a site tells them to fetch, and everything a site tells them to print, as untrusted, and squirrel self settings no longer prints your credentials.

Everyone should update. If you audit sites you do not control, or you use -H/--header to pass authenticated headers, update before your next run.

Added

  • content/stale-copyright flags a footer year that has fallen behind. A copyright year stuck in the past is the most common "this site is abandoned" signal a visitor sees, and it costs nothing to fix. It is a warning at low weight, so one templated footer repeated across every page cannot dominate your content score.
  • content/mojibake flags encoding corruption in visible text. Catches garbled sequences like ’ and é, and replacement characters, in the text your visitors actually read. These almost always mean a template, export, or CMS migration lost the original encoding, and the same corruption is usually sitting in fields you cannot see, such as meta descriptions and alt text.

Fixed

  • Redirects can no longer change protocol. Every fetch derived from page content, including redirect targets, sitemap and RSL references, Link headers, and client-side meta refresh, is now restricted to http and https. Previously a site could redirect an audit to a non-http URL and have the result stored in the report.
  • Custom headers stay on their origin. Values passed with -H/--header are now scoped to the origin you sent them to and are dropped when a redirect crosses to another origin, on auxiliary probe requests as well as page fetches. These values are documented as secrets, so this closes a path where a redirect could forward them to a host you did not choose.
  • A hostile response can no longer exhaust an audit's memory. Every read of an untrusted response body is now bounded as it streams and cancelled at the limit: robots.txt, sitemaps, llms.txt, .well-known documents, RSL, fetched scripts, and page bodies. The previous guards could not do this. A content-length header is absent on a chunked response and reports the compressed size on an encoded one, and the size limit was otherwise applied only once the whole body was already in memory. A small compressed file that expands to gigabytes now stops at the limit instead.
  • A site can no longer repaint your terminal. Page text reaches the console report and the text and llm outputs through many fields, and it could carry terminal control sequences: a site could embed an escape that clears your screen and prints its own "0 issues found" over the real result. Control characters are now stripped where the report is written. The console keeps colour codes, which can only change how text looks and never move the cursor or clear the screen, so the report itself is unchanged.
  • squirrel self settings redacts credentials. The command printed the stored auth token, and any provider keys held in the plaintext fallback used when the OS keychain is unavailable. Output is now redacted. If you have pasted this output anywhere, rotate the token with squirrel auth login.
  • Project names cannot escape their directory. A [project] name in squirrel.toml is now contained before it is used to build the local database path.
  • Repo-local settings are limited to safe keys. A settings.json inside a checkout can now only influence the documented writable settings, so cloning an untrusted repository cannot redirect where the CLI installs updates.
  • Consistent lowercase branding. The product is "squirrelscan" everywhere, including the text report title and the database lock warning.
v0.0.80Jul 24, 2026

Release Notes

The CLI is now open source under MIT, with the public repo set up as the canonical home for the CLI and docs. This release also hardens the public surface and makes sure the telemetry opt-out is honored everywhere.

Added

  • MIT licensed CLI. squirrelscan is now open source under MIT.
  • Public repo source of truth. CLI builds and docs now come from the public repository.
  • Telemetry opt-out respected everywhere. NO_TELEMETRY is honored by the CLI and install flow.

Fixed

  • Public-repo hardening. Release and update paths were tightened to avoid command injection, traversal, unsafe URL handling, and Markdown injection issues.
  • Parser and sanitizer performance issues. Several regex-heavy paths were rewritten to avoid ReDoS-style slowdowns.
  • Secret and scheme filtering tightened. Unsafe URLs and non-http(s) inputs are now rejected more consistently.
v0.0.79Jul 22, 2026

Release Notes

Clearer page limits, more armor for audits of slow or messy sites, and a lot of under-the-hood groundwork for auditing much bigger sites. More on that soon.

Added

  • Audits tell you when they hit your plan's page limit. If a site has more pages than your plan covers in one cloud audit, the report and your audit listings now say the crawl was capped and at what count, instead of quietly auditing a subset. Coding agents get the same notice through the MCP server, so your agent knows it saw part of the site, not all of it.
  • squirrel crawl gets the speed controls. The --concurrency and --per-host flags and the localhost fast path that squirrel audit gained in v0.0.74 now work on the standalone crawl command too.

Fixed

  • Very slow or bot-hostile sites can no longer stall a cloud audit. Analysis of each asset and network probe now runs under its own time budget, and sites that drip-feed bytes to waste crawler time are detected and cut off. An audit of a hostile site finishes with what it could get instead of hanging until the overall timeout.
  • More publish hardening for messy sites. Absurdly long URLs are skipped during the crawl instead of gumming up the works later, every remaining free-text field is trimmed at publish time, and size limits are now enforced byte-accurately so emoji and other multi-byte characters can't split at a boundary. This closes out the class of failures where one extreme page could sink an otherwise good report.

A reliability release for cloud audits. Heavy sites that used to kill the audit engine outright now complete, the easiest way for a good audit to die at the finish line is gone, failed audits always refund, and audits show you they are alive while they work.

Fixed

  • Audits of heavy sites complete instead of dying silently. Sites with very large pages could exhaust the audit engine's memory mid-analysis: the audit went quiet and eventually showed up as timed out, with no report after multiple retries. Audit engines now run with 16x the memory and 8x the CPU, and the exact audits that failed this way now run to completion. If the engine ever does die, the audit is marked failed within moments, with a clear message and an automatic refund, instead of hanging in silence.
  • Audits no longer fail because a page has very long text. A single oversized headline, or any absurdly long string anywhere on a site, could fail the whole audit at publish time: no report, just a refund and a shrug. Publishing now trims display text to fit instead of rejecting the report, across every field, and the same guard covers long lists (a site with issues on more than a thousand pages could trip it too). Big messy sites are exactly the ones that need auditing, so this one mattered.
  • Blocked-site audits refund automatically. When a site blocks the crawler outright (bot protection, 403s at the door), the audit failed but kept its base charge, because the failure notice it published counted as a delivered report. Refunds now check what the report actually says. Every failure path, blocked, down, errored, cancelled, or stalled, nets zero credits.
  • Post-crawl steps have hard deadlines. One audit sat for 52 minutes in a stuck enrichment call after its crawl had already finished. Every post-crawl step now has a deadline: a hung enrichment is dropped, its section is omitted, and the audit finishes with everything else intact. An overall backstop bounds the whole run even if a future step misbehaves.
  • Deleted websites stay deleted. If a bookkeeping step failed during a delete, the site could keep showing up in your website listings until you deleted it again. The record now retries durably until it lands.

Added

  • Live heartbeat while an audit works. The audit feed now shows "still working" progress every 30 seconds through the slow parts, so a long analysis is visibly alive instead of frozen, and a genuinely stuck audit is caught and refunded much sooner.
v0.0.78Jul 21, 2026

Release Notes

A reliability release for cloud audits. Heavy sites that used to kill the audit engine outright now complete, the easiest way for a good audit to die at the finish line is gone, failed audits always refund, and audits show you they are alive while they work.

Fixed

  • Audits of heavy sites complete instead of dying silently. Sites with very large pages could exhaust the audit engine's memory mid-analysis: the audit went quiet and eventually showed up as timed out, with no report after multiple retries. Audit engines now run with 16x the memory and 8x the CPU, and the exact audits that failed this way now run to completion. If the engine ever does die, the audit is marked failed within moments, with a clear message and an automatic refund, instead of hanging in silence.
  • Audits no longer fail because a page has very long text. A single oversized headline, or any absurdly long string anywhere on a site, could fail the whole audit at publish time: no report, just a refund and a shrug. Publishing now trims display text to fit instead of rejecting the report, across every field, and the same guard covers long lists (a site with issues on more than a thousand pages could trip it too). Big messy sites are exactly the ones that need auditing, so this one mattered.
  • Blocked-site audits refund automatically. When a site blocks the crawler outright (bot protection, 403s at the door), the audit failed but kept its base charge, because the failure notice it published counted as a delivered report. Refunds now check what the report actually says. Every failure path, blocked, down, errored, cancelled, or stalled, nets zero credits.
  • Post-crawl steps have hard deadlines. One audit sat for 52 minutes in a stuck enrichment call after its crawl had already finished. Every post-crawl step now has a deadline: a hung enrichment is dropped, its section is omitted, and the audit finishes with everything else intact. An overall backstop bounds the whole run even if a future step misbehaves.
  • Deleted websites stay deleted. If a bookkeeping step failed during a delete, the site could keep showing up in your website listings until you deleted it again. The record now retries durably until it lands.

Added

  • Live heartbeat while an audit works. The audit feed now shows "still working" progress every 30 seconds through the slow parts, so a long analysis is visibly alive instead of frozen, and a genuinely stuck audit is caught and refunded much sooner.
v0.0.77Jul 20, 2026

Release Notes

Fixed issues now actually clear themselves. If you fixed something on a page that a later crawl never revisited, the finding used to sit there open forever and drag your score down. Three separate causes, all fixed. Reports also tell you what they scanned, label anything carried over from an earlier crawl, and five false positives are gone.

Added

  • Reports disclose their scan scope. Every report now states what it actually looked at: how the run started, how deep it crawled, how many pages it covered, and how to run a full scan when you want the rest. No more guessing whether a clean report means "clean" or "barely looked".
  • Carried-forward findings are labeled everywhere. A finding on a page that wasn't re-crawled this run is now marked as carried, with per-rule rollups ("4 of 12 pages carried from previous crawls") in the cloud report, the dashboard, and get_report over MCP. When a rule is clean on every page checked this run and stays red only because of carried pages, it says so, so you can tell "still broken" from "probably fixed, not re-checked yet".
  • "Was on N pages" expands to the actual URLs. In both the cloud report and the dashboard you can open the affected-page list, show all of them when it's long, copy the lot as plain text, and see which URLs were checked this run versus carried over.
  • Agent clients get tool hints over MCP. Tools now advertise whether they only read, whether they change anything, and whether they touch the outside world, so agents can decide what's safe to call without asking first.

Fixed

  • Fixed issues clear instead of piling up. Findings on pages that a later crawl never revisited stayed open indefinitely, and the accumulating warnings kept pushing the health score down. Three causes, all fixed: crawls now seed the frontier with pages that have open carried findings (and stop wasting budget on URLs that are known to be gone), reports over 100 affected pages per check can now resolve pages that were clipped from the published sample, and a page confirmed still failing this run gets a fresh "last seen" stamp instead of looking unconfirmed. On a large site with thousands of stale carried warnings, this is the difference between a score that recovers and one that only ever falls.
  • One health score, not two. The score in your terminal and the score on the published report could disagree on the same run (84 in one place, 56 in the other). The published score is now authoritative everywhere.
  • A burst of cloud audits no longer wedges dispatch. Stopped audit containers held onto their instance slots, so five audits in quick succession could block new runs for up to an hour. Containers are now torn down properly when a run ends.
  • Privacy policy pages are found where they actually live. A /privacy page titled "Privacy Policy" and linked from the footer was reported missing. It's detected now.
  • No more phantom Angular on Tailwind sites. Class names like tracking-tight and leading-relaxed contain ng-, which was enough to report Angular on sites that have never seen it. Detection now requires real framework signals.
  • Cookie-consent checks read the page, not the prose. A page that merely mentions GDPR or cookies (a privacy policy, for instance) was treated as if it had a consent banner. The check now looks for actual consent machinery.
  • Soft 404s confirm before warning. A page that briefly served an error shell during the crawl could produce a finding you couldn't reproduce a minute later. Findings are now confirmed before they're reported.
  • Honeypot fields stop failing accessibility. Hidden anti-spam form fields were reported as focusable hidden content with no useful advice. They're now recognized, downgraded, and told exactly what to add (tabindex="-1").
  • Malformed publish dates are caught. A raw database timestamp in datePublished passed validation silently. Structured-data dates are now validated as real ISO 8601.
  • squirrel self doctor stops suggesting you delete your settings. A permission error reading the user settings file was reported as corruption, complete with a destructive "delete this file" hint. Permission problems are now reported as permission problems.
  • The updater speaks up when it keeps failing. If background auto-updates fail repeatedly, the CLI now tells you plainly to run squirrel self update rather than quietly staying out of date. Commands also wait for a pending update to settle before exiting, so an update in flight isn't cut off mid-write.

Faster

  • Probe responses stream with a hard size cap. Checks that fetch supporting files no longer read an entire oversized response into memory before deciding they don't need it, which trims both time and memory on sites with large assets.
v0.0.76Jul 18, 2026

Release Notes

Big audits publish again, and two false positives are gone. Reports now stay under the publish limit no matter how many pages you crawl, you get warned before starting a cloud audit you can't afford, and a failed publish refunds the whole audit. Plus a new check: soft 404s.

Added

  • New check: soft 404s. Pages that return HTTP 200 but actually render "page not found" content (framework error shells, not-found titles) now get flagged. Search engines treat these as thin or duplicate content, and they usually mean a route is silently broken. Detection is conservative: it requires multiple strong signals before flagging, so a short page with an unlucky title won't trip it.
  • Content and legal checks skip error pages. Rules like cookie consent and content quality no longer judge a page that is really a 404 in disguise. That was the source of phantom "missing GDPR consent" warnings on sites whose error pages leaked into the crawl. Skipped pages are shown as skipped, not silently dropped.
  • Know the cost before you spend. Cloud audits now estimate their credit cost up front (flat base plus per page) and warn you, or ask for confirmation in a terminal, when your balance won't cover it, instead of burning credits on a run that can't finish the way you wanted.

Fixed

  • Large reports publish again. Publishing a big audit (hundreds of pages) could fail with "report exceeds 5MB" even though the real limit is 20MB. Two bugs, both fixed: the error message quoted a stale limit, and site-wide findings embedded every crawled URL, so payload size grew with crawl size. Findings are now sampled (up to 100 pages per finding, with a count of how many more there are), which keeps any report, from 10 pages to thousands, comfortably under the limit. The CLI also checks the size before uploading and trims further instead of failing after the crawl.
  • Cloudflare Turnstile is no longer invisible. Forms protected by Turnstile (and other CAPTCHAs) using the explicit-render or preloaded loader pattern were flagged as unprotected. The check now recognizes preload hints and empty widget mount points, so protected forms pass.
  • Failed publishes refund the audit. If your report can't be published because of a size limit or a server error, the entire audit's credits are refunded automatically instead of leaving you charged for a report you never got.
v0.0.75Jul 17, 2026

Release Notes

Credits stop being a mystery: every audit now shows exactly what it cost and why, and your org gets a full transaction log. Also the first release to arrive on Windows through the repaired self-updater: if you're on 0.0.74, this update installs itself.

Added

  • See exactly what every audit cost. Cloud audit reports now include a cost breakdown: the flat audit base, each rendered page, cache hits, and any refunds. It appears on the report page in the dashboard, and agents get it too: get_report over MCP includes a cost summary, and a new list_credit_transactions tool pages through your org's full credit ledger. There's also a new Transactions view in dashboard settings showing every grant, debit, and refund. If your per-audit cost seems to swing, this is where you see why: only pages whose source changed get re-rendered, so audits right after a deploy render (and bill) more pages than audits of a quiet site.
  • squirrel feedback learned categories. An interactive picker (or the --category flag) files your note as a bug report, feature request, praise, confusion, missing data, or tool ergonomics, and records which CLI version it came from. The same categories run through the CLI, MCP, dashboard, and website, so feedback lands in one place no matter where you send it.
  • Delete websites for real. A new delete_website MCP tool (with dashboard support) removes a site and immediately frees the slot against your website cap.
  • Dashboard polish. Tracked issues can be filtered by how they were found (full crawl vs smart audit), and page-limit settings now show the effective cap when a plan ceiling clamps a custom value.

Fixed

  • squirrel self doctor no longer cries corruption over a permission error. Running doctor from a directory it can't read (locked-down CI images, restricted shells) misreported healthy settings as corrupt and exited non-zero. Permission problems on the working directory are now reported as exactly that, and the rest of the checkup runs normally.
  • MCP sessions no longer drop when tokens refresh concurrently. Two clients refreshing the same session at the same time could race and knock each other out; a short reuse window now lets both land on the rotated token.

Faster

  • Repeat cloud audits skip redundant summary work. Summaries for pages unchanged since the last run are served from a content-keyed cache instead of being recomputed, so re-audits finish sooner.
v0.0.74Jul 16, 2026

Release Notes

Pick your rules and skim your results: audits gain include/exclude filters and a summary mode, local dev crawls get dramatically faster, and Windows self-updates stop dying mid-download. Plus a batch of sharp-edge fixes across auth warnings, settings handling, and cloud publishing.

Added

  • Filter which rules run with --rule-include / --rule-exclude. squirrel audit --rule-include ax,performance runs only those categories; --rule-exclude images skips them. Bare names cover a whole category, category/rule targets a single rule. The report is marked partial and the health score recomputes from what ran. Typos, contradictory filters, and --fail-on gates against excluded categories all error before crawling instead of wasting a run.
  • --summary for a quick score check. Console output trims to the score, category breakdown, and issue counts with no per-issue detail: handy for CI logs and fast re-checks. Works on squirrel audit and squirrel report.
  • Localhost audits are much faster. Plain-HTTP loopback targets (your dev server) automatically skip the polite per-host crawl delay, and new --concurrency / --per-host flags control parallel fetches. Public sites keep the respectful defaults.

Fixed

  • Windows self-updates no longer die mid-download. The background updater ran as a detached child that Windows kills the moment the parent command exits (Job Object semantics), so updates silently never landed. The update now runs in-process with a bounded grace period at exit, and downloads are atomic: a killed update just retries next run.
  • A corrupt or unreadable session file now warns loudly in every command. Cloud-touching commands explain the session could not be loaded and how to check it, instead of silently running anonymous. When an environment token authenticates the run anyway, the warning is suppressed entirely: no more false "running anonymous" on authenticated CI runs.
  • Settings lookup no longer mistakes permission errors for missing files. An unreadable parent directory now surfaces a clear error instead of silently skipping your local settings.
  • Windows users get pointed at the right installer. Running install.sh from Git Bash or MSYS now prints the PowerShell one-liner instead of a dead end.
  • Cloud publish reliability: oversized robots.txt content is clamped instead of rejecting the whole report, and a timing window where a just-published report's run could still be reaped and refunded is closed.

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.