Fix PDF decompression, add proper noun detection toggle, bump to 0.9.25
- 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
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Silent Send",
|
"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.",
|
"description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.",
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Silent Send",
|
"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.",
|
"description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"storage",
|
"storage",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "silent-send",
|
"name": "silent-send",
|
||||||
"version": "0.9.23",
|
"version": "0.9.25",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "Browser extension that substitutes personal data before sending to AI services",
|
"description": "Browser extension that substitutes personal data before sending to AI services",
|
||||||
|
|||||||
@@ -278,7 +278,7 @@
|
|||||||
// 4. Auto-detect: scan the FINAL text for unconfigured PII
|
// 4. Auto-detect: scan the FINAL text for unconfigured PII
|
||||||
// Auto-redact if enabled, otherwise just warn
|
// Auto-redact if enabled, otherwise just warn
|
||||||
if (settings.autoDetect !== false) {
|
if (settings.autoDetect !== false) {
|
||||||
const warnings = autoDetectPII(finalText, identity);
|
const warnings = autoDetectPII(finalText, identity, { detectProperNouns: settings.detectProperNouns === true });
|
||||||
if (warnings.length > 0) {
|
if (warnings.length > 0) {
|
||||||
// Auto-redact detected PII in the outbound text
|
// Auto-redact detected PII in the outbound text
|
||||||
if (settings.autoRedactDetected !== false) {
|
if (settings.autoRedactDetected !== false) {
|
||||||
@@ -454,7 +454,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoDetectPII(text, ident) {
|
function autoDetectPII(text, ident, opts) {
|
||||||
if (!text || text.length < 5) return [];
|
if (!text || text.length < 5) return [];
|
||||||
const hasContext = CONTEXT_WORDS_RE.test(text);
|
const hasContext = CONTEXT_WORDS_RE.test(text);
|
||||||
|
|
||||||
@@ -483,9 +483,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Proper noun heuristic — catch names, company names, project names
|
// Proper noun heuristic — catch names, company names, project names
|
||||||
// that aren't configured in identity
|
// that aren't configured in identity (opt-in, off by default)
|
||||||
|
if (opts?.detectProperNouns) {
|
||||||
const properNouns = detectProperNouns(text, configured);
|
const properNouns = detectProperNouns(text, configured);
|
||||||
findings.push(...properNouns);
|
findings.push(...properNouns);
|
||||||
|
}
|
||||||
|
|
||||||
// Deduplicate by value
|
// Deduplicate by value
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
@@ -1441,7 +1443,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const warnings = autoDetectPII(text, identity);
|
const warnings = autoDetectPII(text, identity, { detectProperNouns: settings.detectProperNouns === true });
|
||||||
if (warnings.length > 0) {
|
if (warnings.length > 0) {
|
||||||
showPreSendWarning(warnings, target);
|
showPreSendWarning(warnings, target);
|
||||||
} else if (preSendWarningEl) {
|
} else if (preSendWarningEl) {
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ const DocumentScanner = {
|
|||||||
const compressed = new Uint8Array(
|
const compressed = new Uint8Array(
|
||||||
[...streamData].map(c => c.charCodeAt(0))
|
[...streamData].map(c => c.charCodeAt(0))
|
||||||
);
|
);
|
||||||
const decompressed = this._inflateSync(compressed);
|
const decompressed = await this._inflateSync(compressed);
|
||||||
if (decompressed) {
|
if (decompressed) {
|
||||||
content = new TextDecoder('latin1').decode(decompressed);
|
content = new TextDecoder('latin1').decode(decompressed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ const DEFAULT_SETTINGS = {
|
|||||||
revealMode: false,
|
revealMode: false,
|
||||||
secretScanning: true,
|
secretScanning: true,
|
||||||
autoDetect: true,
|
autoDetect: true,
|
||||||
|
detectProperNouns: false,
|
||||||
autoRedactDetected: true,
|
autoRedactDetected: true,
|
||||||
autoAddDetected: true,
|
autoAddDetected: true,
|
||||||
maxLogEntries: 200,
|
maxLogEntries: 200,
|
||||||
|
|||||||
@@ -67,6 +67,16 @@
|
|||||||
<span class="toggle-slider"></span>
|
<span class="toggle-slider"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="setting-row">
|
||||||
|
<div>
|
||||||
|
<label>Flag capitalized words as possible names/orgs</label>
|
||||||
|
<p class="setting-desc">Warn when capitalized words mid-sentence may be names, company names, or project names not in your configured identity (high false-positive rate)</p>
|
||||||
|
</div>
|
||||||
|
<label class="toggle">
|
||||||
|
<input type="checkbox" id="detectProperNouns">
|
||||||
|
<span class="toggle-slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<div>
|
<div>
|
||||||
<label>Auto-redact detected PII on send</label>
|
<label>Auto-redact detected PII on send</label>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
$('#showHighlights').checked = settings.showHighlights || false;
|
$('#showHighlights').checked = settings.showHighlights || false;
|
||||||
$('#secretScanning').checked = settings.secretScanning !== false;
|
$('#secretScanning').checked = settings.secretScanning !== false;
|
||||||
$('#autoDetect').checked = settings.autoDetect !== false;
|
$('#autoDetect').checked = settings.autoDetect !== false;
|
||||||
|
$('#detectProperNouns').checked = settings.detectProperNouns === true;
|
||||||
$('#autoRedactDetected').checked = settings.autoRedactDetected !== false;
|
$('#autoRedactDetected').checked = settings.autoRedactDetected !== false;
|
||||||
$('#autoAddDetected').checked = settings.autoAddDetected !== false;
|
$('#autoAddDetected').checked = settings.autoAddDetected !== false;
|
||||||
$('#maxLogEntries').value = settings.maxLogEntries || 200;
|
$('#maxLogEntries').value = settings.maxLogEntries || 200;
|
||||||
@@ -273,6 +274,10 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
await Storage.saveSettings({ autoDetect: e.target.checked });
|
await Storage.saveSettings({ autoDetect: e.target.checked });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#detectProperNouns').addEventListener('change', async (e) => {
|
||||||
|
await Storage.saveSettings({ detectProperNouns: e.target.checked });
|
||||||
|
});
|
||||||
|
|
||||||
$('#autoRedactDetected').addEventListener('change', async (e) => {
|
$('#autoRedactDetected').addEventListener('change', async (e) => {
|
||||||
await Storage.saveSettings({ autoRedactDetected: e.target.checked });
|
await Storage.saveSettings({ autoRedactDetected: e.target.checked });
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user