v0.0.105
Released Oct 7, 2026
Release Notes
images/responsive-size measures thumbnails in pixels, schema/json-ld-valid follows schema.org and Google more closely and now checks the fields of each breadcrumb and FAQ question, and squirrel entities shows the page each dangling reference comes from.
Changed
images/responsive-sizecompares a thumbnail's real pixel size with the size itswidthandheightattributes give it, allowing for 2x screens, the way Lighthouse's responsive images audit does. It still looks only at images 100x100 or smaller by those attributes (the defaultmax_thumbnail_dimension), with nosrcsetand outside<picture>. A large image shown small is now reported even when its file is light, such as a 1200x1200 JPEG of 20 KB shown at 64x64, once the pixels a 2x screen never draws come to 4 KiB or more of the file, so this rule can report more than before. With the pixel size known, an image no more than twice the size it is shown at is not reported, animated or not, so an animated WebP shown at its own size no longer is. When the pixel size can't be read, such as a JPEG whose dimensions sit past the bytes read, the rule falls back to the file size check from v0.0.104, which still skips SVG, ICO, GIF and animated images. The rule page has the details.- To read that pixel size, the image check now requests the first 32 KiB of each image on the host you audit and its subdomains, normally with one ranged
GETin place of theHEADit sent before. At the default 500-image limit that is about 16 MB of image data, less when files are small or reused from the cache. A server that rejects the range, or answers without a length, can cost extra requests. Raster images an earlier version measured are requested again on the next audit so their size can be read, even when their cache headers would have let the audit reuse them. schema/json-ld-validnow checks the fields of each entry in aBreadcrumbListand aFAQPage. Those per-entry checks never ran before, so the rule can report findings it did not: a crumb with noposition, noitem(the last crumb may leave it out, as Google allows) or nonameon the crumb or itsitem, and a question with nonameoracceptedAnswer.a11y/label-content-name-mismatchand thetabindex-very-highcheck ofa11y/tabindexlist up to ten elements, and now count the elements past those ten toward the score as well, up to 20 per check and page, the same cap every failing check has. A page with more than ten of them can score lower. Warning checks that cut their item lists short now also record how many items they left out, asdetails.additionalin the JSON report:tabindex-positive, and checks ina11y/identical-links-same-purpose,a11y/link-in-text-block,perf/animated-content,perf/source-mapsandschema/rating-scope. Warnings count once per check and page, so their scores don't change.- The local project store (
~/.squirrel/projects/<domain>/project.db) upgrades itself to schema version 32 the first time this version opens it. Version 31 stores the pages behind each entity map reference and version 32 stores each image's pixel size and whether it is animated. Both only add columns, so v0.0.104 can still open the upgraded store.
Fixed
schema/json-ld-validno longer flags valid markup: a single recipe ingredient, recipe instructions given as text or as a single step, a single FAQ question or breadcrumb not wrapped in a list, a breadcrumb named on itsitemnode, a Product offer that is anAggregateOffer(it needslowPriceandpriceCurrency, notpriceandavailability), an Article with no publisher or a publisher with no logo, and fields given on a top-level node that has an@idbut no@type, which a reference to that@idnow finds. A page reused from the crawl cache picks up that last fix once it is fetched again, or with--refresh.squirrel entitiesand the entity tools insquirrel mcpshow the page each dangling reference comes from. The "Example page" column was always empty, because the store kept no pages for a reference. The edges andsitethey read back now match the audit report's entity map, andsiteis the URL you audited rather than the site's origin (older audits that never recorded that URL still show the origin). New audits store the pages, andsquirrel analyzefills them in for an audit stored by an earlier version.- A finding in your dashboard for an element you fixed, or for one a rule update renamed, now resolves when a published audit checks that page again and lists every item of that check, even while the page still fails the check for another element. Before, it stayed open for as long as the page failed the check at all. A check that lists only some of its items, or could not finish its scan, keeps the rest open, because the audit can't tell they were fixed.
content/hidden-textandcontent/dev-leakageskip a page that hits their scan limits when the part they read was clean, instead of passing it. The pass told your dashboard the page was clean, so a finding from an earlier audit that sat past the limit was marked fixed while it was still there. It now stays open.- The configuration docs use the rule ids and option names the rules read. Entries such as
[rule_options."performance/ttfb"],exclude_patternsandmin_external_linksmatched no rule or option, and an audit ignores an unknown rule id or option without a warning (squirrel config validatedoesn't catch it either), so copying them changed nothing.content/keyword-stuffing'sdensity_thresholdis a percentage (3, not0.03), and the URL patterns these rule options take are a substring, a/segment/or aregex:, never a*glob. The rule options reference is corrected and points to the Options table on each rule's page, and thesquirrel initpage shows the config file the command really writes.
Security
- The MCP SDK is updated to 1.32 for a published advisory in its OAuth client (GHSA-6qxp-vccf-f47h).
squirrel mcpruns only the SDK's stdio server and the OAuth client is not part of the squirrel binary, so the CLI was not exposed.
Update to this version
squirrelscan will auto-update, or run this command to update now:
$