Skip to content

Releases: therealaleph/MasterHttpRelayVPN-RUST

v1.7.11

27 Apr 21:57

Choose a tag to compare

• v1.7.10 release page assets منتشر نشد (CI failures): دو bug همزمان بودن — (۱) target i686-pc-windows-msvc که در v1.7.7 برای Win7 32-bit اضافه شده بود، در v1.7.10 fail کرد چون Rust 1.77.2 (آخرین stable Win7-compat) نمی‌تونه manifest crate‌های مدرن مثل time 0.3.47 رو parse کنه؛ pinning transitive crate‌ها در هر release dep MSRV بمپ می‌کنن غیرقابل دفاع است. (۲) job release با actions/download-artifact@v4 با ۵-retry-exhausted error fail شد. Fix: target i686 از matrix حذف شد (کاربران Win7 ۳۲ بیتی باید self-build کنن — instructions در #318)؛ release و telegram jobs به gh run download با retry loop ۳-attempt تبدیل شدن. v1.7.11 release اولین کاملی هست که از v1.7.9 منتشر می‌شه با همه fixهای v1.7.10 (Apps Script range probe + Android Paste button) plus این workflow fix.

• v1.7.10 release page assets failed to publish (CI failures): two concurrent bugs — (1) the i686-pc-windows-msvc target added in v1.7.7 for Win7 32-bit support broke in v1.7.10 because Rust 1.77.2 (the last stable that produces Win7-compatible binaries) can't parse the manifest of modern transitive crates like time 0.3.47; pinning transitives at every release where a dep bumps MSRV is brittle and unsustainable. (2) The release job's actions/download-artifact@v4 step hit a 5-retries-exhausted error. Fix: dropped the i686 target from the matrix entirely (Win7 32-bit users must self-build now — instructions in #318); the release and telegram jobs now use gh run download with a 3-attempt retry loop. v1.7.11 is the first complete release published since v1.7.9 and ships all the v1.7.10 fixes (Apps Script range probe handling per #337, Android Paste button per #344) along with this workflow repair.

Full Changelog: v1.7.10...v1.7.11

v1.7.9

27 Apr 13:05

Choose a tag to compare

• رفع باگ "binary i686 ویندوز روی Windows 7 ۳۲ بیتی load نمی‌شه" (#318، #323): از Rust 1.78 (می ۲۰۲۴) std GetSystemTimePreciseAsFileTime (Win8+) رو به‌جای GetSystemTimeAsFileTime (Win2k+) کرد، و این نیاز کرد binary ویندوز ۳۲ بیتی از kernel32 یه export که تو Win7 وجود نداره use کنه. binary v1.7.7/v1.7.8 با خطای the procedure entry point GetSystemTimePreciseAsFile could not be located in the dynamic link library kernel32.dll روی Win7 SP1 بسته می‌شد. Fix: فقط target i686-pc-windows-msvc رو در workflow CI به Rust 1.77.2 (آخرین stable Win7-compatible) pin کردیم. سایر targets روی stable می‌مونن. این یعنی artifact mhrv-rs-windows-i686.zip در v1.7.9 روی Win7 SP1 ۳۲ بیتی load می‌شه. ممنون از @Im-P3dro برای گزارش

• Fix "i686 Windows binary fails to load on Windows 7 32-bit" (#318, #323): Rust 1.78 (May 2024) raised std's Windows MSRV from Win7 to Win10 by switching std::time to GetSystemTimePreciseAsFileTime (Win8+ in kernel32) instead of the older GetSystemTimeAsFileTime. The v1.7.7 and v1.7.8 i686 Windows binaries failed to load on Win7 SP1 with the procedure entry point GetSystemTimePreciseAsFile could not be located in the dynamic link library kernel32.dll, defeating the entire reason that target ships (legacy Win7 32-bit boxes per #272). Fix: pin only the i686-pc-windows-msvc CI matrix entry to Rust 1.77.2 (the last stable that targets Win7); every other target stays on @stable. The mhrv-rs-windows-i686.zip artifact in v1.7.9 once again loads on Win7 SP1. Thanks @Im-P3dro for the report.

What's Changed

  • ci(release): pin i686-pc-windows-msvc to Rust 1.77.2 for Win7 compat by @therealaleph in #323

Full Changelog: v1.7.8...v1.7.9

v1.7.8

27 Apr 11:34

Choose a tag to compare

• Blacklist خودکار deployment با timeout مکرر در batch (#319): قبلاً وقتی یک deployment hang می‌کرد (معمولاً به دلیل TUNNEL_SERVER_URL قدیمی که به host از کار افتاده اشاره می‌کرد، یا Apps Script که UrlFetchApp داخلش hang کرده بود)، round-robin مدام trafficرو به همون deployment می‌فرستاد و sessionها timeout می‌خوردند بدون recovery تا restart process. Fix: state per-deployment با window ۳۰ ثانیه‌ای — ۳ timeout در پنجره ۳۰ ثانیه‌ای منجر به blacklist با cooldown ۱۲۰ ثانیه می‌شه. هر batch موفق strikeها رو پاک می‌کنه. cooldown کوتاه (۲ دقیقه به‌جای ۱۰ دقیقه برای quota) تا deploymentای که سریع recover می‌شه به‌سرعت برگرده. مستقل از blacklist موجود برای quota-error (که هنوز ۱۰ دقیقه cooldown داره). برای scenario 5 از 8 deployment کهنه: بعد از یک batch، ۳ deployment dropped می‌شن و session جدید با احتمال خیلی بیشتر روی deployment سالم می‌افته. ممنون از @dazzling-no-more

• Auto-blacklist deployments after sustained batch timeouts (#319): previously, when a single deployment hung (most commonly due to a stale TUNNEL_SERVER_URL pointing at a dead host, or Apps Script's internal UrlFetchApp stalling), round-robin kept dispatching real traffic to it. Sessions piled into the bad deployment and timed out without recovery until the user restarted mhrv-rs. Fix: per-deployment strike counter with a 30-second sliding window — 3 timeouts in 30 s triggers a 120-second cooldown blacklist. Any successful batch clears the strike counter, so unrelated transient blips can't accumulate across hours. Short cooldown (2 min vs. the 10 min permanent-blacklist for quota errors) so a deployment that recovers rejoins the round-robin quickly. For the "5 of 8 deployments stale" scenario: after one batch each, the 3 dead deployments drop out and new sessions land on healthy deployments with much higher probability. Distinct from the quota blacklist (still 600s cooldown). Thanks @dazzling-no-more

What's Changed

Full Changelog: v1.7.7...v1.7.8

v1.7.7

26 Apr 22:32

Choose a tag to compare

• اضافه شدن build برای ویندوز ۳۲ بیتی (i686-pc-windows-msvc) به matrix release (#272, #288): کاربری که سیستم قدیمی ویندوز ۳۲ بیتی داشت درخواست build اختصاصی کرد. حالا artifact ‫mhrv-rs-windows-i686.zip‬ هم در release page موجوده. ممنون از @amiralishoja برای PR
• رفع باگ "یک deployment معیوب همه ‍session‌ها رو روی cadence legacy گیر می‌اندازه" (#290): قبلاً وقتی یکی از deployment‌ها fast-empty (long-poll نمی‌شناخت) برمی‌گردوند، flag global server_no_longpoll فعال می‌شد و کل session‌ها رو روی cadence ۳۰ ثانیه‌ای legacy گیر می‌انداخت — حتی اگه deployment‌های دیگه راحت long-poll می‌کردن. اون flag همچنین هیچ‌وقت reset نمی‌شد، پس tunnel-node بازنشانده تا restart process به مسیر سریع برنمی‌گشت. Fix: state per-deployment با TTL ۶۰ ثانیه. flag aggregate فقط وقتی فعال می‌شه که همه deployment‌های یکتا mark شده باشن، و خودش رو از روی expiry self-correct می‌کنه. tunnel-node ارتقا داده شده خودش به مسیر long-poll fast بدون restart برمی‌گرده. ۴ تست جدید با tokio::test(start_paused = true) پوشش‌دهی timing logic. ممنون از @dazzling-no-more

• Add 32-bit Windows (i686-pc-windows-msvc) to the release matrix (#272, #288): a user with a legacy 32-bit Windows machine asked for a dedicated build. mhrv-rs-windows-i686.zip now appears alongside the other artifacts on every release page. Thanks @amiralishoja for the PR
• Fix "one degraded deployment drags all sessions onto the legacy cadence" bug (#290): previously, a single fast-empty observation from any one deployment flipped the global server_no_longpoll flag, dragging every session onto the 30-second legacy cadence even when the other deployments were happily long-polling. The flag also never reset, so a redeployed/recovered tunnel-node didn't return to the fast path until the mhrv-rs process restart. Fix: state is now per-deployment with a 60-second TTL. The aggregate flag flips only when every unique configured deployment is marked, and self-corrects on read when entries expire. An upgraded tunnel-node rejoins the long-poll fast path on its own. 4 new tests using tokio::test(start_paused = true) to cover the timing logic without burning real wall-clock seconds. Thanks @dazzling-no-more

What's Changed

New Contributors

Full Changelog: v1.7.6...v1.7.7

v1.7.6

26 Apr 21:50

Choose a tag to compare

• Revert غلط v1.7.4 برای googlevideo.com (#275، #281): v1.7.4 تلاش کرد googlevideo.com رو به لیست SNI rewrite اضافه کنه به این تئوری که chunk‌های ویدیو باید از Apps Script relay دور بزنن. چندین کاربر گزارش دادن که v1.7.4 YouTube رو کاملاً شکست داد — علت: googlevideo.com توسط edge IP‌های جدا "EVA" گوگل serve می‌شه، نه GFE IP عادی که google_ip کاربر معمولاً به اون اشاره می‌کنه. SNI-rewrite کردن googlevideo.com:443 به یه GFE IP باعث TLS handshake failure یا wrong-cert error برای اون کاربرها شد. رفتار قبل از v1.7.4 برگشته (chunk‌های ویدیو از مسیر Apps Script relay می‌رن — کندتر ولی روی هر GFE IP قابل اعتماد). تغییرات youtube_via_relay carve-out از v1.7.4 (که ytimg.com رو از relay پاک کرد) دست نخورده — اون regression جدا بود و درست شده باقی مونده. اگه کاربری در آینده EVA edge IP خودش رو پیکربندی بکنه، یه knob مجزا اضافه می‌کنیم.

• Revert v1.7.4 googlevideo.com SNI rewrite (#275, #281): v1.7.4 added googlevideo.com to the SNI rewrite list on the theory that video chunks should bypass the Apps Script relay. Multiple users reported v1.7.4 broke YouTube entirely — root cause: googlevideo.com is served by Google's separate "EVA" edge IPs, not the regular GFE IPs that google_ip typically points at. SNI-rewriting googlevideo.com:443 to a GFE IP got TLS handshake failures or wrong-cert errors for those users. Pre-v1.7.4 behaviour is restored (video chunks go via the Apps Script relay path — slower but reliable on every GFE IP). The other v1.7.4 youtube_via_relay carve-out changes (which removed ytimg.com from the carve-out) are intact — those were a separate fix that's still correct. If a user ever wants direct googlevideo.com routing, that needs a separate config knob letting them specify their EVA edge IP independently.

Full Changelog: v1.7.5...v1.7.6

v1.7.5

26 Apr 21:29

Choose a tag to compare

• گزینهٔ جدید block_quic در config برای رد کردن client-side QUIC (#213): با "block_quic": true در config.json، listener SOCKS5 UDP هر datagramی به مقصد port 443 (یعنی HTTP/3-over-UDP) رو silent drop می‌کنه. browser به TCP/HTTPS fallback می‌کنه (که از مسیر CONNECT معمولی رد می‌شه و از relay می‌گذره). برای کاربرهایی که QUIC TCP-meltdown رو در Full mode تجربه می‌کنن (پهنای باند < 1 Mbps در عوض > 50 Mbps با TCP/HTTPS) خوبه. به‌صورت opt-in (پیش‌فرض false). ممنون از @w0l4i
• release artifacts دوباره به پوشهٔ releases/ در مخزن commit می‌شن (به درخواست کاربر تلگرام): پس از v1.1.0 این عادت متوقف شده بود — حالا بعد از هر release tag، workflow خودکار فایل‌های pre-built رو در پوشه releases/ به‌روزرسانی می‌کنه. کاربرانی که به صفحه GitHub Releases دسترسی ندارن (به‌خاطر فیلتر در ایران) می‌تونن از طریق Code → Download ZIP به فایل‌های آخرین نسخه برسن. صفحه release رسمی همچنان artifact‌های versioned رو داره — این پوشه fallback هست

• New block_quic config option for client-side QUIC drop (#213): set "block_quic": true in config.json and the SOCKS5 UDP relay silently drops any datagram destined for port 443 (HTTP/3-over-UDP). The client's QUIC stack retries a couple of times and then falls back to TCP/HTTPS, which goes through the regular CONNECT path and through the relay. Useful for users seeing QUIC TCP-meltdown in Full mode (sub-1 Mbps where TCP/HTTPS does 50+). Opt-in (default false). Thanks @w0l4i
• Release artifacts now committed back to the in-repo releases/ folder (per Telegram channel request): the practice was stopped after v1.1.0 — now after every release tag, the workflow auto-refreshes releases/ with the pre-built binaries. Users behind GitHub-Releases-page filtering can grab the latest version via Code → Download ZIP. The official release page still has versioned artifacts; the in-repo folder is the fallback path

Full Changelog: v1.7.4...v1.7.5

v1.7.4

26 Apr 20:15

Choose a tag to compare

• رفع باگ "video timeout با send YouTube through relay" (#275): قبلاً وقتی youtube_via_relay = true بود، تمام دامنه‌های مرتبط با YouTube از طریق Apps Script رد می‌شدن، شامل googlevideo.com (chunkهای video) و ytimg.com (thumbnails). نتیجه: یک chunk timeout کل پخش video رو در Firefox abort می‌کرد، و video طولانی به ۶ دقیقه cap اجرای Apps Script می‌خورد. Fix: حالا youtube_via_relay فقط API/HTML رو از relay رد می‌کنه (youtube.com, youtu.be, youtube-nocookie.com, youtubei.googleapis.com — جایی که Restricted Mode enforce می‌شه)، در حالی که CDNهای video/image مستقیماً از Google edge می‌گذرن (googlevideo.com که در نسخه‌های قبل اصلاً در لیست SNI rewrite نبود اضافه شد، ytimg.com، ggpht.com). نتیجه: Restricted Mode بدون قطع شدن video. ممنون از @amirabbas117 برای تحلیل دقیق
• Negative-cache برای destinationهای unreachable + pre-warm بزرگ‌تر در startup (#280): گوشی‌های بدون IPv6 وقتی پروب IPv6-only host (مثلاً ds6.probe.whatismyipaddress.com) می‌فرستن، 5+ batch Apps Script در ثانیه روی destination تضمین‌fail هدر می‌رفت. حالا cache 30s × 256-entry در TunnelMux نگه می‌داره برای destinationهایی که tunnel-node با Network is unreachable یا No route to host پاسخ داده — short-circuit به 502 Bad Gateway (HTTP CONNECT) یا 0x04 Host unreachable (SOCKS5) برای هر retry بعدی. Pre-warm pool startup هم بزرگتر شد (۱۲ تا ۲۴ connection به‌جای ۸) برای کمتر شدن first-use latency. ممنون از @dazzling-no-more

• Fix "video timeout when 'Send YouTube through relay' is on" (#275): previously, youtube_via_relay = true routed every YouTube-related domain through Apps Script — including googlevideo.com (video chunks) and ytimg.com (thumbnails). Result: a single chunk timeout aborted entire Firefox playbacks, and long videos hit Apps Script's 6-min execution cap mid-playback. Fix: youtube_via_relay now only relays the API/HTML hosts (youtube.com, youtu.be, youtube-nocookie.com, youtubei.googleapis.com — where Restricted Mode is enforced), while video/image CDNs go direct via Google edge (googlevideo.com was missing from the SNI rewrite list entirely; now added; ytimg.com, ggpht.com stay on SNI rewrite always). Restricted Mode bypass without breaking playback. Thanks @amirabbas117 for the detailed analysis
• Negative-cache for unreachable destinations + larger startup pre-warm pool (#280): on devices without IPv6, OS/app probes to IPv6-only hostnames (e.g. ds6.probe.whatismyipaddress.com) were burning 5+ Apps Script batches per second on a guaranteed-fail destination. TunnelMux now keeps a 30s × 256-entry cache of destinations the tunnel-node returned Network is unreachable / No route to host for, and short-circuits subsequent CONNECTs with 502 Bad Gateway (HTTP CONNECT) or 0x04 Host unreachable (SOCKS5). Startup pre-warm pool also grew (12 → 24 connections) to reduce first-use latency. Thanks @dazzling-no-more

What's Changed

Full Changelog: v1.7.3...v1.7.4

v1.7.3

26 Apr 19:01

Choose a tag to compare

• حذف نیاز به فورک tun2proxy (#271): v1.7.0 از یه فورک شخصی tun2proxy (با پارامتر udpgw_server در JNI) استفاده می‌کرد چون upstream هنوز feature flag udpgw رو منتشر نکرده بود. حالا که tun2proxy 0.7.21 رسماً روی crates.io با feature flag udpgw در دسترسه + maintainer toolchain CLI API رو به‌عنوان مسیر صحیح برای کاربران Android معرفی کرد، فورک رو حذف می‌کنیم. روش جدید: mhrv-rs از طریق dlsym در زمان اجرا تابع tun2proxy_run_with_cli_args رو از libtun2proxy.so resolve می‌کنه و CLI args ساده می‌فرسته (--proxy socks5://127.0.0.1:1081 --tun-fd <fd> --udpgw-server 198.18.0.1:7300 ...). نه فورک، نه [patch.crates-io]، نه commit SHA. وقتی tun2proxy update می‌شه، فقط نسخهٔ crates.io رو bump می‌کنیم. ممنون از @yyoyoian-pixel

• Drop the tun2proxy fork dependency (#271): v1.7.0 used a personal fork of tun2proxy (with a udpgw_server parameter added to the JNI signature) because upstream hadn't published the udpgw feature flag yet. With tun2proxy 0.7.21 now on crates.io with udpgw feature flag, and the upstream maintainer pointing callers at the C-style CLI API as the recommended path for Android, we drop the fork. New approach: mhrv-rs resolves tun2proxy_run_with_cli_args from libtun2proxy.so at runtime via dlsym and passes a simple CLI string (--proxy socks5://127.0.0.1:1081 --tun-fd <fd> --udpgw-server 198.18.0.1:7300 ...). No fork, no [patch.crates-io], no pinned SHA. Future tun2proxy upgrades are a single Cargo version bump. Thanks @yyoyoian-pixel

What's Changed

  • feat: enable udpgw client via tun2proxy CLI API — no fork needed by @yyoyoian-pixel in #271

Full Changelog: v1.7.2...v1.7.3
• حذف نیاز به فورک tun2proxy (#271): v1.7.0 از یه فورک شخصی tun2proxy (با پارامتر udpgw_server در JNI) استفاده می‌کرد چون upstream هنوز feature flag udpgw رو منتشر نکرده بود. حالا که tun2proxy 0.7.21 رسماً روی crates.io با feature flag udpgw در دسترسه + maintainer toolchain CLI API رو به‌عنوان مسیر صحیح برای کاربران Android معرفی کرد، فورک رو حذف می‌کنیم. روش جدید: mhrv-rs از طریق dlsym در زمان اجرا تابع tun2proxy_run_with_cli_args رو از libtun2proxy.so resolve می‌کنه و CLI args ساده می‌فرسته (--proxy socks5://127.0.0.1:1081 --tun-fd <fd> --udpgw-server 198.18.0.1:7300 ...). نه فورک، نه [patch.crates-io]، نه commit SHA. وقتی tun2proxy update می‌شه، فقط نسخهٔ crates.io رو bump می‌کنیم. ممنون از @yyoyoian-pixel

• Drop the tun2proxy fork dependency (#271): v1.7.0 used a personal fork of tun2proxy (with a udpgw_server parameter added to the JNI signature) because upstream hadn't published the udpgw feature flag yet. With tun2proxy 0.7.21 now on crates.io with udpgw feature flag, and the upstream maintainer pointing callers at the C-style CLI API as the recommended path for Android, we drop the fork. New approach: mhrv-rs resolves tun2proxy_run_with_cli_args from libtun2proxy.so at runtime via dlsym and passes a simple CLI string (--proxy socks5://127.0.0.1:1081 --tun-fd <fd> --udpgw-server 198.18.0.1:7300 ...). No fork, no [patch.crates-io], no pinned SHA. Future tun2proxy upgrades are a single Cargo version bump. Thanks @yyoyoian-pixel

What's Changed

  • feat: enable udpgw client via tun2proxy CLI API — no fork needed by @yyoyoian-pixel in #271

Full Changelog: v1.7.2...v1.7.3

v1.7.2

26 Apr 17:37

Choose a tag to compare

• import/export کانفیگ در نسخهٔ اندروید با QR code، کلیپ‌بورد، deep link، و share sheet (#266): انتقال کانفیگ بین دستگاه‌ها با یک تپ. Export: یک دیالوگ یکپارچه با QR code + رشتهٔ فشرده + دکمهٔ کپی، یا Share از طریق هر اپ (تلگرام، WhatsApp، ایمیل). فیلدهای device-specific (پورت‌ها، حالت VPN/proxy، splitMode) export نمی‌شن، فقط فیلدهای منطقی (mode، script_ids، auth_key، sni_hosts، passthrough_hosts، upstream_socks5). encoding با DEFLATE compression + base64 — کانفیگ معمولی ~۲۰۰ کاراکتر می‌شه به‌جای ~۸۰۰. Import: clipboard banner خودکار وقتی مهرو متن mhrv-rs:// یا JSON خام در clipboard می‌بینه، scanner QR، یا deep link mhrv-rs://... (تپ روی لینک در هر اپ). هر import نیاز به تأیید صریح کاربر داره — قبل از overwrite شدن کانفیگ فعلی، یه دیالوگ deployment IDهای جدید رو نشون می‌ده و هشدار میده که "این لینک ترافیک شما رو از طریق این deployment IDها مسیریابی می‌کنه — فقط از منابع قابل اعتماد import کنید." این مهمه چون کانفیگ شامل auth_key هست. ممنون از @yyoyoian-pixel

• Config import/export on Android via QR code, clipboard, deep link, and share sheet (#266): one-tap config sharing between devices. Export: a unified dialog with QR code + compressed text hash + copy button, or Share via any app (Telegram, WhatsApp, email). Device-specific fields (ports, VPN/proxy mode, splitMode) are not exported — only logical config (mode, script_ids, auth_key, sni_hosts, passthrough_hosts, upstream_socks5). DEFLATE compression + base64 encoding shrinks a typical config from ~800 to ~200 chars. Import: clipboard banner auto-appears when mhrv-rs detects mhrv-rs://... or raw JSON in clipboard, QR scanner, or deep link mhrv-rs://... (tap from any app). Every import path requires explicit user confirmation — before the current config is overwritten, a dialog displays the new deployment IDs and warns "this link routes your traffic through these deployment IDs — only import from sources you trust." Important because the config contains auth_key. Thanks @yyoyoian-pixel

What's Changed

  • feat(android): config import/export — clipboard, QR, deep link, share by @yyoyoian-pixel in #266

Full Changelog: v1.7.1...v1.7.2

v1.7.1

26 Apr 16:36

Choose a tag to compare

• امکان حذف CA به‌صورت verified (#121): فلگ جدید mhrv-rs --remove-cert (CLI) و دکمهٔ Remove CA در UI دسکتاپ. CA رو از trust store سیستم‌عامل (Keychain مک، anchor dirs لینوکس، Trusted Root ویندوز)، NSS مرورگرها (Firefox/Chrome در لینوکس)، و فولدر ca/ روی دیسک پاک می‌کنه. config.json و deployment Apps Script شما دست نمی‌خوره — نیاز به redeploy نیست. قبل از هر کاری با store، یه trust verification by-name انجام می‌شه؛ اگه remove از سیستم‌عامل fail بشه، browser state دست نمی‌خوره و حالت RemovalIncomplete گزارش می‌شه (retry idempotent). در Unix، اگه با sudo اجرا بشه، HOME رو به user واقعی re-root می‌کنه تا path‌های user-scoped (NSS profile، login keychain) به /root نرن. ۲۹ unit test جدید پوشش‌دهی pure logic. تست شده end-to-end در ویندوز، و در v1.7.1 من مسیر macOS رو هم با hardware واقعی verify کردم (login keychain delete کار می‌کنه، NSS certutil-missing graceful fallback می‌ده). مسیر Linux منتظر تست از کاربرها. ممنون از @dazzling-no-more

• Verified CA removal (#121): new mhrv-rs --remove-cert flag (CLI) and a Remove CA button in the desktop UI. Clears the CA from the OS trust store (macOS Keychain, Linux anchor dirs, Windows Trusted Root), NSS browser stores (Firefox/Chrome on Linux), and the on-disk ca/ directory. config.json and your Apps Script deployment are never touched — no redeploy needed. A by-name trust verification runs before any browser-state mutation; if the OS removal fails, browser state is left alone and the call returns RemovalIncomplete (idempotent retries). On Unix, if invoked under sudo, HOME is re-rooted to the real user so user-scoped paths (NSS profile, login keychain) target the user, not root. 29 new unit tests covering the pure logic. Tested end-to-end on Windows by the contributor, and the macOS path was verified on real hardware during merge (login-keychain delete works; NSS-certutil-missing path falls back cleanly). Linux paths await user testing. Thanks @dazzling-no-more

What's Changed

  • feat(cert): add --remove-cert flag and Remove CA button for clean-slate revocation by @dazzling-no-more in #121

Full Changelog: v1.7.0...v1.7.1