Releases: SysAdminDoc/ScriptVault
Release list
v3.17.0
Trust enforcement, sync data-safety, and backup slimming.
Security
- Subresource Integrity "Require" mode is now enforced — refuses to run any @require/@resource without a verifiable SRI hash; the install review flags every un-pinned dependency as "unverified remote code".
- Scam / crypto-drain detector — flags wallet seed/private-key access, drainer keywords, and wallet transaction requests, with a high-severity "possible credential/wallet exfiltration" finding when a script harvests secrets and sends data off-page. Benign wallet-adjacent scripts aren't flagged.
Data safety
- Cloud backup no longer clobbers the sync envelope (distinct object per provider) and encrypts under E2EE.
- Easy Cloud sync received the merge fixes: restored-from-trash scripts survive, clean 3-way merges aren't discarded, correct 3-way base.
- SettingsManager write-race fix — concurrent settings writes no longer drop a freshly refreshed OAuth token.
UX & storage
- "Only on This Site" one-click scope in the popup + @match validation in the dashboard editor.
- Backup blobs are gzip-compressed in IndexedDB (transparent, backward-compatible).
Full detail in CHANGELOG.md. Remaining roadmap items (on-device AI, optional host permissions, GM.fetch streaming, per-script cookie jars, git/local-folder sync) are larger bets deferred to dedicated sessions.
v3.16.0
Deep engineering + product-quality audit pass.
Security
- GM networking bound to the authenticated caller. GM_xmlhttpRequest / GM_webSocket / GM_download, GM_getResourceText/URL, GM_loadScript, and menu register/unregister used the caller-supplied script id, letting one userscript borrow another's @connect allowlist or read its @resource bodies. All now use Chrome's unspoofable sender.userScriptId.
- Attribute-injection XSS in the dependency graph and other panels (quote-unescaping escapers) fixed.
Data safety
- Cloud sync no longer permanently re-deletes restored-from-trash scripts (the tombstone-resurrection guard was dead code).
- Trash restore persists the script before emptying the trash entry (no loss on a service-worker crash).
- Backup restore no longer wipes per-script settings (match rules, notes, tags, pin) of installed scripts.
Correctness
- Chrome no longer misdetected as Firefox — restores per-script world isolation on Chrome 133+ and the correct setup instructions.
- Editor no longer swallows the first keystroke after a tab switch; cursor Ln/Col updates instead of freezing.
- New Script / Duplicate / New Folder report failures instead of silently doing nothing.
- Storage meter measures real usage; Find Scripts pagination works again.
Full detail in CHANGELOG.md; ~13 additional verified findings are tracked in ROADMAP.md.
v3.15.1
Fixed
- Editor screen was unusable in v3.15.0. The full-screen editor overlay stacked below the sticky dashboard header, which painted over the Save/Close row and panel tabs — nothing in the top band was visible or clickable. The overlay now stacks above all page chrome (and below modals).
- Hidden editor buttons actually hide. Preview CSS no longer shows for JS scripts; file-binding buttons only appear when relevant.
Changed
- Editor nav redesigned into one band: panel tabs (Code/Settings/Externals/Storage/Info) on the left, icon-only tools with tooltips on the right. Editor chrome is two slim rows; the code pane takes ~91% of the viewport at 1440x900.
- Save button is accented and fills while there are unsaved changes.
Internal
- New
npm run smoke:editorharness drives the real editor in headless Chromium and hit-tests every control, so layering regressions fail loudly.
v3.15.0
Removed
- Script Store tab removed entirely. The eagerly-loaded multi-source discovery tab (~2,100 lines) is gone; script discovery lives in the lighter Find Scripts dialog (toolbar, popup, side panel), Collections, and Gist import.
Changed
- Full-screen script editor. The editor now covers the entire viewport with a slim single-row header and tightened tab/toolbar rows — the code pane gains roughly 150-200px of vertical space.
- New Script opens the editor directly. The template-picker modal is removed; starters remain in the editor template manager.
Fixed
- Storage quota bar uses the real quota (unlimitedStorage-aware via navigator.storage.estimate) — no more false "Storage at 100% capacity" warnings.
- Doubled navigation labels ("SettingsSettings", "Installed UserscriptsInstalled Userscripts") from a duplicate i18n pass.
- Theme switches no longer show a success toast.
- Stray empty pill in the header when no script editors are open.
- RTL direction bootstrap actually runs — the inline script MV3 CSP always blocked is now an external file; extension pages load console-clean.
ScriptVault v3.11.0
ScriptVault v3.11.0
Chrome MV3 release for the Phase 38 parity wave and storage/persistence rollback hardening.
Highlights:
- GM_addElement null-on-failure compatibility.
- Regex dashboard search and update-click confirmation guard.
- Popup context-menu script launchers and Navigation API window.onurlchange support.
- GM_info script tag alias and storage rollback regression coverage.
- minimum_chrome_version raised to Chrome 130.
Firefox remains tracked separately until the Firefox MV3/AMO validation gate is complete.
ScriptVault v2.3.4
ScriptVault v2.3.4
Two CSP-blocked inline <script> blocks were silently breaking the dashboard's view-settings toolbar (zoom + density) and the DevTools panel registration. Also relocates the self-distribution signing keys out of the repo root so Chrome's "Load unpacked" stops warning about bundled key files.
Now live on the Chrome Web Store.
Install (Brave / Chrome / Edge — recommended)
Dragdrop CRX installs are blocked by Chromium 75+ for any extension not in the Web Store, regardless of signing or developer mode. Use Load unpacked instead:
- Download
ScriptVault-v2.3.4.zipand extract it to a permanent folder (e.g.~/extensions/scriptvault/). Don't delete the folder afterwards — the browser loads the extension from this path on every startup. - Open
brave://extensions(orchrome://extensions,edge://extensions). - Toggle Developer mode on (top-right).
- Click Load unpacked and select the extracted folder.
The CRX is still attached for users who have a flow that supports it (enterprise policy with ExtensionInstallSources whitelist, Chrome --load-extension command-line flag, or older Chromium forks like Vivaldi). It is signed with a self-distribution key (extension ID dogogpmmlddegcodbcbeccebdlegphph) — distinct from the Chrome Web Store listing.
Changes
- Fixed: Two inline
<script>blocks violated theextension_pagesCSP (script-src 'self').pages/dashboard.htmlhad a 75-line view-settings controller (zoom + density) andpages/devtools.htmlhad a 9-line panel registration call — both blocked at load time, leaving the dashboard's zoom/density toolbar inert and the DevTools panel un-registered. Extracted topages/dashboard-viewsettings.jsandpages/devtools.js. The remaining inline script inpages/editor-sandbox.htmlis the Monaco bootstrap and is allowed by the sandbox CSP ('unsafe-inline'). - Chore: Moved self-distribution signing keys (
scriptvault.pem,scriptvault-selfhost.pem) out of the repo root to~/.scriptvault-keys/. Chrome's "Load unpacked" warnedThis extension includes the key file ... You probably don't want to do thatbecause anything inside the extension dir gets bundled at build/install time.pack-crx.mjsalready takes the key path as a positional CLI arg, so callers just pass~/.scriptvault-keys/scriptvault-selfhost.pemnow. Both keys remain gitignored.
Includes the v2.3.2 service-worker syntax fix and the v2.3.3 self-healing "Allow User Scripts" warning, both of which shipped without GitHub releases.
ScriptVault v2.3.1
ScriptVault v2.3.1
Fixes a broken v2.3.0 — extensions failed to load with Could not load icon 'icons/16.png' specified in 'icons' because the manifest referenced a directory that was deleted during v2.3.0's branding cleanup. Also fixes a separate ZIP-format issue: the v2.3.0 ZIP used Windows-style backslash entry names (images\icon128.png) which Chrome cannot match against manifest paths regardless of file presence.
Install (Brave / Chrome / Edge — recommended)
Dragdrop CRX installs are blocked by Chromium 75+ for any extension not in the Web Store, regardless of signing or developer mode. Use Load unpacked instead:
- Download
ScriptVault-v2.3.1.zipand extract it to a permanent folder (e.g.~/extensions/scriptvault/). Don't delete the folder afterwards — the browser loads the extension from this path on every startup. - Open
brave://extensions(orchrome://extensions,edge://extensions). - Toggle Developer mode on (top-right).
- Click Load unpacked and select the extracted folder.
The CRX is still attached for users who have a flow that supports it (enterprise policy with ExtensionInstallSources whitelist, Chrome --load-extension command-line flag, or older Chromium forks like Vivaldi). It is signed with a self-distribution key (extension ID dogogpmmlddegcodbcbeccebdlegphph) — distinct from the Chrome Web Store listing.
Changes
- Fixed:
manifest.jsonreferencedicons/16.png/icons/32.png/icons/48.png/icons/128.png, but theicons/directory was deleted in v2.3.0's branding cleanup. Repointed manifest,pages/popup.html,modules/public-api.js,modules/backup-scheduler.js, and the TypeScript mirror atsrc/modules/public-api.tsto the survivingimages/icon{16,32,48,128}.pngfiles. Firefox manifest was already correct. - Fixed:
build.sh/publish.shPowerShellCompress-Archivefallback wrote Windows-style backslash entries (images\icon128.png). Switched tobsdtar(C:\Windows\System32\tar.exe), which writes POSIX-style forward-slash entries that Chrome can match.
523/523 tests green.
ScriptVault v2.3.0
ScriptVault v2.3.0
Install (Brave / Chrome / Edge — recommended)
Dragdrop CRX installs are blocked by Chromium 75+ for any extension not in the Web Store, regardless of signing or developer mode. The CRX in this release will hit CRX_REQUIRED_PROOF_MISSING in Brave and a similar block in Chrome/Edge. Use Load unpacked instead:
- Download
ScriptVault-v2.3.0.zipand extract it to a permanent folder (e.g.~/extensions/scriptvault/). Don't delete the folder afterwards — the browser loads the extension from this path on every startup. - Open
brave://extensions(orchrome://extensions,edge://extensions). - Toggle Developer mode on (top-right).
- Click Load unpacked and select the extracted folder.
The CRX is still attached for users who have a flow that supports it (enterprise policy with ExtensionInstallSources whitelist, Chrome --load-extension command-line flag, or older Chromium forks like Vivaldi). It is signed with a self-distribution key (extension ID dogogpmmlddegcodbcbeccebdlegphph) — distinct from the Chrome Web Store listing.
Highlights
- Fixed: weekly-digest alarm never dispatched (unknown alarm names now route to
NotificationSystem.handleAlarm()) - Security:
ScriptSigning.verifyScript()prototype-pollution guard viaObject.hasOwn()— maliciouspublicKeystrings liketoStringno longer auto-trust - Security:
GM_addElementattrspath now dropson*event handlers and rejectsjavascript:/vbscript:URLs (matches the existinginnerHTMLpath) - Reliability:
ScriptValuesset/delete/setAll/deleteMultiple now snapshot prior state and roll back the cache on persist failure - Reliability:
ScriptStorage.clear()andFolderStorage.update()rollback on save failure - Memory:
requireCachecapped at 500 entries (LRU) - Accuracy:
QuotaManager.getBreakdown()usesTextEncoderfor true UTF-8 byte counts (wasstring.length) - Robustness:
pages/install.jsrenderInstallUI()shows visible error instead of crashing on missing DOM - Robustness:
pages/sidepanel.jschrome.runtime.sendMessagecalls catch SW-wake errors
See CHANGELOG.md for the full list.
ScriptVault v2.1.7
ScriptVault v2.1.7
A two-day rollup covering every change from 2026-04-09 through 2026-04-10. The shipping binaries are attached below: ScriptVault-v2.1.7.crx and ScriptVault-v2.1.7.zip.
Critical fixes
- Monaco editor would never load. The sandboxed editor iframe's CSP had been tightened to
script-src 'self', which blocks theFunction()constructor that Monaco's AMD loader uses internally to evaluate fetched module code.require(['vs/editor/editor.main'], …)silently failed and the iframe hung on the "Loading Editor…" splash. Restored the Monaco-compatible sandbox CSP:script-src 'self' 'unsafe-eval' 'unsafe-inline' blob:. Safe because the iframe runs with thesandboxattribute (opaque origin, no extension-API or parent-DOM access). - Opening a script to edit showed a blank editor.
pages/monaco-adapter.jswas computing thepostMessagetarget origin from the iframe'ssrcURL (→chrome-extension://<id>). But the editor iframe is declared undermanifest.json → sandbox.pages, so Chrome runs it in an opaque"null"origin, not the extension origin.postMessagesilently drops any message whosetargetOrigindoesn't match the recipient's document origin, so everyset-valuewas being rejected — Monaco loaded, but the script code never arrived. Fix: always post withtargetOrigin: '*'(the channel is private between dashboard and iframe). This bug was masked until the earlier CSP fix because Monaco wasn't loading at all. - Editor text rendered at ~100 pixels tall.
monaco-adapter.applySettings()was passingeditorFontSizestraight through to Monaco, but that setting is a percentage (100= 100%), not pixels. Monaco was being told to render 100-pixel text. Fixed by converting the percentage to pixels insideapplySettingsusing the same math the siblingsetFontSize(pct)helper already uses:round(13 * pct / 100)clamped to8..32. - Dashboard column header rendered between data rows 3 and 4 instead of at the top of the table. Two interacting issues:
.scripts-table-containerusedoverflow: hidden, which per CSS spec makes that ancestor the containing block for any descendantposition: stickyelement. The sticky thead'stop: 100pxwas therefore being measured from the container's top — landing in the middle of the table. Switched the container tooverflow: clip, which still clips the rounded corners but does not establish a sticky containing block.- Defensive: Chrome/Webkit have a long-standing bug where sticky
<thead>is miscomputed when the parent table usesborder-collapse: separate. Movedposition: stickyto the individual<th>cells.
Dashboard redesign
Debloat
- Removed the entire
.scripts-results-bar— the secondary row below the toolbar that held quick-filter chips, the live results summary text, and the Reset View button. - Removed
.scripts-toolbar-right. The filter dropdown, script counter, search box, view toggle, and column toggle now all live on the left side of the toolbar in a single flat row. - Removed the provenance origin badges (
Greasy Fork/GitHub/OpenUserJS/Local) from every script row.describeScriptProvenance()is still used by the script info side panel and by exports. - Removed the
conflict-badgeandsync-conflictbadges from script rows. - Fixed folder-row
colspanfrom 14 → 13 (the table only has 13 columns). - Deleted dead helpers left over from the removed UI:
updateScriptResultsSummary,updateScriptQuickFilterButtons,resetScriptWorkspaceView, theSCRIPT_FILTER_LABELSlookup table, and the--results-bar-bottomCSS var. Sticky column headers now re-anchor to--toolbar-bottom.
Light theme readability
A comprehensive html[data-theme="light"] element-override block now lives at the end of the dashboard stylesheet. The base dark styles used white-tinted gradients, sheens, and shadows that disappeared on a light background; those overlays are now swapped for darker inks in light mode so every control stays readable. Covered selectors include tm-header, tm-tabs-bar, tm-tab.active, tm-tab[data-tab=newscript], header-icon-btn, header-zoom-select, scripts-shell, scripts-toolbar, toolbar-btn, search-box, select-field, script-counter, scripts-table-container, scripts-table th / row striping / hover / selected, script-name, script-author, action-icon, btn, the settings/trash/utilities/help hero blocks, editor header/tabs/toolbar, the script-health-badge warning and alert variants, script-tag, and the toolbar divider.
Toast position
- The dashboard toast container now docks at bottom-center instead of bottom-right (
bottom: 20px; left: 50%; transform: translateX(-50%); align-items: center). The narrow-viewport media query keeps the same centered anchor with a safemax-width. The wrapper usespointer-events: nonewhile individual toasts re-enablepointer-eventsso nothing else gets click-blocked.
Toolbar popup debloat
The browser-action popup had drifted into cluttered territory. Total reduction across this rollup: roughly −1,250 lines across popup.html, popup.js, and popup-a11y.test.js, plus the full deletion of popup-timeline.js.
First pass
- Execution Timeline panel removed.
pages/popup-timeline.jsdeleted entirely (real perf work lives in the DevTools panel + dashboard Debugger). - URL bar removed — the browser's address bar already shows the URL 12px above the popup.
- Page summary block removed — "Checking this page…" title + meta + count badge duplicated information shown by the header and list.
- popup-meta footer strip removed — the
Alt+Shift+D Dashboardhint and Feedback link. The keyboard shortcut hint violated the no-keyboard-shortcuts rule and the Feedback link lives in the dashboard. - Redundant count displays collapsed from 4 → 1.
headerCount,pageSummaryCount,popupListSummary, andfooterTotalCountall rendered the same number. Kept the single header pill. - Empty-state action buttons removed — the menu directly below already had "Find New Scripts" and "Create New Script".
- Pinned / Paused filter chips removed. Pinned scripts already sort to the top; Paused is just the inverse of Running. Chips reduced from 5 → 3 (
All / Running / Errors).
Second pass
- Entire popup script toolbar removed — search input and all remaining filter chips.
- Script row state pill removed (Running / Ready / Paused / Errors text) — the toggle alone communicates active state.
- Colored status dot + pulse animation removed.
- Row secondary text removed (description / run count / "updated 3d ago").
- Perf badge removed (avg-ms timing pill).
- Error dot removed — duplicate of the dashboard error log.
- All row tags removed — Pinned, New, Edited, Stale, and the source/Local provenance chip.
- Dead helpers deleted —
describePopupScriptProvenanceandderivePopupHomepageUrl(~70 lines) and theCtrl+Fsearch-focus keyboard handler (no search box left to focus).
Script row anatomy now
[toggle] [icon] Script Name v1.2.3 [pencil] [⋮]
That's it.
Dashboard UX polish from Codex
- Bulk selection rail removed — the obsolete dashboard bulk-selection rail and its dead controller code (~90 lines from
pages/dashboard.js) are gone. - Scripts table — rounded top corner now renders cleanly.
- Popup condensed — spacing, toolbar, empty-state, and timeline layouts slimmed so more content fits without scrolling.
- Popup chrome auto-hides — search, list, and timeline UI elements now hide when not useful.
- Script ID handling hardened — dashboard deep-links now URL-encode script IDs (
#script_<id>) so ids containing special characters round-trip correctly. - Notification click context — uses
chrome.storage.sessionwhen available (SW-scoped, no leftover keys); falls back tochrome.storage.localwith alarm-based cleanup. - Dashboard HTML slimmed — bulk-selection-rail inline styles extracted from
pages/dashboard.html(~120 lines) into the external stylesheet. - Accessibility tests updated —
dashboard-a11yandpopup-a11ytest suites refreshed to match the new slimmer UI. - 266 new
tests/dashboard-modules.test.jscases added for coverage of the trimmed dashboard modules.
Tests
- 512 / 512 green across all changes in this rollup.
Artifacts
ScriptVault-v2.1.7.crx— Chrome signed extension (drag-drop ontochrome://extensionswith Developer Mode enabled)ScriptVault-v2.1.7.zip— Source ZIP for Chrome Web Store / unpacked install
ScriptVault v1.7.7
v1.7.7 — GM_audio Fix, Firefox Compatibility, CSS Fixes
GM API Fixes
- GM_audio was completely non-functional —
addStateChangeListener()referencedwindow.__ScriptVault_ChannelID__which was never defined; all audio state events were silently dropped. Fixed to use the correctCHANNEL_IDvariable. - GM_audio event listener leak — the message handler was added but never removed when
removeStateChangeListener()was called. Now stores handler reference and properly cleans up when the last listener is removed.
Firefox MV3 Compatibility
- Keyboard shortcuts restored —
manifest-firefox.jsonhad emptycommands: {}. Now includes all 3 shortcuts (Alt+Shift+S popup, Alt+Shift+D dashboard, Alt+Shift+E toggle scripts). - Offscreen API guard —
ScriptAnalyzer._ensureOffscreen()now checkschrome.offscreenexistence before calling, gracefully falling back to regex analysis on Firefox.
CSS Fixes
- Z-index hierarchy fixed — Find Scripts overlay (50 -> 55) now correctly stacks above editor overlay (50). Setup warning banner (99 -> 101) now visible above sticky header (100).
- Modal responsiveness —
min-width: min(400px, 90vw)andmax-width: min(500px, 95vw)prevent modals from overflowing on narrow viewports.
Assets
ScriptVault-v1.7.7.zip— Chrome Web Store ready packageScriptVault-v1.7.7.crx— Direct install CRX3 file