From 9c7e79b9b3fa3b9728769c111268527baf81baf6 Mon Sep 17 00:00:00 2001
From: Anthony Ettinger
Date: Fri, 12 Jun 2026 18:36:39 +0000
Subject: [PATCH] Never inject a duplicate stats.js tag when one is already
present
The "already installed" check only matched single-line tracker tags, so a
prettier-formatted multi-line slipped past it; the audience
installer also only inspected the top-ranked candidate file, missing
installs living in a lower-ranked one. Add hasTrackerReference (any
reference to the tracker origin's /stats.js counts as installed), apply it
in previewInstallAtPath and the install probe, and make the audience
installer scan all candidate files before injecting.
Co-Authored-By: Claude Fable 5
---
lib/github/install-audience.ts | 46 +++++++++++++++++++++++++---------
lib/github/install-tracker.ts | 21 ++++++++++++++++
tests/audience-hub.test.ts | 31 +++++++++++++++++++++++
3 files changed, 86 insertions(+), 12 deletions(-)
diff --git a/lib/github/install-audience.ts b/lib/github/install-audience.ts
index cbdc1266..855fa7e5 100644
--- a/lib/github/install-audience.ts
+++ b/lib/github/install-audience.ts
@@ -19,7 +19,11 @@ import {
openPullRequest,
putFile,
} from "./repos";
-import { findInstallCandidates, previewInstallAtPath } from "./install-tracker";
+import {
+ findInstallCandidates,
+ hasTrackerReference,
+ previewInstallAtPath,
+} from "./install-tracker";
const SITE_ORIGIN = env.siteUrl.replace(/\/$/, "");
const BRANCH_PREFIX = "crawlproof/audience-hub";
@@ -284,30 +288,48 @@ export async function installAudienceHub(
repo: input.repo,
rootPath: input.rootPath,
});
+
+ // Pass 1: if ANY candidate file already references stats.js, the
+ // tracker is installed — even when it lives in a lower-ranked file or
+ // is formatted across multiple lines. Never add a duplicate tag.
+ const contents = new Map();
for (const candidate of candidates) {
- const preview = await previewInstallAtPath({
+ const file = await getFileContent({
token: input.token,
owner: input.owner,
repo: input.repo,
path: candidate.path,
- projectId: input.projectId,
+ ref: base,
});
- if (preview.status === "already_installed") {
- trackerAlready = preview.path;
+ if (!file) continue;
+ contents.set(file.path, { sha: file.sha, content: file.content });
+ if (hasTrackerReference(file.content)) {
+ trackerAlready = file.path;
break;
}
- if (preview.status === "ready") {
- const file = await getFileContent({
+ }
+
+ // Pass 2: only when no candidate has it do we inject into the best one.
+ if (!trackerAlready) {
+ for (const candidate of candidates) {
+ const preview = await previewInstallAtPath({
token: input.token,
owner: input.owner,
repo: input.repo,
- path: preview.path,
- ref: base,
+ path: candidate.path,
+ projectId: input.projectId,
});
- if (file) {
- trackerEdit = { path: file.path, sha: file.sha, after: preview.after };
+ if (preview.status === "already_installed") {
+ trackerAlready = preview.path;
+ break;
+ }
+ if (preview.status === "ready") {
+ const file = contents.get(preview.path);
+ if (file) {
+ trackerEdit = { path: preview.path, sha: file.sha, after: preview.after };
+ }
+ break;
}
- break;
}
}
}
diff --git a/lib/github/install-tracker.ts b/lib/github/install-tracker.ts
index 990e1210..efb6ba2b 100644
--- a/lib/github/install-tracker.ts
+++ b/lib/github/install-tracker.ts
@@ -152,6 +152,17 @@ function injectBeforeBodyClose(
return updated;
}
+/**
+ * Loose duplicate guard: does this file reference our stats.js at all?
+ * The line-based regex below only matches single-line tags, so a
+ * prettier-formatted multi-line slips past it and we'd
+ * inject a second copy. Any reference to the tracker origin's /stats.js
+ * means "already installed" for injection purposes.
+ */
+export function hasTrackerReference(content: string): boolean {
+ return content.includes(`${TRACKER_ORIGIN}/stats.js`);
+}
+
function trackerTagLineRe() {
const origin = escapeRegExp(TRACKER_ORIGIN);
return new RegExp(
@@ -395,6 +406,11 @@ export async function previewInstallAtPath(input: {
if (normalized) {
return { status: "already_installed", path: file.path };
}
+ // Multi-line or unusually formatted tags won't match the line regex but
+ // are still an install — never inject a duplicate next to one.
+ if (hasTrackerReference(file.content)) {
+ return { status: "already_installed", path: file.path };
+ }
if (!/<\/body>/i.test(file.content)) {
return {
status: "not_a_template",
@@ -593,6 +609,11 @@ export async function installTracker(input: InstallInput): Promise/i.test(file.content)) {
return { kind: "hit", file };
}
diff --git a/tests/audience-hub.test.ts b/tests/audience-hub.test.ts
index 353e5efe..ea16b09d 100644
--- a/tests/audience-hub.test.ts
+++ b/tests/audience-hub.test.ts
@@ -7,6 +7,7 @@ import {
generatedClientHelper,
serverHelperPath,
} from "@/lib/github/install-audience";
+import { hasTrackerReference } from "@/lib/github/install-tracker";
describe("statusForEvent", () => {
it("maps lifecycle events to lifecycle statuses", () => {
@@ -123,6 +124,36 @@ describe("generated files", () => {
});
});
+describe("hasTrackerReference (duplicate-install guard)", () => {
+ // env.siteUrl is stubbed to http://localhost:3000 in tests/setup.ts.
+ const origin = "http://localhost:3000";
+
+ it("detects a single-line script tag", () => {
+ expect(
+ hasTrackerReference(
+ ``,
+ ),
+ ).toBe(true);
+ });
+
+ it("detects a prettier-formatted multi-line tag", () => {
+ const layout = `
+
hi