v0.0.138
Released Oct 27, 2026
Release Notes
The bundled page classifier and the findings built on it: link findings say where on the page a link sits, a defect in a shared component reads as one fix-once line, reports carry a Page structure block, and schema/expected-type and a sharper schema/breadcrumb use the page type. First-run telemetry and an audit offer at the end of squirrel setup, with DO_NOT_TRACK honoured. The Markdown report no longer lets crawled text add links or images, and keeps ordinary text readable. A page of thousands of comment-class containers can no longer stall the classifier.
Added
schema/expected-typeflags a page that the bundled page classifier is sure about and that declares none of the structured data its type should carry:Producton a product page,ArticleorBlogPostingon an article or blog post,CollectionPageorItemListon a listing,ContactPageor an organization type on a contact page,AboutPage,Personor an organization type on an about page, andTechArticle,HowToorFAQPageon documentation. It trusts only the model's answer, at 0.9 confidence or above (min_confidencesets it), never a type read from the page's own markup. A page that declares a listing type is not asked for article or product markup. With--no-classifierit reports nothing. See schema/expected-type.- First-run telemetry.
squirrel setupreports each step's outcome (step:outcome, no free text),squirrel auth loginreports completion, and the first audit on an install reports success or a failure class once. After login, telemetry carries your login session so the API can attribute events to your user ID; nothing is sent when telemetry is off, and no URL, host, path or email is ever included. The one-time install registration also reportscpu_translatedandhw_arm64(macOS only, fromsysctl), so real Intel Macs can be told apart from Rosetta shells. Telemetry now also honoursDO_NOT_TRACK=1(ortrue) and a project-level"telemetry": falsein.squirrel/settings.json(an unreadable project file counts as opted out), and the installers honourDO_NOT_TRACKfor their failure report. Existing installs see the updated telemetry notice once more. Listed on the telemetry docs. - First audit right after install. The installer's closing message now leads with
squirrel audit https://your-site.comand listssquirrel setupsecond.squirrel setupends by asking for a site URL and offering to run the audit now (yes runs it; enter skips). With no TTY, in CI or an agent, with--yesor--dry-run, it never asks and prints the command instead.
Changed
- Noindex pages no longer affect
content/thin-vs-site-normon an indexed site: they are left out of each page type's median and cannot be reported as thin outliers. The check details count the pages left out. A staging or preview site whose homepage is noindex still checks every page. See Thin against your own site (#1029). - Where the markup says nothing, a small page classifier bundled with squirrel (about 9 MB, no network call), names the part of the page: the header, footer, navigation, sidebar or page content, and sections such as the pagination, breadcrumbs, a related-content block, the business details, the social sharing links, the account and login links, the author byline and the newsletter signup. The header, the footer and comment threads in the markup always win, comment threads stay markup-only, and a section the classifier names refines a navigation or sidebar landmark. Each page also stores the classifier's page type, and only a page at the root path is ever labelled
homepage.squirrel self doctorshows the artifact and its load time. It can be wrong: on a single article the previous and next post links can read as pagination, a "follow us" row of profile icons can read as social sharing links, and the comments label comes from markup only. Switch it off with--no-classifieror[classifier] enabled = falseand link sections come from markup alone. The weights aretreetop-pagetype-v1, MIT licensed like the rest of the repository. schema/breadcrumbfails a page that shows a breadcrumb trail and declares noBreadcrumbList: at least one link the page classifier places in the breadcrumbs section, and no schema. A page without that signal gets the same info check as before. The rule's severity is now warning, so itswarnchecks (aBreadcrumbListwith no items, or positions out of order) count toward the warning totals instead of being advisory. See schema/breadcrumb.- Reports now include a Page structure block. It counts the links in each part of the audited pages (header, footer, navigation, sidebar, page content and more), shows what share of internal links is site furniture rather than page content, and counts how many pages the classifier calls product pages, blog posts, contact pages and so on. The console, text, Markdown and LLM reports print it in a new Report detail section at the very end, after the issues, the HTML report shows it as a Page structure section after the site details, and the JSON and XML reports carry it as data. In the console, text, Markdown and LLM reports the not-checked notices and the scan notes that used to sit under the title (rate limiting, scan scope, coverage and the like) moved into that section too, as a list; the HTML report keeps its notices at the top. It is informational and never scored. A report built from an older crawl has no block, so audit again to see it. See Report detail.
links/no-contextual-inboundsays where the links to a chrome-only page sit. An item readshttps://example.com/pricing, linked only from the footer and the navigationand carriesmeta.sectionscounts. Links in a post's own footer that the page treats as content are counted apart (, and 22 template links inside the page content), never named as a place the page is linked from. A crawl whose links have no section keeps the plain item. See links/no-contextual-inbound.links/broken-linkssays where on the page a broken internal link sits (the footer, the navigation, the comments, the page content), from landmarks and comment-thread markup. Each item also carriesmeta.sectionscounts. So do the items oflinks/anchor-text,links/broken-anchors,links/broken-external-links,links/https-downgrade,links/invalid-links,links/nofollow-internal,links/redirect-chains,links/tel-mailtoandlinks/weak-internal-links, each with a docs sentence on its rule page. A crawl whose links carry no section keeps every item as it was.- A broken link lists each page that carries it once, with how many of that page's links point at it and where on the page they sit:
from: /about (2 links, in the page content). A page that linked a broken target twice used to be listed twice. The summary counts links and pages apart (1 broken internal link(s) (4xx/5xx), found on 3 pages), andmeta.linkedFromnow counts pages. The HTML report expands a long list of pages inside the item, and the other formats say how many pages they leave out (+4 more pages) instead of pointing at a list above that never held them. The same holds forlinks/broken-external-links,links/broken-anchors(same-page links count every repeat) and thelinks-to-redirectcheck oflinks/redirect-chains. The JSON report carries the per-page detail assources(page,links,sections), and the XML report as alinkscount and<section>elements on each source page, where it also writes item metadata such assectionsas JSON instead of[object Object]. See source pages. #837 - A finding in a part of the page every page repeats (the site header, footer or navigation, a sidebar, the breadcrumbs, the pagination, or the newsletter signup, social share, business details or account links) names the region instead of listing every page: the same generic link text in the header of a 120-page site reads
In the site header, on 120 of 120 pages, a stale footer copyright year readsIn the site footer, on 148 of 150 pages, and a link to a redirecting docs page in the breadcrumbs readsIn the breadcrumbs, on 14 of 14 pages. A finding is shown this way when it is in the region on at least 80% of the pages that have that region (counted against those pages, not every page) and on at least 2 pages; pages where it is elsewhere are listed under the line, and its label drops thelinked in the footerphrase the line already says. The Markdown, text, LLM and console reports drop the page list for it, the HTML report keeps every page behind a collapsed list, and the JSON and XML reports keep the bounded list and addscope(region,pages,regionPages,otherPages). A finding in the page content, in a region on few pages, or in a report without page structure data keeps its page list.a11y/link-textnow records where each flagged link sits, matched to the page's link placements, and it, the link rules andcontent/stale-copyright(the footer) carry the pages per section asregions. Detection, severities and scores are unchanged. See findings in a shared page region. #846 - A finding on every page of one page type says so instead of listing the pages. The expected-schema check on a site with a documentation section reads
On all 9 documentation pages, orOn 9 of 11 documentation pageswhen it is most of them, in place of nine rows with the same template behind them. A finding is shown this way when all its pages are one page type, it is on at least 2 pages, and they are at least 80% of the audited pages of that type (counted from the Page types in the report's page structure block, not every page). The Markdown, text, LLM and console reports print the line and no page list, the HTML report keeps the pages behind a collapsed list, and the JSON and XML reports keep the bounded page list and addscopewithpageType,pagesandtypePages. A finding on mixed types, on one page, below the share, or in a report with no page structure keeps its page rows. Onlyschema/expected-typeis covered today. The Page types line now says "documentation pages" and "listing pages" where it said "docs pages" and "index pages". See schema/expected-type. #857 - The bundled agent skills are squirrelscan 1.21 and audit-website 2.7. The squirrelscan skill now covers confirming website ownership over MCP, paused recurring audits and the off-site redirect follow-up.
Fixed
- The Markdown report keeps ordinary message text readable. The escaping added for crawled text also wrote
\(,\)and\!into plain sentences (Title is 72 characters \(recommended: 30-60\)). Brackets, backticks,<,|, a backslash, an entity-shaped&and a leading block marker are still escaped, which is what stops a link, image, tag or heading from forming; parentheses,!, a mid-sentence>and a bare&are left as written. - A page of thousands of comment-class containers can no longer stall the classifier. Each container with a heading under it was checked against every
<h1>on the page, so 40,000 of them cost 8 seconds of CPU. The check now marks the ancestors of each heading once and costs the nodes it touches. - Backslashes no longer make a non-root URL look like the homepage. The page classifier's root-path rule now uses the platform URL parser, which treats a backslash as a path separator for web URLs and rejects malformed input instead of classifying it as the site root. (#903)
- The install channel now reaches install registration.
squirrel self installskips startup extras, soSQUIRREL_INSTALL_SOURCEwas gone by the first command that registers the install and every install reportedbinary.self installnow persists the validated value (^[a-z0-9-]{1,32}$, anything else is dropped) and registration sends it. install.sh stampsinstall-shwhen no source is set. - Installer failure reports name the host when curl cannot connect. A curl failure under
set -e(exit 6, 7, 28, 35, 52 or 56) reported only its code, so 82 identical reports could not be told apart. The anonymous report now carriescurl exit N reaching <host>: the host only, never a path, query or credentials. - The editor summary digest of a capped published report counts every issue. A rule with more than 25 issue classes lost the rest from its occurrence count, so a summary built from the stored report could under-count and re-rank issues against the one built from the full report. The digest now takes the true counts from the report's check tallies.
Security
- A crawled page can no longer add links or images to the Markdown report.
squirrel report --format markdownandsquirrel audit -f markdownnow escape the text the audited site controls: the pages in a check's page list (the path shown and the link), item labels and the pages an item was found on, check messages and names (which can quote the page, such as an ad URL or a misspelled word), the Entities section's names, ids and values from the site's JSON-LD, the site profile, a partial audit's reason, the audited URL line, and a detected technology's name and version. Before, a page whose path held](,)or![closed the page link early and added a link or a remote image of the site's choosing to the report a reader opens, and a label could open a heading or a list of its own. A stored report's generator version now prints on the scan line only when it looks like a version (squirrelscan/repo#3522).
Docs
- The Performance rules page counts 5 Reliability rules. The card said 2 after the broken-link rules moved into the category.
- Rule-option examples use the table the CLI reads. Fourteen rule-reference pages now put per-rule settings under
[rule_options."<id>"], not the ignored[rules."<id>"]. The docs check rejects the ignored table so copied examples keep changing audit behavior. (#1176) - The failed-audits guide covers the dashboard for an off-site redirect. Audit the destination instead, or move the website there, and undo a move within 20 seconds. See failed audits.
- Scheduled audits are documented as belonging to the organization. A schedule outlives the member who set it up, and Settings > Schedule names who did. See scheduled audits.
Update to this version
squirrelscan will auto-update, or run this command to update now: