From 4b494b5eaba75df2564c81e89d5293b1c3d385f3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 29 Mar 2026 21:09:49 +0000 Subject: [PATCH] Fix PDF decompression, add proper noun detection toggle, bump to 0.9.25 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - document-scanner.js: Add missing await on _inflateSync() call — FlateDecode streams were not being decompressed because the async function was called without await, causing decompressed to hold a Promise instead of data - content.js, storage.js, options.html, options.js: Gate proper noun / capital letter detection behind a new detectProperNouns setting (default off); was previously always-on causing noisy false-positive warnings on AI thinking output and common capitalized words - Bump version 0.9.23 → 0.9.25 https://claude.ai/code/session_01ReZUeR1nrYzJeX7fTqwXMw --- manifest.firefox.json | 2 +- manifest.json | 2 +- package.json | 2 +- src/content/content.js | 14 ++++++++------ src/lib/document-scanner.js | 2 +- src/lib/storage.js | 1 + src/options/options.html | 10 ++++++++++ src/options/options.js | 5 +++++ 8 files changed, 28 insertions(+), 10 deletions(-) diff --git a/manifest.firefox.json b/manifest.firefox.json index 2142180..bfe133a 100644 --- a/manifest.firefox.json +++ b/manifest.firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "0.9.23", + "version": "0.9.25", "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 c146340..1bc547e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Silent Send", - "version": "0.9.23", + "version": "0.9.25", "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 97b8b2b..2c731e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "silent-send", - "version": "0.9.23", + "version": "0.9.25", "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 407e6cf..3a24f8b 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -278,7 +278,7 @@ // 4. Auto-detect: scan the FINAL text for unconfigured PII // Auto-redact if enabled, otherwise just warn if (settings.autoDetect !== false) { - const warnings = autoDetectPII(finalText, identity); + const warnings = autoDetectPII(finalText, identity, { detectProperNouns: settings.detectProperNouns === true }); if (warnings.length > 0) { // Auto-redact detected PII in the outbound text if (settings.autoRedactDetected !== false) { @@ -454,7 +454,7 @@ }); } - function autoDetectPII(text, ident) { + function autoDetectPII(text, ident, opts) { if (!text || text.length < 5) return []; const hasContext = CONTEXT_WORDS_RE.test(text); @@ -483,9 +483,11 @@ } // Proper noun heuristic — catch names, company names, project names - // that aren't configured in identity - const properNouns = detectProperNouns(text, configured); - findings.push(...properNouns); + // that aren't configured in identity (opt-in, off by default) + if (opts?.detectProperNouns) { + const properNouns = detectProperNouns(text, configured); + findings.push(...properNouns); + } // Deduplicate by value const seen = new Set(); @@ -1441,7 +1443,7 @@ return; } - const warnings = autoDetectPII(text, identity); + const warnings = autoDetectPII(text, identity, { detectProperNouns: settings.detectProperNouns === true }); if (warnings.length > 0) { showPreSendWarning(warnings, target); } else if (preSendWarningEl) { diff --git a/src/lib/document-scanner.js b/src/lib/document-scanner.js index fa7aaee..7135877 100644 --- a/src/lib/document-scanner.js +++ b/src/lib/document-scanner.js @@ -265,7 +265,7 @@ const DocumentScanner = { const compressed = new Uint8Array( [...streamData].map(c => c.charCodeAt(0)) ); - const decompressed = this._inflateSync(compressed); + const decompressed = await this._inflateSync(compressed); if (decompressed) { content = new TextDecoder('latin1').decode(decompressed); } diff --git a/src/lib/storage.js b/src/lib/storage.js index 75083b2..23b4122 100644 --- a/src/lib/storage.js +++ b/src/lib/storage.js @@ -36,6 +36,7 @@ const DEFAULT_SETTINGS = { revealMode: false, secretScanning: true, autoDetect: true, + detectProperNouns: false, autoRedactDetected: true, autoAddDetected: true, maxLogEntries: 200, diff --git a/src/options/options.html b/src/options/options.html index df3cb49..87c3eb8 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -67,6 +67,16 @@ +
+
+ +

Warn when capitalized words mid-sentence may be names, company names, or project names not in your configured identity (high false-positive rate)

+
+ +
diff --git a/src/options/options.js b/src/options/options.js index e4bc55c..08964b0 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -22,6 +22,7 @@ document.addEventListener('DOMContentLoaded', async () => { $('#showHighlights').checked = settings.showHighlights || false; $('#secretScanning').checked = settings.secretScanning !== false; $('#autoDetect').checked = settings.autoDetect !== false; + $('#detectProperNouns').checked = settings.detectProperNouns === true; $('#autoRedactDetected').checked = settings.autoRedactDetected !== false; $('#autoAddDetected').checked = settings.autoAddDetected !== false; $('#maxLogEntries').value = settings.maxLogEntries || 200; @@ -273,6 +274,10 @@ document.addEventListener('DOMContentLoaded', async () => { await Storage.saveSettings({ autoDetect: e.target.checked }); }); + $('#detectProperNouns').addEventListener('change', async (e) => { + await Storage.saveSettings({ detectProperNouns: e.target.checked }); + }); + $('#autoRedactDetected').addEventListener('change', async (e) => { await Storage.saveSettings({ autoRedactDetected: e.target.checked }); });