Skip to content

feat(search): commercial-parity features and privacy hardening from Android 26.07.03#100

Merged
ErikChevalier merged 2 commits into
mainfrom
feat/commercial-parity-port
Jul 12, 2026
Merged

feat(search): commercial-parity features and privacy hardening from Android 26.07.03#100
ErikChevalier merged 2 commits into
mainfrom
feat/commercial-parity-port

Conversation

@ErikChevalier

Copy link
Copy Markdown
Contributor

What & why

Brings the desktop app to feature parity with Android v26.07.03 (SearchMob PR #103): instant answers, !bangs, search-as-you-type on the served pages, the Wikipedia-thumbnail privacy proxy, User-Agent pinning + per-host politeness + whole-call HTTP deadline, and the cross-layer ranking/parsing fixes.

New (all on-device, no new third parties)

  • Instant answers: calculator, unit / number-base conversions, percentages — an answer card on the served page and in the GUI, guarded against date/phone-shaped input.
  • !bangs: curated on-device table; served /search 302s to the site's own search, the GUI opens the browser directly. Terms never enter the metasearch fan-out; unknown tags fall through.
  • Search-as-you-type on the served pages (ARIA listbox over /suggest, debounced, aborts stale fetches, / focuses the box), result count + elapsed time meta line, a favicon, and the topbar/sort/did-you-mean controls now carry the active vertical and sort.

Privacy

  • Wikipedia summary thumbnails re-served through a loopback /img proxy (scoped to upload.wikimedia.org, image-only, size-capped); CSP tightens to img-src 'self' data: + connect-src 'self'.
  • One UA per logical search, refreshed UA pool, process-wide thread-safe per-host politeness (previously absent), whole-call HTTP deadline.
  • OpenSearch descriptor uses the request Host for network visitors and no longer embeds the access token (the descriptor is unauthenticated).

Fixes

  • Verticals no longer poison Wikipedia/Marginalia/Mwmbl with site: clauses their indexes cannot parse.
  • Dedup folds http/https + mobile hosts; blank titles backfill; domain rules resolve most-specific-first; day-first slash dates and single-digit after: dates parse.
  • GUI: superseded searches can no longer overwrite fresh results or flash a stale error; engine status renders on empty served pages; explicit search-field focus on launch.

24 new tests (instant answers, bangs, parity fixes, route-level parity features, GUI parity) plus updated proxy/descriptor tests; ruff + mypy --strict + full suite green locally (818 passed).

Release chore for 26.07.02 follows after merge.

🤖 Generated with Claude Code

…ndroid 26.07.03

Port of the Android parity sweep (SearchMob PR #103) to the desktop app:

New features, all computed on-device with no new third parties:
- Instant answers: calculator (2+2, sqrt(9)*3), unit conversions
  (10 km to miles, 72 f to c), number-base conversions (0xff in decimal),
  and percentages (15% of 80), shown as an answer card on the served page
  and in the GUI. Date/phone-shaped input is guarded so the card never
  mis-fires.
- DuckDuckGo-style !bangs (!w, !gh, !yt, ...) resolved from a curated
  on-device table: the served /search 302s to the site's own search and
  the GUI opens the browser directly; the terms never enter the
  metasearch fan-out, and unknown tags (!important) are never hijacked.
- Search-as-you-type on the served pages: an ARIA-listbox dropdown over
  /suggest with debounce, stale-fetch aborts, and keyboard support; '/'
  focuses the search box. The served meta line shows result count and
  elapsed time, a favicon is served, and the topbar/sort/did-you-mean
  controls carry the active vertical and sort instead of resetting them.

Privacy hardening:
- The Wikipedia summary thumbnail is re-served through a new loopback
  /img proxy (SSRF-scoped to upload.wikimedia.org, image-only,
  size-capped) so the browser never fetches from Wikimedia directly; CSP
  tightens from img-src https: to img-src 'self' data: plus
  connect-src 'self'.
- One User-Agent per logical search (a client pins its UA; fresh
  searches still rotate), refreshed UA pool, process-wide thread-safe
  per-host politeness spacing, and a whole-call HTTP deadline so a
  byte-trickling upstream cannot hold a search open.
- The OpenSearch descriptor uses the request Host for network-mode
  visitors and never embeds the access token.

Correctness fixes:
- Vertical scoping no longer poisons engines without site:/OR syntax
  (Wikipedia/Marginalia/Mwmbl get the operator-free query; constraints
  stay locally enforced).
- Dedup key folds http/https and mobile-host variants; merged results
  backfill a blank title; domain rules resolve most-specific-first;
  slash dates with day>12 parse day-first; before:/after: accept
  single-digit months/days.
- GUI: stale searches can no longer overwrite fresh results or flash
  their error; the engine-status diagnostic renders on empty served
  pages; the search field takes focus explicitly on launch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread tests/gui/test_parity_features_gui.py Fixed
The code-quality bot flagged the mixed 'import ... as' + 'from ... import'
of the same module; the module alias stays (the monkeypatching needs it)
and MainWindow is reached through it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ErikChevalier
ErikChevalier merged commit 8b2e235 into main Jul 12, 2026
2 checks passed
@ErikChevalier
ErikChevalier deleted the feat/commercial-parity-port branch July 12, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant