From eec0d52681aae53accad628b0fbd137557eb85f9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 27 Mar 2026 20:53:53 +0000 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20PPI=20warning=20accept/ignore=20butt?= =?UTF-8?q?ons=20=E2=80=94=20v2.0.14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accept (+) button: - Was reading raw storage (getStorageData) which returns encrypted blobs when encryption is enabled, silently failing to add mappings - Fixed: adds directly to the local mappings array and persists via setStorageData (storage bridge handles encryption transparently) Auto-detect false positives: - Was only checking identity values, not explicit mappings — values already in the mappings table still got flagged as unconfigured PPI - Fixed: now adds all mapping real/substitute values to the skip set Ignore button: - Changed from plain text link to grey pill button for better UX - Still persists permanently via ss_ignored_ppi in storage https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn --- manifest.firefox.json | 2 +- manifest.json | 2 +- package.json | 2 +- src/content/content.css | 7 ++++--- src/content/content.js | 28 +++++++++++++++------------- src/options/options.html | 2 +- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/manifest.firefox.json b/manifest.firefox.json index 0f9077d..880e480 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "2.0.13", + "version": "2.0.14", "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 9800648..8ff33ee 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "2.0.13", + "version": "2.0.14", "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 0a2ff37..2dcb4a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "silent-send", - "version": "2.0.13", + "version": "2.0.14", "private": true, "license": "BSL-1.1", "description": "Browser extension that substitutes personal data before sending to AI services", diff --git a/src/content/content.css b/src/content/content.css index 8f287d9..d6d9fd3 100644 --- a/src/content/content.css +++ b/src/content/content.css @@ -221,13 +221,14 @@ .ss-ps-add:disabled { border-color: #333; cursor: default; } .ss-ps-ignore { - background: none; + background: #4b5563; border: none; - color: #6b7280; + color: #d1d5db; font-size: 9px; cursor: pointer; flex-shrink: 0; - padding: 2px 4px; + padding: 3px 6px; + border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px; } diff --git a/src/content/content.js b/src/content/content.js index c7e5031..e4cb462 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -578,7 +578,7 @@ if (!text || text.length < 5) return []; const hasContext = CONTEXT_WORDS_RE.test(text); - // Build skip set from configured values + // Build skip set from configured values (identity + explicit mappings) const configured = new Set(); if (ident) { const addAll = (arr, key) => (arr || []).forEach(item => { @@ -588,6 +588,11 @@ addAll(ident.names); addAll(ident.emails); addAll(ident.usernames); addAll(ident.hostnames); addAll(ident.phones); } + // Also skip values that are already in explicit mappings + for (const m of mappings) { + if (m.real) configured.add(m.real.toLowerCase()); + if (m.substitute) configured.add(m.substitute.toLowerCase()); + } const findings = []; for (const pat of PPI_PATTERNS) { @@ -1848,13 +1853,12 @@ const items = warnings.slice(0, 8).map((w, i) => { const fake = generateFake(w.name, w.value); const displayVal = w.value.length > 25 ? w.value.slice(0, 22) + '...' : w.value; + const displayFake = fake.length > 20 ? fake.slice(0, 17) + '...' : fake; return `
${w.name} ${displayVal} ${w.hint} - ${settings.autoAddDetected !== false - ? `` - : ''} +
`; }).join(''); @@ -1881,28 +1885,26 @@ preSendWarningEl.classList.remove('visible'); }); - // Auto-add buttons + // Auto-add buttons (+) preSendWarningEl.querySelectorAll('.ss-ps-add').forEach(btn => { btn.addEventListener('click', async () => { const real = decodeURIComponent(btn.dataset.real); const fake = decodeURIComponent(btn.dataset.fake); const cat = btn.dataset.cat || 'general'; - // Add to mappings via storage - const result = await getStorageData('ss_mappings'); - const currentMappings = result || []; - currentMappings.push({ + // Add to local mappings array (used by the fetch interceptor) + const newMapping = { id: crypto.randomUUID(), real, substitute: fake, category: cat, caseSensitive: false, enabled: true, createdAt: Date.now(), - }); - await setStorageData('ss_mappings', currentMappings); + }; + mappings.push(newMapping); - // Update local mappings so the fetch interceptor uses them immediately - mappings = currentMappings; + // Persist via storage bridge (handles encryption transparently) + setStorageData('ss_mappings', mappings); // Replace the PPI value in the current input right now if (inputEl) { diff --git a/src/options/options.html b/src/options/options.html index a2b68e0..afb9870 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -591,7 +591,7 @@ From 9a1189659bdd532f94d7abe783f9374b2b1d4d7b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 27 Mar 2026 21:05:32 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20reveal/highlight=20scoped=20to=20cha?= =?UTF-8?q?t=20area=20only=20+=20remove=20footer=20link=20=E2=80=94=20v2.0?= =?UTF-8?q?.14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reveal mode and highlights were replacing text in sidebars, navigation, headers, repo names, and other non-chat UI elements. Now skips: -