pagetrace 0.14.0 → 0.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,85 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
  While the version is below 1.0.0, breaking changes ship in a minor release.
8
8
 
9
+ ## [0.14.5] - 2026-09-08
10
+
11
+ ### Fixed
12
+
13
+ - `extractLlmsTxt` used `Buffer.byteLength`, which does not exist in a browser,
14
+ so any page on a site that actually has an `/llms.txt` crashed the checker
15
+ with "Buffer is not defined". It counts UTF-8 bytes with `TextEncoder` now —
16
+ the same number, available everywhere. `extract.ts` is meant to be pure and
17
+ bundleable, and this was the one line that was not.
18
+ - The scan log blamed the fetch for failures that happened after it, because
19
+ the error handler settled a fixed step rather than the one still running.
20
+
21
+ ## [0.14.4] - 2026-09-08
22
+
23
+ ### Added
24
+
25
+ - Whole-site mode in the checker. It crawls from the sitemap the way
26
+ `pagetrace audit --url` does and runs every rule over the result, so the
27
+ cross-page findings a single page cannot produce — duplicate titles, hreflang
28
+ reciprocity, dead internal links, sitemap health — finally appear on the site.
29
+ Findings are grouped by code and message and list the routes they touch, which
30
+ is how the CLI's own report aggregates.
31
+
32
+ ### Fixed
33
+
34
+ - Every request now has an eight-second deadline. A proxy that is down hangs
35
+ rather than refusing, and the chain sat waiting on it.
36
+ - robots.txt and sitemap.xml were fetched through a reader that renders what it
37
+ fetches, so they came back as HTML documents and stopped looking like
38
+ themselves. Those requests now ask for text, and a sitemap whose XML did not
39
+ survive has its URLs recovered from the body rather than being given up on.
40
+ - Switching scope left the other scope's score standing under a heading that no
41
+ longer described it.
42
+
43
+ ## [0.14.3] - 2026-09-08
44
+
45
+ ### Fixed
46
+
47
+ - The checker could not fetch anything: it depended on one public CORS proxy,
48
+ and that proxy was returning Cloudflare 520s for every URL. It now tries
49
+ r.jina.ai, allorigins and codetabs in order and takes the first that answers
50
+ with HTML, so one service having a bad day no longer takes the feature down.
51
+
52
+ ### Added
53
+
54
+ - A scan log. The check narrates itself as it runs — each request, its size and
55
+ which proxy served it, then the rule pass — instead of leaving a dead page
56
+ during the seconds it takes. A progress bar tracks the steps, the report dims
57
+ while it works, the score counts up to its value, and a category holding a
58
+ blocker gets a coloured edge.
59
+ - Example URLs to try, so the page can be used without owning a site.
60
+
61
+ ## [0.14.2] - 2026-09-08
62
+
63
+ ### Added
64
+
65
+ - An SEO checker page on the website: enter a URL and get all twenty-three
66
+ page-level checks scored and grouped, passes shown alongside failures. It
67
+ fetches robots.txt and llms.txt too, so the site-level checks answer from
68
+ evidence; anything not fetched reads "not checked" rather than passing or
69
+ failing.
70
+
71
+ ### Fixed
72
+
73
+ - `npm run build:site` wrote into `docs/`, which tsup cleans, so building the
74
+ site deleted the site. Its output now has its own directory, `docs/assets/`,
75
+ which is the only thing the build can remove. The Pages deploy would have
76
+ published a lone JavaScript file.
77
+
78
+ ## [0.14.1] - 2026-09-08
79
+
80
+ ### Added
81
+
82
+ - A website at [shyamexe.github.io/pagetrace](https://shyamexe.github.io/pagetrace/), built from
83
+ `docs/` and deployed by GitHub Pages. Its playground compiles `extract`, `audit` and `diff` into
84
+ the page via a new `src/browser.ts` entry, so it runs the same rules as the CLI rather than a
85
+ reimplementation of them. `npm run build:site` produces the bundle, and the Pages workflow rebuilds
86
+ it on every deploy so it cannot drift from the rules it claims to run.
87
+
9
88
  ## [0.14.0] - 2026-09-08
10
89
 
11
90
  ### Added
@@ -385,6 +464,11 @@ Initial release. `snapshot`, `check` and `audit` commands; filesystem and HTTP
385
464
  crawling; diff classified by transition; absolute, cross-page and hreflang audit
386
465
  rules; pretty, JSON, markdown, GitHub and HTML reporters.
387
466
 
467
+ [0.14.5]: https://github.com/shyamexe/pagetrace/compare/v0.14.0...v0.14.5
468
+ [0.14.4]: https://github.com/shyamexe/pagetrace/commit/ec2a5e2cd590
469
+ [0.14.3]: https://github.com/shyamexe/pagetrace/commit/c45cfb49e265
470
+ [0.14.2]: https://github.com/shyamexe/pagetrace/commit/b3aa77388ee9
471
+ [0.14.1]: https://github.com/shyamexe/pagetrace/commit/7cc91383ed7a
388
472
  [0.14.0]: https://github.com/shyamexe/pagetrace/compare/v0.13.0...v0.14.0
389
473
  [0.13.0]: https://github.com/shyamexe/pagetrace/compare/v0.12.0...v0.13.0
390
474
  [0.12.0]: https://github.com/shyamexe/pagetrace/compare/v0.11.0...v0.12.0
package/README.md CHANGED
@@ -19,6 +19,10 @@ npm install -D pagetrace
19
19
 
20
20
  Requires Node 20.19 or newer. No native modules, three small dependencies.
21
21
 
22
+ ## Playground
23
+
24
+ Try the rules without installing anything: **[shyamexe.github.io/pagetrace](https://shyamexe.github.io/pagetrace/)**. The site compiles `extract`, `audit` and `diff` — the pure half of this package — into the page, so it runs the same rules the CLI does, in your browser, with nothing uploaded.
25
+
22
26
  ## Commands
23
27
 
24
28
  | Command | Answers | Crawls | Exit 1 when |
package/dist/cli.cjs CHANGED
@@ -1549,7 +1549,7 @@ function extractLinks(html) {
1549
1549
  }
1550
1550
  function extractLlmsTxt(body) {
1551
1551
  const sections = body.split(/\r?\n/).filter((line) => line.startsWith("## ")).map((line) => line.slice(3).trim());
1552
- return { present: true, sections, bytes: Buffer.byteLength(body, "utf8") };
1552
+ return { present: true, sections, bytes: new TextEncoder().encode(body).length };
1553
1553
  }
1554
1554
  var XML_ENTITIES = {
1555
1555
  amp: "&",
@@ -2210,11 +2210,11 @@ Commit both files, then run \`pagetrace check ${flags.dir ? `--dir ${flags.dir}`
2210
2210
  });
2211
2211
  cli.command("update", "Check npm for a newer pagetrace and install it").option("--check", "Only report whether an update exists").action(async (flags) => {
2212
2212
  const latest = await latestVersion("pagetrace");
2213
- if (!isNewer(latest, "0.14.0")) {
2214
- console.log(import_picocolors2.default.green(`pagetrace ${"0.14.0"} is the latest version.`));
2213
+ if (!isNewer(latest, "0.14.5")) {
2214
+ console.log(import_picocolors2.default.green(`pagetrace ${"0.14.5"} is the latest version.`));
2215
2215
  return;
2216
2216
  }
2217
- console.log(import_picocolors2.default.yellow(`Update available: ${"0.14.0"} \u2192 ${latest}`));
2217
+ console.log(import_picocolors2.default.yellow(`Update available: ${"0.14.5"} \u2192 ${latest}`));
2218
2218
  if (flags.check) return;
2219
2219
  if (process.argv[1]?.startsWith(process.cwd())) {
2220
2220
  console.log(
@@ -2232,7 +2232,7 @@ cli.command("update", "Check npm for a newer pagetrace and install it").option("
2232
2232
  console.log(import_picocolors2.default.green(`Updated to pagetrace ${latest}.`));
2233
2233
  });
2234
2234
  cli.help();
2235
- cli.version("0.14.0");
2235
+ cli.version("0.14.5");
2236
2236
  async function main() {
2237
2237
  try {
2238
2238
  cli.parse(process.argv, { run: false });
package/dist/cli.js CHANGED
@@ -1526,7 +1526,7 @@ function extractLinks(html) {
1526
1526
  }
1527
1527
  function extractLlmsTxt(body) {
1528
1528
  const sections = body.split(/\r?\n/).filter((line) => line.startsWith("## ")).map((line) => line.slice(3).trim());
1529
- return { present: true, sections, bytes: Buffer.byteLength(body, "utf8") };
1529
+ return { present: true, sections, bytes: new TextEncoder().encode(body).length };
1530
1530
  }
1531
1531
  var XML_ENTITIES = {
1532
1532
  amp: "&",
@@ -2187,11 +2187,11 @@ Commit both files, then run \`pagetrace check ${flags.dir ? `--dir ${flags.dir}`
2187
2187
  });
2188
2188
  cli.command("update", "Check npm for a newer pagetrace and install it").option("--check", "Only report whether an update exists").action(async (flags) => {
2189
2189
  const latest = await latestVersion("pagetrace");
2190
- if (!isNewer(latest, "0.14.0")) {
2191
- console.log(pc2.green(`pagetrace ${"0.14.0"} is the latest version.`));
2190
+ if (!isNewer(latest, "0.14.5")) {
2191
+ console.log(pc2.green(`pagetrace ${"0.14.5"} is the latest version.`));
2192
2192
  return;
2193
2193
  }
2194
- console.log(pc2.yellow(`Update available: ${"0.14.0"} \u2192 ${latest}`));
2194
+ console.log(pc2.yellow(`Update available: ${"0.14.5"} \u2192 ${latest}`));
2195
2195
  if (flags.check) return;
2196
2196
  if (process.argv[1]?.startsWith(process.cwd())) {
2197
2197
  console.log(
@@ -2209,7 +2209,7 @@ cli.command("update", "Check npm for a newer pagetrace and install it").option("
2209
2209
  console.log(pc2.green(`Updated to pagetrace ${latest}.`));
2210
2210
  });
2211
2211
  cli.help();
2212
- cli.version("0.14.0");
2212
+ cli.version("0.14.5");
2213
2213
  async function main() {
2214
2214
  try {
2215
2215
  cli.parse(process.argv, { run: false });
package/dist/index.cjs CHANGED
@@ -988,7 +988,7 @@ function extractLinks(html) {
988
988
  }
989
989
  function extractLlmsTxt(body) {
990
990
  const sections = body.split(/\r?\n/).filter((line) => line.startsWith("## ")).map((line) => line.slice(3).trim());
991
- return { present: true, sections, bytes: Buffer.byteLength(body, "utf8") };
991
+ return { present: true, sections, bytes: new TextEncoder().encode(body).length };
992
992
  }
993
993
  var XML_ENTITIES = {
994
994
  amp: "&",
package/dist/index.js CHANGED
@@ -913,7 +913,7 @@ function extractLinks(html) {
913
913
  }
914
914
  function extractLlmsTxt(body) {
915
915
  const sections = body.split(/\r?\n/).filter((line) => line.startsWith("## ")).map((line) => line.slice(3).trim());
916
- return { present: true, sections, bytes: Buffer.byteLength(body, "utf8") };
916
+ return { present: true, sections, bytes: new TextEncoder().encode(body).length };
917
917
  }
918
918
  var XML_ENTITIES = {
919
919
  amp: "&",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagetrace",
3
- "version": "0.14.0",
3
+ "version": "0.14.5",
4
4
  "description": "Baseline your site's SEO and AEO surface, diff every build against it, and fail CI on regressions.",
5
5
  "main": "./dist/index.cjs",
6
6
  "scripts": {
@@ -10,7 +10,8 @@
10
10
  "test:watch": "vitest",
11
11
  "coverage": "vitest run --coverage",
12
12
  "typecheck": "tsc --noEmit",
13
- "prepublishOnly": "npm run typecheck && npm run test && npm run build"
13
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build",
14
+ "build:site": "tsup src/browser.ts --format iife --global-name pagetrace --platform browser --minify --no-dts --out-dir docs/assets"
14
15
  },
15
16
  "keywords": [
16
17
  "seo",