Skip to content

feat(user-agent): expand OS, browser, device, and bot detection#77

Merged
lohanidamodar merged 4 commits into
mainfrom
claude/user-agent-detection-expansion-6rbfh4
Jul 20, 2026
Merged

feat(user-agent): expand OS, browser, device, and bot detection#77
lohanidamodar merged 4 commits into
mainfrom
claude/user-agent-detection-expansion-6rbfh4

Conversation

@lohanidamodar

@lohanidamodar lohanidamodar commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

The user-agent package shipped a deliberately small rule set, so many popular user agents resolved to null/unknown. This PR broadens coverage across all four categories using Matomo DeviceDetector 6.4 as the reference, while keeping the existing fast parsing approach — direct token checks plus a small set of bounded regular expressions, with no data files and no runtime dependencies.

Short-name codes stay aligned with Matomo (IPA, OHS, BR, YA, UC, FIR, …) so the added categories match its reference output. Model marketing names still come back as the raw model token by design — mapping those requires Matomo's LGPL data, which this library intentionally does not ship.

What's added

Operating systems — iPadOS, tvOS, watchOS, HarmonyOS, OpenHarmony, Fire OS, webOS, Sailfish, BlackBerry, PlayStation, Nintendo, and popular Linux distributions (Debian, Fedora, Arch Linux, Mint, Kali, Raspbian, and more). iPad now resolves to iPadOS instead of iOS, matching Matomo.

Browsers — Opera Mobile, Brave, Vivaldi, Yandex Browser, UC Browser, DuckDuckGo, QQ Browser, Coc Coc, Whale, Huawei Browser, Amazon Silk, and Firefox Focus. These resolve ahead of the generic Chrome and Android WebView rules, since their user-agent strings also carry a Chrome/ token (and sometimes the Version/4.0 WebView marker). The engine is derived from the actual tokens: Blink at the embedded Chrome version, or WebKit at the AppleWebKit version for legacy Amazon Silk builds that carry no Chrome token.

HTTP libraries — Python urllib, aiohttp, Go-http-client, Node Fetch, Axios, HTTPie, Apache HTTP Client, Java, and more.

Device brands — Realme, Asus, Tecno, Infinix, HTC, Lenovo, ZTE, TCL, Meizu, Fairphone, Alcatel, plus LG/Sony smart-TV brand mapping.

Crawlers — PerplexityBot, Google Extended, GoogleOther, Meta External Agent, CCBot, YouBot, Yahoo Slurp, SeznamBot, Pinterest, and more. Needles are narrowed so human traffic — the Sogou browser, the Pinterest app, and the WhatsApp in-app browser — is not misclassified as a bot (Matomo treats the WhatsApp token as a mobile app, not a crawler).

Safety / no regressions

  • Linux-distro matching is word-boundary anchored and gated on Linux/X11, so tokens like Arch inside Search do not false-positive.
  • HarmonyOS/Fire OS resolve before Android only on their explicit tokens; ordinary Android UAs are unaffected.
  • Xbox still reports Windows; standard Chrome/Firefox/Safari/Samsung/WebView results are unchanged.

Review feedback (Greptile)

  • WhatsApp no longer reported as a bot — Matomo classifies it as a mobile app, so real in-app sessions return isBot() === false.
  • Legacy Amazon Silk (Silk/3.13, no Chrome token) now reports WebKit 533.16 instead of Blink 3.13, matching Matomo.
  • Nothing brand rule dropped — the bare Nothing needle matched unrelated build/app tokens, and real devices report opaque model codes with no brand string.

Testing

bin/monorepo test user-agent94 tests, 393 assertions, all passing. CI green across validate (Vale), test (PHPStan level 5, Rector, PHPUnit), and benchmark.

  • Differential MatomoCompatibilityTest gains iPad, Debian, and Yandex profiles (verified field-for-field against Matomo 6.4).
  • New unit coverage for the added browsers, libraries, platforms, device brands, and crawlers, plus negative cases (Sogou browser, Pinterest app, WhatsApp in-app browser) confirming they stay non-bot, and a legacy-Silk WebKit-engine case.
  • All detections were diff-checked against a live Matomo 6.4 run across 40+ real-world user agents.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BnwCG9DYF9KQwBtRbQHZNv

Broaden detection coverage using Matomo DeviceDetector 6.4 as the
reference so that popular user agents resolve to a real result instead of
null or unknown, while keeping the fast token-and-bounded-regex hot path
(no data files, no runtime dependencies).

- Operating systems: iPadOS, tvOS, watchOS, HarmonyOS, OpenHarmony, Fire
  OS, webOS, Sailfish, BlackBerry, PlayStation, Nintendo, and popular
  Linux distributions (Debian, Fedora, Arch Linux, Mint, and more).
- Browsers: Opera Mobile, Brave, Vivaldi, Yandex, UC Browser, DuckDuckGo,
  QQ Browser, Coc Coc, Whale, Huawei Browser, Amazon Silk, and Firefox
  Focus, all resolved ahead of the generic Chrome and WebView rules.
