Ships searchable settings (#3850/#3936, @rodboev) as v0.51.471. Supersedes the stale PR #4340 (rebased fresh onto current master; the original was stamped v0.51.469 and went CONFLICTING after several releases shipped).
A search box at the top of the Settings panel finds any field across all sections (Appearance, Preferences, Providers, Plugins, System) without clicking through tabs. Type a label fragment → matching fields appear in a dropdown with their section breadcrumb. Clicking a result jumps to that section, scrolls the field into view, and pulses a brief highlight. Search clears after a pick. The index is built once on first search (covering lazily-loaded provider/plugin cards) and memoized.
Review fixes applied (Codex + Opus)
Search index coverage (Codex): the index only matched label[data-i18n], silently missing the common toggle shape <label><input><span data-i18n="…"></span></label> — so most checkbox settings ("Virtualize long transcripts", "Browser notifications", "Check for updates", …) were unsearchable. Broadened the index query to label[data-i18n], label [data-i18n], label and made _resolveSettingsField resolve any [data-i18n] node back to its .settings-field.
Stale async-render race (Codex + Opus): the first search awaits a provider/plugin network fetch; an outside-click dismiss or a panel reopen during that window could resurrect/paint a stale dropdown. _beginSettingsPanelSession() and the outside-click dismiss handler now bump _settingsSearchSeq and clear the search input + results, so any in-flight build is invalidated.
4 new regression tests for the above.
Verification
XSS-safe (Opus, verified): every result string (label, section breadcrumb, no-results) renders through esc(); the search query is never rendered; the resolver selector is CSS.escape-guarded. A maliciously-named provider/plugin card cannot inject markup.
Gate (all three): Codex SAFE TO SHIP (re-gate after fixes) · Opus SAFE TO SHIP (XSS-safe, navigation/highlight correct, no panel regression) · full suite 9312 passed, 0 failed.
One full-suite failure during gating (test_fade_text_effect_uses_dynamic_window_check) was a fragile test, not a regression — it used a hardcoded PANELS_JS.index(needle, 300000) byte offset that the feature's added lines shifted onto the wrong occurrence; the production listener code is unchanged and passes on clean master. Fixed the test to anchor on the listener block.
Attribution
Original author @rodboev (#3936/#3850). Commits carry a Co-authored-by trailer; CHANGELOG + release credit the author.
Summary
Ships searchable settings (#3850/#3936, @rodboev) as v0.51.471. Supersedes the stale PR #4340 (rebased fresh onto current master; the original was stamped v0.51.469 and went CONFLICTING after several releases shipped).
A search box at the top of the Settings panel finds any field across all sections (Appearance, Preferences, Providers, Plugins, System) without clicking through tabs. Type a label fragment → matching fields appear in a dropdown with their section breadcrumb. Clicking a result jumps to that section, scrolls the field into view, and pulses a brief highlight. Search clears after a pick. The index is built once on first search (covering lazily-loaded provider/plugin cards) and memoized.
Review fixes applied (Codex + Opus)
label[data-i18n], silently missing the common toggle shape<label><input><span data-i18n="…"></span></label>— so most checkbox settings ("Virtualize long transcripts", "Browser notifications", "Check for updates", …) were unsearchable. Broadened the index query tolabel[data-i18n], label [data-i18n], labeland made_resolveSettingsFieldresolve any[data-i18n]node back to its.settings-field._beginSettingsPanelSession()and the outside-click dismiss handler now bump_settingsSearchSeqand clear the search input + results, so any in-flight build is invalidated.Verification
esc(); the search query is never rendered; the resolver selector isCSS.escape-guarded. A maliciously-named provider/plugin card cannot inject markup.test_fade_text_effect_uses_dynamic_window_check) was a fragile test, not a regression — it used a hardcodedPANELS_JS.index(needle, 300000)byte offset that the feature's added lines shifted onto the wrong occurrence; the production listener code is unchanged and passes on clean master. Fixed the test to anchor on the listener block.Attribution
Original author @rodboev (#3936/#3850). Commits carry a
Co-authored-bytrailer; CHANGELOG + release credit the author.Closes #3850. Supersedes #4340.