Bug 1: popup.html had duplicate id="optAutoRedact" on both the
Auto Redact toggle and Auto-redact Detected PII toggle. The second
overwrote the first, making the Auto Redact setting uncontrollable.
Fixed by giving the second toggle id="optAutoRedactDetected".
Bug 2: injector.js hardcoded activity log trim to 100, ignoring the
user's maxLogEntries setting. Now reads the setting from storage.
Added test-suite.html with 35+ tests covering storage, encryption,
sync (encryption-mandatory flows), auto-redact (built-in + custom
patterns), substitution engine, smart patterns, and auto-detect.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
PII (Personally Identifiable Information) is the correct standard term.
Renamed all instances — comments, UI labels, variable names, function
names (autoDetectPPI → autoDetectPII, scanInputForPPI → scanInputForPII,
ppiWarnings → piiWarnings), CSS comments, README, and options page.
Added Ko-fi donation section to README and Options footer. Tone: no
obligation, no warranty, no influence on updates — just appreciation.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
Commercial use is no longer permitted under the license. The BSL-1.1
still converts to MIT on March 26, 2030. All disclaimer and liability
language retained — applies to all users regardless.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
- LICENSE: expanded warranty disclaimer covering silent failures from
third-party changes, coverage gaps, regulatory non-compliance, and
commercial licensee expectations. Explicit limitation of liability
for privacy breaches, identity theft, and regulatory penalties.
- PRIVACY.md: added limitations section covering third-party changes,
coverage gaps, user responsibility, and compliance disclaimer.
- README.md: detailed disclaimer with specific scenarios — site API
changes, coverage gaps, user verification responsibility, and
commercial license scope.
- Popup: expanded footer warning about third-party changes and user
responsibility.
- Options page: added footer disclaimer with LICENSE link, updated
version to 0.9.0.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
Users can now define custom regex patterns for proprietary token formats,
internal URLs with keys, or any secret the built-in scanner doesn't cover.
Patterns are added/toggled/removed from the Options page and apply to both
the live interception (content.js) and the Test tab (popup.js).
Renamed all user-facing "Secret scanning" labels to "Auto Redact" across
popup and options. Internal variable names (secretScanning, SecretScanner)
kept for backwards compatibility with stored settings.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
- Edit domains inline (pencil icon, saves on Enter)
- Suggested domains: clickable chips for popular AI/dev/collab sites
- Bulk add: paste multiple domains at once (one per line or comma-separated)
- Popup domain management: add/remove/suggestions directly from the popup
- Permission revoke on removal + suggested list updates dynamically
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
New AI sites: Perplexity, Copilot, DeepSeek, HuggingChat, Poe
Developer/support: GitHub, GitLab, Reddit (www + old), Stack Overflow, Pastebin
The existing interception is service-agnostic — it scans all JSON strings
in POST/PUT/PATCH requests through the 4-stage substitution pipeline.
No site-specific handling needed; all sites use the same method.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
Replace tab-load-only injection with scripting.registerContentScripts()
so custom domains inject at document_start (like built-in sites) and
persist across service worker restarts. Scripts re-register automatically
when domains change. Removed domains now revoke browser permissions.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
Sync operations (browser sync, Gist, custom URL, sync code) now refuse to
operate without encryption enabled. Disabling encryption also turns off all
active sync channels. Activity log cap reduced from 200 to 100 entries for
both storage and display.
https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
Updated "How to verify it's working" with step-by-step instructions
for each browser showing exactly where to click:
- Firefox: F12 → Network → POST events → Request tab → expand JSON
- Chrome: F12 → Network → POST chat/events → Payload tab
- Safari: Cmd+Opt+I → Network → POST → Request
Includes what to look for (replaced data should be there, real data
should not) and what to do if verification fails.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
README changes:
- Added step-by-step "How to verify it's working" section with 6
methods, including Network tab inspection to prove real data never
reaches the AI
- Removed App Store distribution steps (internal, not user-facing)
- Rewrote "What Silent Send can't catch" — updated file uploads line
(we now scan them), clearer language
- Replaced "Legal" section with concise user-facing disclaimer —
removed internal litigation notes that read like developer-to-
developer instead of developer-to-user
- Shortened license section
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Added:
- Safari installation section (full guide: build, test without
Apple Developer account via Allow Unsigned Extensions, App Store
distribution steps)
- Document scanning section with format support table
- Concatenated name patterns in smart pattern examples
- Options tab mention in "how to verify" section
- Browser support note (Chrome, Firefox, Safari)
- document-scanner.js and build-safari.sh in architecture section
- Updated service-worker.js and content.js descriptions
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Popup:
- Added 5th "Options" tab with key settings accessible without
opening the full options page: secret scanning, auto-detect PPI,
auto-redact, show highlights, document scan preview
- "Open Full Options Page" button for sync/encryption/org/import
- Settings changes in popup immediately broadcast to content scripts
Safari:
- Added build-safari.sh that uses Apple's safari-web-extension-converter
to generate an Xcode project from the Firefox build
- browser-polyfill.js already handles Safari (uses browser.* like Firefox)
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Fixed safeHTML in all three files — template.content.childNodes and
doc.body.childNodes are live NodeLists that shrink as nodes are moved.
Using Array.from() to create a static copy before spreading into
replaceChildren().
Expanded proper noun common words filter with ~500 additional verbs,
nouns, and adjectives (generate, design, manage, process, account,
button, dashboard, etc.) to prevent false PPI flags on titles,
headings, and UI button labels.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Massively expanded the common words filter — added ~500 common verbs,
nouns, and adjectives that frequently appear capitalized in titles,
headings, UI buttons, and instructions. 'Generate Design', 'Create
Account', 'Search Filter', etc. are no longer flagged as PPI.
Updated both content.js and auto-detect.js with the same word list.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
sessionSubstitutions stored keys as toLowerCase() for lookup, but the
lowercase key was also used as the substitute value when building
reveal pairs. This caused unrevealText to replace "John Smith" with
"ademo demo" instead of "Ademo Demo".
Fixed by storing both the original-case substitute and the original
real value in sessionSubstitutions. The lowercase key is still used
for lookup, but the preserved-case value is used for reveal pairs.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
When reveal mode was turned OFF, text stayed showing real data
(e.g. "John Smith") instead of reverting to the AI's actual text
("Ademo Demo"). The unreveal function relied on a WeakMap of
original text nodes which lost entries when DOM nodes were replaced
during streaming responses.
Fixed by replacing WeakMap-based restore with active reverse
replacement: unrevealText() replaces real→substitute (the opposite
direction of revealText). This is reliable regardless of DOM changes.
Removed originalTexts WeakMap entirely.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
1. Removed data_collection_permissions from Firefox manifest — it
requires Firefox 140+ but we target 128+. Only produces a warning
when missing, not a blocking error.
2. Fixed JS syntax error in content.js line 450 — two extra closing
braces from a bad merge in the proper noun detection function
caused a parse error that blocked Mozilla validation.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Replaced all 31 innerHTML assignments across popup.js (12),
options.js (17), and content.js (3) to pass Mozilla AMO linter.
Each file gets a safeHTML(el, html) helper:
- popup.js/options.js: DOMParser-based (extension page context)
- content.js: <template> element pattern (page world context)
Empty innerHTML clears replaced with el.replaceChildren().
innerHTML += replaced with createElement + safeHTML + appendChild.
All event listener bindings after HTML rebuilds remain functional
since safeHTML uses replaceChildren() which populates DOM
synchronously before querySelectorAll + addEventListener calls.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Required for Firefox Add-ons (AMO) public listing submission.
Documents that all processing is 100% local, no data collection,
no servers, no analytics. Explains each permission and all
optional network requests (sync, org policy).
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Set Chrome, Firefox, and package.json all to version 2.0.0
(major bump reflecting encrypted storage, document scanning,
org/team features, sync improvements).
Sign script rewritten:
- Tries current version first instead of always bumping
- Only bumps on "version already exists" errors
- Handles rate limiting by parsing throttle duration from error
and waiting the exact time (not blindly retrying)
- Only updates source files on successful signing (not before)
- Reduced max attempts to 5 (with proper backoff, shouldn't need more)
- Commits version bump only after successful sign
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
The X icon looked like a dismiss/close button (temporary). Changed to
a small 'IGNORE' text link that clearly communicates the action is
permanent — the value will never be flagged again.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Proper noun heuristic:
- Changed from matching any single capitalized word to requiring
TWO OR MORE consecutive capitalized words (e.g. "Acme Corp")
- Single capitalized words at sentence starts were causing massive
false positives — every sentence starts with a capital letter
- Minimum 5 characters total and 2 proper words required
Ignore button:
- Each PPI warning item now has an X (ignore) button alongside
the + (add mapping) button
- Ignored values are persisted to storage (ss_ignored_ppi) so
they stay dismissed across page reloads
- Ignored values are skipped in both pattern detection and
proper noun detection
- Clicking ignore removes the item from the warning and re-scans
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Reveal mode's text replacement was walking ALL text nodes on the page
including contenteditable elements (the chat input box on Claude.ai,
ChatGPT, etc.), overwriting the user's typed text with garbled
revealed content.
Fixed by adding contenteditable checks to:
- revealInElement() — returns early if element is contenteditable
- unrevealInElement() — same
- highlightMatches() — TreeWalker filter rejects contenteditable nodes
- MutationObserver — skips addedNodes and characterData mutations
inside contenteditable elements
All four code paths now use parent.closest('[contenteditable="true"]')
to detect and skip chat input areas.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
The sign script's sed command was replacing ALL "version" patterns
including "manifest_version": 3, corrupting it to "manifest_version": 1.
Fixed by anchoring the sed pattern to only match the top-level
"version" field (starts with two spaces at line beginning).
Also:
- Added data_collection_permissions to Firefox manifest (new Mozilla
requirement for all extensions)
- Added 8-second sleep between retry attempts to avoid Mozilla API
rate limiting (was causing cascading failures)
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Removed ZIP read/write complexity. All document formats now extract
text and upload as plaintext — the AI extracts text from files anyway,
no need to preserve formatting in a file the user never gets back.
Added support for: DOC, XLS (old binary), ODT, ODS, ODP (OpenDocument),
PPTX (PowerPoint), RTF.
Extraction methods:
- PDF: content stream operators (Tj, TJ)
- DOCX/XLSX/PPTX/ODT/ODS/ODP: ZIP XML text extraction with DEFLATE
- DOC/XLS: UTF-16LE and ASCII text run extraction from binary
- RTF: strip formatting commands, keep text
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
DOCX and XLSX files now get actual text substitution, not just
scan-and-warn:
- Reads the ZIP structure (DOCX/XLSX are ZIP files of XML)
- Decompresses DEFLATE entries via DecompressionStream API
- Finds XML text content between tags
- Applies substituteAll() to each text node
- Rewrites modified entries as uncompressed (stored) in new ZIP
- Unmodified entries preserved with original compression
- Rebuilds central directory and end-of-central-directory record
DOCX targets: word/document.xml, word/header*.xml, word/footer*.xml,
word/comments.xml, word/endnotes.xml, word/footnotes.xml
XLSX targets: xl/sharedStrings.xml, xl/worksheets/sheet*.xml
Formatting, styles, images, formulas all preserved — only text
content between XML tags is modified. Preview mode still shows
findings before upload for user confirmation.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
New module: document-scanner.js
- PDF: extracts text from content streams, scans for PPI, converts to
sanitized plaintext for upload (PDFs can't be reliably edited in-place)
- DOCX/XLSX: extracts text from XML entries, scans for PPI
- Text files: direct string substitution
- Handles scanned/image-only PDFs gracefully (skips with message)
Fetch interceptor (content.js):
- Now intercepts FormData uploads (file uploads) in addition to JSON
- Processes each file through document scanner
- Preview mode for PDF/DOCX/XLSX: shows PPI findings with counts,
user clicks "Substitute & Upload" or "Upload Original"
- Text files substituted silently (no preview friction)
- String form fields also substituted
- 30-second auto-dismiss on preview (uploads original if no response)
Preview UI (content.css):
- Centered overlay with dark theme matching existing warning UI
- Shows original → substituted pairs for each PPI found
- File format note (e.g. "PDF will be converted to plain text")
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Passwords imported from password managers are now:
- Displayed as dots (••••••••) by default in both options and popup
- Separated into their own "Passwords" section in options page
- Only revealable by entering the vault encryption password
- Always masked in the popup mappings list (no reveal there)
Options page:
- New Passwords section with locked/unlocked states
- Reveal button validates against vault encryption password
- Hide button re-masks all password values
- Password mappings excluded from the general Mappings table
- Delete and enable/disable controls work while masked
Popup:
- Password-category mappings show dots for real value
- Password category added to mapping add form dropdown
Storage:
- Added 'password' to default categories list
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
Import parser:
- Passwords now imported from Chrome/Firefox/Bitwarden/1Password CSVs
as exact-match auto-redacted mappings (→ [REDACTED-PASSWORD-N])
- Catches passwords in any context, not just key=value patterns
Proper noun heuristic:
- Auto-detect scanner now catches capitalized words mid-sentence as
potential names, company names, or project names
- Filters against 200+ common English words, programming terms, days,
months to reduce false positives
- Added to both content.js (page world) and auto-detect.js (popup)
README:
- Documented proper noun detection with examples
- Documented bulk import with all supported formats
- Added Sync features section (auto sync, conflict resolution,
version history, connected devices)
- Added Organization/Team section with policy format
- Added tamper protection documentation
- Added Legal section with liability analysis
- Updated architecture with all new modules
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
New module: import-parser.js
- Auto-detects format from filename and content headers
- Chrome/Firefox password CSV: extracts usernames, emails, domains
(NEVER imports passwords)
- Bitwarden/1Password CSV: extracts usernames, emails, domains
- Browser autofill CSV: extracts names, emails, phones, addresses
- Plain CSV: two-column real→substitute with optional category
- Plain text: one value per line, auto-categorizes (email, phone, name)
- Values without substitutes are marked "needs mapping" so the user
can see what needs filling in
Options UI:
- Import button in Transfer Data section
- Preview panel shows parsed items before applying
- Summary shows counts and highlights items needing substitutes
- Apply merges into active profile (identity) and mappings table
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn