feat: Options tab in popup + Safari build script

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
This commit is contained in:
Claude
2026-03-27 03:11:49 +00:00
parent 66f408713c
commit 04372ab561
4 changed files with 173 additions and 1 deletions
+29
View File
@@ -623,6 +623,35 @@ body {
font-size: 12px;
}
/* Options tab */
.setting-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid #f3f4f6;
}
.setting-item:last-of-type { border-bottom: none; }
.setting-label {
flex: 1;
min-width: 0;
}
.setting-label strong {
font-size: 12px;
display: block;
color: #1f2937;
}
.setting-label .setting-desc {
font-size: 10px;
color: #9ca3af;
display: block;
margin-top: 1px;
}
/* Footer */
.footer {
padding: 8px 16px;
+49
View File
@@ -33,6 +33,7 @@
<button class="tab" data-tab="mappings">Mappings</button>
<button class="tab" data-tab="activity">Activity</button>
<button class="tab" data-tab="test">Test</button>
<button class="tab" data-tab="options">Options</button>
</nav>
<!-- Locked State Overlay -->
@@ -193,6 +194,54 @@
<div class="test-identity-status" id="identityStatus"></div>
</section>
<!-- Options Tab -->
<section class="tab-content" id="tab-options">
<div class="setting-item">
<div class="setting-label">
<strong>Secret scanning</strong>
<span class="setting-desc">Auto-redact API keys, tokens, passwords, SSNs, credit cards</span>
</div>
<label class="toggle"><input type="checkbox" id="optSecretScanning" checked><span class="toggle-slider"></span></label>
</div>
<div class="setting-item">
<div class="setting-label">
<strong>Auto-detect PPI</strong>
<span class="setting-desc">Warn about unconfigured personal data (IPs, addresses, paths)</span>
</div>
<label class="toggle"><input type="checkbox" id="optAutoDetect" checked><span class="toggle-slider"></span></label>
</div>
<div class="setting-item">
<div class="setting-label">
<strong>Auto-redact detected PPI</strong>
<span class="setting-desc">Replace detected PPI with placeholders on send</span>
</div>
<label class="toggle"><input type="checkbox" id="optAutoRedact" checked><span class="toggle-slider"></span></label>
</div>
<div class="setting-item">
<div class="setting-label">
<strong>Show highlights</strong>
<span class="setting-desc">Highlight substituted values in AI responses</span>
</div>
<label class="toggle"><input type="checkbox" id="optHighlights"><span class="toggle-slider"></span></label>
</div>
<div class="setting-item">
<div class="setting-label">
<strong>Document scan preview</strong>
<span class="setting-desc">Show PPI findings before uploading documents</span>
</div>
<label class="toggle"><input type="checkbox" id="optDocPreview" checked><span class="toggle-slider"></span></label>
</div>
<div style="margin-top:12px;padding-top:10px;border-top:1px solid #e5e7eb">
<button class="btn" id="btnOpenFullOptions" style="width:100%;font-size:12px">Open Full Options Page</button>
<p class="help-text" style="margin-top:6px;text-align:center">Sync, encryption, org, version history, import/export, and more</p>
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="privacy-note">
+29 -1
View File
@@ -208,12 +208,40 @@ async function initUnlockedUI() {
});
});
// Options link
// Options link (footer)
$('#btnOptions').addEventListener('click', (e) => {
e.preventDefault();
api.runtime.openOptionsPage();
});
// Options tab
$('#btnOpenFullOptions').addEventListener('click', () => {
api.runtime.openOptionsPage();
});
// Load options tab settings
$('#optSecretScanning').checked = settings.secretScanning !== false;
$('#optAutoDetect').checked = settings.autoDetect !== false;
$('#optAutoRedact').checked = settings.autoRedactDetected !== false;
$('#optHighlights').checked = settings.showHighlights || false;
$('#optDocPreview').checked = settings.docScanPreview !== false;
// Options tab change handlers
const optHandlers = [
['optSecretScanning', 'secretScanning'],
['optAutoDetect', 'autoDetect'],
['optAutoRedact', 'autoRedactDetected'],
['optHighlights', 'showHighlights'],
['optDocPreview', 'docScanPreview'],
];
for (const [id, key] of optHandlers) {
$(`#${id}`).addEventListener('change', async (e) => {
settings[key] = e.target.checked;
await Storage.saveSettings({ [key]: e.target.checked });
api.runtime.sendMessage({ type: 'update:settings', settings });
});
}
// Update privacy note based on encryption state
const encEnabled = await Storage._isAtRestEncryptionEnabled();
const encNote = $('#privacyEncNote');