From 57de5e8d534bbd82ddf0550262047973df7b6191 Mon Sep 17 00:00:00 2001 From: swwind Date: Sat, 22 Aug 2026 20:19:38 +0800 Subject: [PATCH 1/2] Clarify absorbed technology traces --- README.md | 22 +++++++++++----------- src/engine.js | 8 ++++---- src/popup.css | 2 +- src/popup.js | 4 ++-- src/signatures/bundlers.js | 2 +- src/signatures/meta.js | 4 ++-- test/run.mjs | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6238b04..d6880f6 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ toolbar icon into that project's logo. - Two rival frameworks on one page → 😈, and the popup lists everything. Click the icon for the details: what was found, which version (as precisely as -the page allows), what it was built on, and the exact byte patterns that led to -that conclusion. +the page allows), what evidence was absorbed, and the exact byte patterns that +led to that conclusion. ![The extension on anthropic.com: the toolbar icon has become the jQuery mark, and the popup reads "jQuery v3.5.1 - with Rspack", listing jQuery under UI @@ -81,10 +81,10 @@ Visit a few sites and watch the icon: | Site | Expected | | --- | --- | -| | Next.js, built on React + Turbopack | -| | VitePress, built on Vue + Vite | +| | Next.js, absorbing React + Turbopack traces | +| | VitePress, absorbing Vue + Vite traces | | | Angular 22.1.3 | -| | SvelteKit, built on Svelte 5 + Vite | +| | SvelteKit, absorbing Svelte 5 + Vite traces | | | jQuery 4.0.0 | | | Svelte 5, with jQuery, Stimulus and webpack | @@ -185,12 +185,12 @@ first entry of an array (Lit's `litElementVersions`) and `.v` as a `Set` which is what stops SvelteKit's build id, a 13-digit timestamp sitting in a property called `version`, being reported as a release. -### Built on +### Absorbed evidence Next.js *is* React and ships webpack or Turbopack. Reporting all three as separate findings would be technically true and useless, so a meta-framework -absorbs what is intrinsic to it and the popup shows those as chips under the -card, evidence and all. +absorbs what is intrinsic to it and the popup shows those traces as chips under +the card, evidence and all. Only intrinsic relationships are folded in. React on webpack is a *choice*, not a fact about React, so those stay two findings — and Astro keeps its islands @@ -209,9 +209,9 @@ React is a normal Tuesday, not a contradiction. hardly ever the most interesting thing about a page, so anything else found beside it wins. Everything else sorts on the weight of its evidence, which is what puts Alpine ahead of the Preact-based search widget on alpinejs.dev. -- **Rspack ≤ 1.x is webpack, byte for byte.** Rspack ships a deliberately +- **Rspack ≤ 1.x leaves webpack-shaped traces.** Rspack ships a deliberately webpack-compatible runtime: 0.7 and 1.x emit `webpackChunk*` and - `data-webpack` exactly like webpack 5. The `ruid` stamp rescues 1.0+, but an + `data-webpack` markers like webpack 5. The `ruid` stamp rescues 1.0+, but an Rspack 0.x site is reported as webpack 5 and there is no signal to do better. Rspack 2's ESM chunks are the opposite case: no chunk global and no `data-rspack`, just the exported `__rspack_esm_id`/`__rspack_esm_ids` names — @@ -300,7 +300,7 @@ checks they are loadable. That is the whole of it. worse than no patterns. 2. Add an entry to the right file in `src/signatures/`, with `seen:` noting what you checked it against. Set `category`, and add a relation at the bottom of - the file if it is built on something else. + the file if another finding should be absorbed into it. 3. Put the project's own logo in as `icons/src/.svg` (or `.png` if that is all they publish) and run `npm run icons`, which writes `icons/.png` at 128 px. That one file is what the repo keeps; `npm run build` derives the diff --git a/src/engine.js b/src/engine.js index 9df070d..a947e07 100644 --- a/src/engine.js +++ b/src/engine.js @@ -34,7 +34,7 @@ return root.StackSignatures || []; } - /** Relations pushed by the signature files: `id` is built on `builtOn`. */ + /** Relations pushed by the signature files: `id` absorbs `builtOn`. */ function relations() { return root.StackRelations || []; } @@ -232,12 +232,12 @@ } /** - * Fold a technology's evidence into the thing that is built on top of it. + * Fold one technology's evidence into a more specific finding. * * Next.js *is* React and ships webpack or Turbopack; reporting all three as * separate findings would be technically true and useless. Only intrinsic - * relationships belong here -- React on webpack is a choice, not a fact - * about React, so those stay two findings. + * relationships and deliberate compatibility traces belong here -- React on + * webpack is a choice, not a fact about React, so those stay two findings. */ function applyRelations(detections, notes) { const byId = new Map(detections.map((d) => [d.id, d])); diff --git a/src/popup.css b/src/popup.css index 57fa78d..5481dea 100644 --- a/src/popup.css +++ b/src/popup.css @@ -129,7 +129,7 @@ main { flex: none; } -/* ---------- "built on" strip ---------- */ +/* ---------- absorbed evidence strip ---------- */ .built-on { display: flex; diff --git a/src/popup.js b/src/popup.js index f57fc94..67cb6b7 100644 --- a/src/popup.js +++ b/src/popup.js @@ -55,10 +55,10 @@ ); } - /** The technologies a detection was folded out of, as a compact strip. */ + /** The technologies whose evidence was folded into this detection. */ function renderBuiltOn(d) { const strip = el('div', { className: 'built-on' }, [ - el('span', { className: 'built-on-label', textContent: 'built on' }), + el('span', { className: 'built-on-label', textContent: 'absorbed' }), ]); for (const b of d.builtOn) { strip.append( diff --git a/src/signatures/bundlers.js b/src/signatures/bundlers.js index 8743fef..3487e00 100644 --- a/src/signatures/bundlers.js +++ b/src/signatures/bundlers.js @@ -422,7 +422,7 @@ { id: 'rspack', builtOn: ['webpack'], - note: "Rspack ships a webpack-compatible runtime, so this page's webpack markers are attributed to Rspack.", + note: "Rspack ships webpack-compatible runtime markers, so this page's webpack traces are attributed to Rspack.", }, { id: 'vite', diff --git a/src/signatures/meta.js b/src/signatures/meta.js index a705fde..ce6d544 100644 --- a/src/signatures/meta.js +++ b/src/signatures/meta.js @@ -531,12 +531,12 @@ { id: 'vitepress', builtOn: ['vue', 'vite', 'rollup', 'esbuild'], - note: 'VitePress is a Vue site generator built on Vite, so those markers are attributed to VitePress.', + note: 'VitePress is a Vue site generator that uses Vite, so those markers are attributed to VitePress.', }, { id: 'rspress', builtOn: ['react', 'rspack', 'webpack'], - note: 'Rspress is a React site generator built on Rsbuild/Rspack, so those markers are attributed to Rspress.', + note: 'Rspress is a React site generator that uses Rsbuild/Rspack, so those markers are attributed to Rspress.', }, { id: 'astro', diff --git a/test/run.mjs b/test/run.mjs index ba33f42..1e8d547 100644 --- a/test/run.mjs +++ b/test/run.mjs @@ -53,8 +53,8 @@ const CASES = [ // A Next.js webpack build: the Next markers in the chunk registry win over // the plain webpack reading, and webpack arrives folded in. { dir: 'next-webpack', primary: 'next', version: null, builtOn: ['webpack'], only: true }, - // Rspack 1.x stamps its exact version into the runtime, which is the only - // thing separating it from webpack 5 -- its runtime is webpack's otherwise. + // Rspack 1.x stamps its exact version into a webpack-compatible runtime, + // which is what separates these markers from plain webpack 5. { dir: 'rspack1', primary: 'rspack', version: '1.5.8', builtOn: ['webpack'], only: true }, { dir: 'rspack2', primary: 'rspack', version: '≥ 2', only: true }, { dir: 'turbopack', primary: 'turbopack', version: null, only: true }, From 58b3372f717bd6519d52f515340bb7a92194720d Mon Sep 17 00:00:00 2001 From: swwind Date: Sat, 22 Aug 2026 20:21:52 +0800 Subject: [PATCH 2/2] Run push CI only on main --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cff1dbf..1555507 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: push: + branches: [main] pull_request: workflow_dispatch: