From 433e5a7736c9eea7b4bb1214878897f095053be1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 29 Mar 2026 17:35:39 +0000 Subject: [PATCH] fix: filter out partial name substitutions from reveal pairs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smart engine records individual name parts ("Ademo"→"John", "Demo"→"Smith") AND the combined form ("Ademo Demo"→"John Smith") in sessionSubstitutions. The catch-all in buildRevealPairs was adding all of them, causing partial replacements that corrupted the DOM and made the cache oscillate between 4 and 0 pairs. Fix: skip session entries whose key is a substring of a longer entry (e.g. "ademo" is part of "ademo demo"). Only the combined form gets added as a reveal pair. Also: remove debug logging, improve cache with size tracking. https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT --- manifest.firefox.json | 2 +- manifest.json | 2 +- package.json | 2 +- src/content/content.js | 25 ++++++++++++++++++------- src/options/options.html | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/manifest.firefox.json b/manifest.firefox.json index 04b5adc..b077e8d 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "0.9.15", + "version": "0.9.16", "description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.", "browser_specific_settings": { "gecko": { diff --git a/manifest.json b/manifest.json index 4c4696e..717da76 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "0.9.15", + "version": "0.9.16", "description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.", "permissions": [ "storage", diff --git a/package.json b/package.json index 0646944..c3edf07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "silent-send", - "version": "0.9.15", + "version": "0.9.16", "private": true, "license": "MIT", "description": "Browser extension that substitutes personal data before sending to AI services", diff --git a/src/content/content.js b/src/content/content.js index 1b2c7ef..7f17e5a 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -1444,11 +1444,18 @@ // Catch-all: add any session substitution not already covered above. // This picks up combined names ("Ademo Demo" → "John Smith"), // auto-detected PII, and auto-redacted secrets. + // Skip entries that are substrings of a longer entry (e.g. "Ademo" + // is part of "Ademo Demo") to prevent partial replacements. + const allKeys = [...sessionSubstitutions.keys()]; for (const [key, entry] of sessionSubstitutions) { - if (!added.has(key)) { - pairs.push({ from: entry.replaced, to: entry.original }); - added.add(key); - } + if (added.has(key)) continue; + // Skip if this entry's replaced value is a substring of a longer one + const isPartOfLonger = allKeys.some(k => + k !== key && k.includes(key) && sessionSubstitutions.has(k) + ); + if (isPartOfLonger) continue; + pairs.push({ from: entry.replaced, to: entry.original }); + added.add(key); } pairs.sort((a, b) => b.from.length - a.from.length); @@ -1458,6 +1465,7 @@ // Cache — invalidate when identity/mappings change or new substitutions happen // Settings-only updates (e.g. reveal toggle) do NOT invalidate let _revealPairsCache = null; + let _lastSessionSubsSize = 0; window.addEventListener('message', (event) => { if (event.data?.type === 'ss:config-updated') { if (event.data.mappings || event.data.identity) _revealPairsCache = null; @@ -1466,7 +1474,12 @@ }); function getRevealPairs() { - if (!_revealPairsCache) _revealPairsCache = buildRevealPairs(); + // Rebuild if cache cleared OR if new substitutions were added + const currentSize = sessionSubstitutions.size; + if (!_revealPairsCache || currentSize !== _lastSessionSubsSize) { + _revealPairsCache = buildRevealPairs(); + _lastSessionSubsSize = currentSize; + } return _revealPairsCache; } @@ -1627,8 +1640,6 @@ // Reveal ALL text on the page + apply highlights function revealAllResponses() { - const pairs = getRevealPairs(); - console.log('[Silent Send] revealAllResponses — pairs:', pairs.length, pairs.map(p => `"${p.from}" → "${p.to}"`)); revealInElement(document.body); highlightMatches(document.body); } diff --git a/src/options/options.html b/src/options/options.html index 548a0d9..b1c3432 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -629,7 +629,7 @@