v0.3.0
Released 3 July 2026. Available on npm as orino-cli and @bynaree/orino.
npx orino-cli@latest auditThis release turns Orino from a single-page snapshot into a configurable, multi-page, CI-ready auditor. You can persist settings and silence false positives in a config file, audit a sample of pages across the whole site instead of just the homepage, catch routes that never made it into your sitemap (and sitemap URLs that no longer have a page), and wire the whole thing into a pipeline that fails only on real regressions.
Configuration file
Section titled “Configuration file”Orino now reads settings from a config file, checked in this order: orino.config.json, then .orino/config.json, then an "orino" key in package.json. Every field is optional, and the resolution order is CLI flag > environment variable > config file > built-in default — so a flag always wins, and the file is there for the settings you do not want to retype on every run.
{ "url": "https://example.com", "pages": 25, "ignore": ["thin-content", "app/studio/**"], "severity": { "thin-content": "info", "lcp-too-slow": "critical" }, "thresholds": { "lcp": 3000, "cls": 0.15, "inp": 300, "ttfb": 800 }, "failOn": "critical", "baseline": "./orino-baseline.json"}ignoresuppresses checks by ID ("thin-content") or by a glob matched against the finding location ("app/studio/**"). Suppressed checks report as skipped and are excluded from the score, exactly like any other skipped check.severitypromotes or demotes individual checks betweencritical,warning, andinfo. Aninfofinding still appears in the output but never affects the score — the clean way to acknowledge an issue without letting it move the number.thresholdsoverrides the Core Web Vitals warning thresholds (lcp/inp/ttfbin milliseconds,clsas a decimal).psiStrategyswitches PageSpeed Insights betweenmobile(default) anddesktop.
Run orino init to drop a fully commented orino.config.json template into the current directory, with every option documented inline. A malformed config file fails loudly with a clear message and exit code 1, rather than being silently ignored.
See the Configuration reference for the full schema.
Multi-page auditing
Section titled “Multi-page auditing”The new --pages <number> flag samples pages from your sitemap and runs the full URL check suite on each — metadata, on-page, structured data, canonical, and internal-link checks — instead of stopping at the homepage.
npx orino-cli audit --url https://example.com --pages 25- Pages linked from the homepage are prioritised, then the remaining sitemap URLs in order. Non-HTML entries (
.xml,.pdf, images) are filtered out, and the homepage is always included. - Pages are fetched in parallel in batches of five, with a two-second pause between batches and a sixty-second overall cap, so a large sitemap never hammers your origin.
- Pages that return a non-200 status are logged as an info finding and skipped — one dead URL never crashes the run.
- The score is calculated across every page combined, and in
--quietmode a per-page summary table is printed at the end. Every finding now records which page it came from.
Two checks that previously had to skip on live audits are now real:
- Duplicate titles and duplicate descriptions are flagged whenever any two sampled pages share the same value.
- Article schema is verified on sampled blog posts (
/blog/,/posts/,/articles/) rather than inferred from the homepage.
Default is --pages 0 (homepage only), so existing behaviour is unchanged unless you opt in.
Routes vs sitemap cross-check
Section titled “Routes vs sitemap cross-check”Orino is the only audit tool that holds both your codebase route list and your live sitemap, so it can diff the two. Two new architecture checks run in full mode (codebase + URL) on Next.js projects:
- Route missing from sitemap — a page exists in your codebase but not in
sitemap.xml. If it should be indexed, add it. Dynamic routes ([slug]), API routes, and special pages are excluded. - Sitemap URL has no route — a URL sits in
sitemap.xmlwith no matching route, usually a deleted page still lingering in the sitemap. CMS-style paths (/blog/,/posts/,/articles/) and content-ID URLs are excluded to avoid false positives on dynamically generated content.
Comparison strips domains and trailing slashes and is case-insensitive, and www and apex are treated as the same host. Outside full mode, both checks skip with an explanation.
CI story
Section titled “CI story”-
--fail-on <level>sets the severity at which Orino fails the build:critical(default),warning, orany. Exit0means the threshold was met,1means issues at or above it were found, and2is reserved for configuration errors (invalid flags, a missing baseline, no framework and no URL). -
--baseline <path>compares the run against a recorded baseline so CI fails only on new issues, not pre-existing ones. A finding counts as new when its check ID is not in the baseline. Generate one with the neworino baselinecommand:Terminal window npx orino-cli baseline --output ./orino-baseline.json -
JSON output (
--json) gains four fields for pipeline tooling:exitCode,newFindings,baselineCompared, andpagesAudited. -
A ready-made GitHub Actions workflow ships at
.github/workflows/orino.yml. It runs the audit, comments the score on pull requests, and fails the check when criticals are found.
Changed
Section titled “Changed”- Exit code semantics. Code
1now means “issues found at or above the--fail-onlevel” (defaultcritical, so the default behaviour is unchanged). Code2now also covers configuration errors — an invalid--fail-onvalue, a missing--baselinefile, or a malformed config file — in addition to the existing “no framework and no URL” case. - Cross-page uniqueness is no longer skipped on live audits when you pass
--pages; it becomes a real check across the sampled set. With a single page it still skips rather than guessing. - Core Web Vitals thresholds and PSI strategy are now configurable through the config file, where previously they were fixed at the mobile defaults.