- Libraries: Python urllib, aiohttp, Go-http-client, Node Fetch, Axios,
  HTTPie, Apache HTTP Client, Java, and more.
- Device brands: Realme, Asus, Tecno, Infinix, HTC, Lenovo, ZTE, TCL,
  Meizu, Nothing, Fairphone, Alcatel, plus LG/Sony smart-TV mapping.
- Bots: PerplexityBot, Google Extended, GoogleOther, Meta External Agent,
  CCBot, YouBot, Yahoo Slurp, SeznamBot, Pinterest, and more, with
  narrowed needles so the Sogou browser and Pinterest app are not
  misclassified as bots.

Short-name codes stay aligned with Matomo so the added categories match
its reference output. Differential tests against Matomo 6.4 gain iPad,
Debian, and Yandex profiles; unit tests cover the new browsers,
libraries, platforms, device brands, and crawlers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnwCG9DYF9KQwBtRbQHZNv
@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

Benchmark results

user-agent

Parser Operations/second Relative
Utopia User Agent 105,750 228.14x
Matomo DeviceDetector 6.4 464 1.00x

Shared CI runners — treat absolute numbers as rough, compare modes within a run. Commit e6b95f4.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands the user-agent package detection rules. The main changes are:

  • Broader operating-system, browser, library, device, and bot detection.
  • More specific matching for derivative browsers before generic Chrome and WebView rules.
  • Updated tests and docs for the new detection coverage.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
packages/user-agent/src/UserAgent/Detection/BotDetector.php Expands bot detection and removes the WhatsApp bot match.
packages/user-agent/src/UserAgent/Detection/ClientDetector.php Adds derivative browser and HTTP library detection, including corrected legacy Silk engine handling.
packages/user-agent/src/UserAgent/Detection/DeviceDetector.php Expands brand and TV detection while narrowing the Honor match and removing the Nothing rule.
packages/user-agent/src/UserAgent/Detection/OperatingSystemDetector.php Adds detection for more Apple, Android-based, console, TV, and Linux distribution operating systems.

Reviews (4): Last reviewed commit: "fix(user-agent): tighten Honor brand rul..." | Re-trigger Greptile

Comment thread packages/user-agent/src/UserAgent/Detection/BotDetector.php Outdated
Comment thread packages/user-agent/src/UserAgent/Detection/ClientDetector.php Outdated
Comment thread packages/user-agent/src/UserAgent/Detection/DeviceDetector.php Outdated
claude added 2 commits July 19, 2026 01:17
- OperatingSystemDetector: satisfy PHPStan (drop always-true empty-string
  check in webOS version parsing) and Rector (use instanceof over !== null
  for the Apple and Linux-distro results).
- ClientDetector: report the correct engine for Chromium derivatives that
  ship no Chrome token — legacy Amazon Silk now resolves to WebKit at its
  AppleWebKit version instead of Blink at the Silk version, matching Matomo.
- BotDetector: stop treating WhatsApp as a bot. Matomo classifies the
  WhatsApp token as a mobile app, so real in-app browser sessions must not
  report isBot().
- DeviceDetector: drop the Nothing brand rule; the bare "Nothing" needle
  matched unrelated build and app tokens and mislabeled the brand.
- Vale: add Wget, aiohttp, Axios, HTTPie, and GPTBot to the shared
  vocabulary so the README spell-check passes.
- Tests: lock in legacy Silk WebKit engine reporting and WhatsApp staying
  non-bot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnwCG9DYF9KQwBtRbQHZNv
The README spell-check runs over the whole file, so every product and
brand name in the expanded detection-coverage section needs a vocabulary
entry. Add the OS, browser, and library names introduced by this PR
(macOS, iOS, iPadOS, HarmonyOS, webOS, Vivaldi, Yandex, DuckDuckGo,
Huawei, OkHttp, and more). Verified with Vale 3.15.1 that the package
README reports zero spelling errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnwCG9DYF9KQwBtRbQHZNv
Comment thread packages/user-agent/src/UserAgent/Detection/DeviceDetector.php Outdated
The bare `Honor` alternative matched the common word "honor" anywhere in
the user-agent string, so an app or build token such as
`Build/InHonorOfRelease` could mislabel a non-Honor device. Match only the
uppercase `HONOR` brand token or `Honor <model>` (numbers, X/V series, and
named product lines), alongside the existing HLK-/BKL- model codes. Real
Honor devices — including uppercase `HONOR WKG-LX9` — still resolve to
Honor, while "honor" in surrounding text no longer sets the brand.

Adds regression tests for named and uppercase Honor models and a negative
case where "InHonorOfRelease" must not override the real Samsung brand.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnwCG9DYF9KQwBtRbQHZNv
@lohanidamodar
lohanidamodar merged commit 56c85cd into main Jul 20, 2026
6 checks passed
@lohanidamodar
lohanidamodar deleted the claude/user-agent-detection-expansion-6rbfh4 branch July 20, 2026 09:05
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.

3 participants