Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package topgrade for openSUSE:Factory 
checked in at 2026-05-16 19:25:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/topgrade (Old)
 and      /work/SRC/openSUSE:Factory/.topgrade.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "topgrade"

Sat May 16 19:25:10 2026 rev:24 rq:1353480 version:17.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/topgrade/topgrade.changes        2026-04-25 
21:38:47.281240090 +0200
+++ /work/SRC/openSUSE:Factory/.topgrade.new.1966/topgrade.changes      
2026-05-16 19:26:32.659000524 +0200
@@ -1,0 +2,25 @@
+Sat May 16 00:34:44 UTC 2026 - Gerald Chen <[email protected]>
+
+- Update to version 17.5.0:
+  * chore: release v17.5.0 (#1984)
+  * fix(terminal): only accept actual keypresses in menus (#2020)
+  * fix(oh-my-bash): fix oh-my-bash failing in non-bash shells (#2014)
+  * chore(pre-commit): autoupdate (#2012)
+  * chore(deps): update actions/dependency-review-action action to v5 (#2000)
+  * chore(deps): update github/codeql-action action to v4.35.4 (#1999)
+  * chore(deps): update release-plz/action action to v0.5.129 (#2008)
+  * chore(deps): lock file maintenance (#2009)
+  * feat(step): add install-release (#2011)
+  * feat(vim): support neovim vim.pack updates (#2010)
+  * feat(protonplus): support flatpak installation of ProtonPlus (#2006)
+  * chore: label all new issues as 'needs triage' (#2007)
+  * chore(pre-commit): autoupdate (#1997)
+  * chore(deps): update github/codeql-action action to v4.35.3 (#1994)
+  * chore(deps): lock file maintenance (#1996)
+  * feat(mise): add options for quiet, silent, verbose, and add assume_yes 
support (#1990)
+  * feat(clamav): don't run if systemd autoupdater is active (#1988)
+  * chore(deps): lock file maintenance (#1987)
+  * feat: passwordless reboot and shutdown using `system_shutdown` (#1985)
+  * feat(cargo): add locked option for cargo install-update (#1980)
+
+-------------------------------------------------------------------

Old:
----
  topgrade-17.4.0.tar.zst

New:
----
  topgrade-17.5.0.tar.zst

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ topgrade.spec ++++++
--- /var/tmp/diff_new_pack.p9t4PB/_old  2026-05-16 19:26:34.119060390 +0200
+++ /var/tmp/diff_new_pack.p9t4PB/_new  2026-05-16 19:26:34.123060554 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           topgrade
-Version:        17.4.0
+Version:        17.5.0
 Release:        0
 Summary:        Upgrade all the things
 License:        GPL-3.0-only
@@ -30,8 +30,11 @@
 ExclusiveArch:  %{rust_tier1_arches}
 
 %description
-Keeping your system up to date usually involves invoking multiple package 
managers. This results in big, non-portable shell one-liners saved in your 
shell.
-To remedy this, Topgrade detects which tools you use and runs the appropriate 
commands to update them
+Keeping your system up to date usually involves invoking multiple
+package managers. This results in big, non-portable shell
+one-liners saved in your shell. To remedy this, Topgrade detects
+which tools you use and runs the appropriate commands to update
+them.
 
 %prep
 %autosetup -a1

++++++ _service ++++++
--- /var/tmp/diff_new_pack.p9t4PB/_old  2026-05-16 19:26:34.159062030 +0200
+++ /var/tmp/diff_new_pack.p9t4PB/_new  2026-05-16 19:26:34.163062194 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/topgrade-rs/topgrade.git</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="scm">git</param>
-    <param name="revision">v17.4.0</param>
+    <param name="revision">v17.5.0</param>
     <param name="match-tag">*</param>
     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.p9t4PB/_old  2026-05-16 19:26:34.187063179 +0200
+++ /var/tmp/diff_new_pack.p9t4PB/_new  2026-05-16 19:26:34.195063507 +0200
@@ -1,7 +1,7 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/topgrade-rs/topgrade.git</param>
-              <param 
name="changesrevision">ae6cc7ddf5c8a0ab3a4eabe84e55c87f93dfd538</param></service><service
 name="tar_scm">
+              <param 
name="changesrevision">4de8767a6753bf66dd744907009cab9cfb95249d</param></service><service
 name="tar_scm">
                 <param 
name="url">https://ghproxy.net/https://github.com/topgrade-rs/topgrade.git</param>
               <param 
name="changesrevision">ef0a0d69bbe0cb08d6c4930ee18b734e03c215fb</param></service></servicedata>
 (No newline at EOF)

++++++ topgrade-17.4.0.tar.zst -> topgrade-17.5.0.tar.zst ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/bug_report.md 
new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/bug_report.md
--- old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/bug_report.md    2026-04-24 
11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/bug_report.md    2026-05-15 
20:54:34.000000000 +0200
@@ -3,6 +3,7 @@
 about: Topgrade is misbehaving
 title: ''
 type: Bug
+labels: needs triage
 assignees: ''
 
 ---
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/feature_request.md 
new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/feature_request.md
--- old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/feature_request.md       
2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/feature_request.md       
2026-05-15 20:54:34.000000000 +0200
@@ -3,6 +3,7 @@
 about: Suggest a general feature, or feature within an already existing step
 title: ''
 type: Feature
+labels: needs triage
 assignees: ''
 
 ---
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/step_request.md 
new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/step_request.md
--- old/topgrade-17.4.0/.github/ISSUE_TEMPLATE/step_request.md  2026-04-24 
11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/ISSUE_TEMPLATE/step_request.md  2026-05-15 
20:54:34.000000000 +0200
@@ -3,7 +3,7 @@
 about: Suggest a new step/package manager to update
 title: ''
 type: Feature
-labels: request step
+labels: request step,needs triage
 assignees: ''
 
 ---
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/topgrade-17.4.0/.github/workflows/check_security_vulnerability.yml 
new/topgrade-17.5.0/.github/workflows/check_security_vulnerability.yml
--- old/topgrade-17.4.0/.github/workflows/check_security_vulnerability.yml      
2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/workflows/check_security_vulnerability.yml      
2026-05-15 20:54:34.000000000 +0200
@@ -32,6 +32,6 @@
         uses: 
microsoft/DevSkim-Action@4b5047945a44163b94642a1cecc0d93a3f428cc6 # v1.0.16
 
       - name: Upload DevSkim scan results to GitHub Security tab
-        uses: 
github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # 
v4.35.2
+        uses: 
github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # 
v4.35.4
         with:
           sarif_file: devskim-results.sarif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/topgrade-17.4.0/.github/workflows/dependency-review.yml 
new/topgrade-17.5.0/.github/workflows/dependency-review.yml
--- old/topgrade-17.4.0/.github/workflows/dependency-review.yml 2026-04-24 
11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/workflows/dependency-review.yml 2026-05-15 
20:54:34.000000000 +0200
@@ -22,4 +22,4 @@
           persist-credentials: false
 
       - name: 'Dependency Review'
-        uses: 
actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # 
v4.9.0
+        uses: 
actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # 
v5.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/.github/workflows/release-plz.yml 
new/topgrade-17.5.0/.github/workflows/release-plz.yml
--- old/topgrade-17.4.0/.github/workflows/release-plz.yml       2026-04-24 
11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/workflows/release-plz.yml       2026-05-15 
20:54:34.000000000 +0200
@@ -28,7 +28,7 @@
           toolchain: stable
       - name: Run release-plz
         id: release-plz
-        uses: release-plz/action@1528104d2ca23787631a1c1f022abb64b34c1e11 # 
v0.5.128
+        uses: release-plz/action@064f4d1e36c843611ddf013be726beaa4ad804db # 
v0.5.129
         with:
           command: release
         env:
@@ -66,7 +66,7 @@
         with:
           toolchain: stable
       - name: Run release-plz
-        uses: release-plz/action@1528104d2ca23787631a1c1f022abb64b34c1e11 # 
v0.5.128
+        uses: release-plz/action@064f4d1e36c843611ddf013be726beaa4ad804db # 
v0.5.129
         with:
           command: release-pr
         env:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/.github/workflows/scorecards.yml 
new/topgrade-17.5.0/.github/workflows/scorecards.yml
--- old/topgrade-17.4.0/.github/workflows/scorecards.yml        2026-04-24 
11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/.github/workflows/scorecards.yml        2026-05-15 
20:54:34.000000000 +0200
@@ -71,6 +71,6 @@
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: 
github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # 
v4.35.2
+        uses: 
github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # 
v4.35.4
         with:
           sarif_file: results.sarif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/.pre-commit-config.yaml 
new/topgrade-17.5.0/.pre-commit-config.yaml
--- old/topgrade-17.4.0/.pre-commit-config.yaml 2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/.pre-commit-config.yaml 2026-05-15 20:54:34.000000000 
+0200
@@ -17,7 +17,7 @@
   - id: trailing-whitespace
 
 - repo: https://github.com/adhtruong/mirrors-typos
-  rev: v1.45.1
+  rev: v1.46.1
   hooks:
   - id: typos
     args:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/CHANGELOG.md 
new/topgrade-17.5.0/CHANGELOG.md
--- old/topgrade-17.4.0/CHANGELOG.md    2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/CHANGELOG.md    2026-05-15 20:54:34.000000000 +0200
@@ -7,6 +7,23 @@
 
 ## [Unreleased]
 
+## [17.5.0](https://github.com/topgrade-rs/topgrade/compare/v17.4.0...v17.5.0) 
- 2026-05-15
+
+### Added
+
+- *(step)* add install-release 
([#2011](https://github.com/topgrade-rs/topgrade/pull/2011))
+- *(vim)* support neovim vim.pack updates 
([#2010](https://github.com/topgrade-rs/topgrade/pull/2010))
+- *(protonplus)* support flatpak installation of ProtonPlus 
([#2006](https://github.com/topgrade-rs/topgrade/pull/2006))
+- *(mise)* add options for quiet, silent, verbose, and add assume_yes support 
([#1990](https://github.com/topgrade-rs/topgrade/pull/1990))
+- *(clamav)* don't run if systemd autoupdater is active 
([#1988](https://github.com/topgrade-rs/topgrade/pull/1988))
+- passwordless reboot and shutdown using `system_shutdown` 
([#1985](https://github.com/topgrade-rs/topgrade/pull/1985))
+- *(cargo)* add locked option for cargo install-update 
([#1980](https://github.com/topgrade-rs/topgrade/pull/1980))
+
+### Fixed
+
+- *(terminal)* only accept actual keypresses in menus 
([#2020](https://github.com/topgrade-rs/topgrade/pull/2020))
+- *(oh-my-bash)* fix oh-my-bash failing in non-bash shells 
([#2014](https://github.com/topgrade-rs/topgrade/pull/2014))
+
 ## [17.4.0](https://github.com/topgrade-rs/topgrade/compare/v17.3.0...v17.4.0) 
- 2026-04-21
 
 ### Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/Cargo.lock 
new/topgrade-17.5.0/Cargo.lock
--- old/topgrade-17.4.0/Cargo.lock      2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/Cargo.lock      2026-05-15 20:54:34.000000000 +0200
@@ -381,9 +381,9 @@
 
 [[package]]
 name = "cc"
-version = "1.2.60"
+version = "1.2.62"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
+checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
 dependencies = [
  "find-msvc-tools",
  "jobserver",
@@ -392,12 +392,6 @@
 ]
 
 [[package]]
-name = "cesu8"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
-
-[[package]]
 name = "cfg-if"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -456,9 +450,9 @@
 
 [[package]]
 name = "clap_complete"
-version = "4.6.2"
+version = "4.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3ff7a1dccbdd8b078c2bdebff47e404615151534d5043da397ec50286816f9cb"
+checksum = "e3e962dae2b1e5007fe9e3db363ddc43a8bf25546d279f7a8a4401204690e80c"
 dependencies = [
  "clap",
 ]
@@ -679,6 +673,33 @@
 checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
 
 [[package]]
+name = "crossterm"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
+dependencies = [
+ "bitflags 2.11.1",
+ "crossterm_winapi",
+ "document-features",
+ "filedescriptor",
+ "mio",
+ "parking_lot",
+ "rustix 1.1.4",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
+[[package]]
+name = "crossterm_winapi"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "crunchy"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -980,14 +1001,24 @@
 checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
 
 [[package]]
+name = "filedescriptor"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
+dependencies = [
+ "libc",
+ "thiserror 1.0.69",
+ "winapi",
+]
+
+[[package]]
 name = "filetime"
-version = "0.2.27"
+version = "0.2.28"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
+checksum = "2d5b2eef6fafbf69f877e55509ce5b11a760690ac9700a2921be067aa6afaef6"
 dependencies = [
  "cfg-if",
  "libc",
- "libredox",
 ]
 
 [[package]]
@@ -1237,9 +1268,9 @@
 
 [[package]]
 name = "h2"
-version = "0.4.13"
+version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
+checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -1271,9 +1302,9 @@
 
 [[package]]
 name = "hashbrown"
-version = "0.17.0"
+version = "0.17.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
 
 [[package]]
 name = "heck"
@@ -1525,9 +1556,9 @@
 
 [[package]]
 name = "idna_adapter"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -1562,7 +1593,7 @@
 checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
 dependencies = [
  "equivalent",
- "hashbrown 0.17.0",
+ "hashbrown 0.17.1",
  "serde",
  "serde_core",
 ]
@@ -1587,16 +1618,6 @@
 checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
 
 [[package]]
-name = "iri-string"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20"
-dependencies = [
- "memchr",
- "serde",
-]
-
-[[package]]
 name = "is_elevated"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1650,27 +1671,32 @@
 
 [[package]]
 name = "jni"
-version = "0.21.1"
+version = "0.22.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
+checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
 dependencies = [
- "cesu8",
  "cfg-if",
  "combine",
- "jni-sys 0.3.1",
+ "jni-macros",
+ "jni-sys",
  "log",
- "thiserror 1.0.69",
+ "simd_cesu8",
+ "thiserror 2.0.18",
  "walkdir",
- "windows-sys 0.45.0",
+ "windows-link 0.2.1",
 ]
 
 [[package]]
-name = "jni-sys"
-version = "0.3.1"
+name = "jni-macros"
+version = "0.22.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
+checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
 dependencies = [
- "jni-sys 0.4.1",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "simd_cesu8",
+ "syn",
 ]
 
 [[package]]
@@ -1704,9 +1730,9 @@
 
 [[package]]
 name = "js-sys"
-version = "0.3.95"
+version = "0.3.98"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
+checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
 dependencies = [
  "cfg-if",
  "futures-util",
@@ -1728,9 +1754,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.185"
+version = "0.2.186"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
 
 [[package]]
 name = "libredox"
@@ -1738,10 +1764,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
 dependencies = [
- "bitflags 2.11.1",
  "libc",
- "plain",
- "redox_syscall",
 ]
 
 [[package]]
@@ -1769,6 +1792,15 @@
 checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
 
 [[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
 name = "log"
 version = "0.4.29"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1855,6 +1887,7 @@
 checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
 dependencies = [
  "libc",
+ "log",
  "wasi",
  "windows-sys 0.61.2",
 ]
@@ -1873,18 +1906,18 @@
 
 [[package]]
 name = "normpath"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b"
+checksum = "b9985ef7269fa99f3b12437bb698381da2428743ab90f20393f399fa14cab21a"
 dependencies = [
  "windows-sys 0.61.2",
 ]
 
 [[package]]
 name = "notify-rust"
-version = "4.16.0"
+version = "4.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5e551a9f0db223eaf3eb156906f99f46897fd951ee66dd1cb0be14db4d36d2fa"
+checksum = "50ff2e74231b72c832d82982193b417f230945be6bdb5575b251d941d31adb00"
 dependencies = [
  "futures-lite",
  "log",
@@ -2042,6 +2075,29 @@
 checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
 
 [[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-link 0.2.1",
+]
+
+[[package]]
 name = "parse-changelog"
 version = "0.6.16"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2099,12 +2155,6 @@
 ]
 
 [[package]]
-name = "plain"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
-
-[[package]]
 name = "polling"
 version = "3.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2333,9 +2383,9 @@
 
 [[package]]
 name = "redox_syscall"
-version = "0.7.4"
+version = "0.5.18"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
 dependencies = [
  "bitflags 2.11.1",
 ]
@@ -2391,9 +2441,9 @@
 
 [[package]]
 name = "reqwest"
-version = "0.13.2"
+version = "0.13.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
+checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0"
 dependencies = [
  "base64",
  "bytes",
@@ -2559,9 +2609,9 @@
 
 [[package]]
 name = "rustls"
-version = "0.23.38"
+version = "0.23.40"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21"
+checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
 dependencies = [
  "aws-lc-rs",
  "log",
@@ -2587,9 +2637,9 @@
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.14.0"
+version = "1.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
+checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
 dependencies = [
  "web-time",
  "zeroize",
@@ -2597,9 +2647,9 @@
 
 [[package]]
 name = "rustls-platform-verifier"
-version = "0.6.2"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
+checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
 dependencies = [
  "core-foundation",
  "core-foundation-sys",
@@ -2624,9 +2674,9 @@
 
 [[package]]
 name = "rustls-webpki"
-version = "0.103.12"
+version = "0.103.13"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06"
+checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
 dependencies = [
  "aws-lc-rs",
  "ring",
@@ -2665,6 +2715,12 @@
 ]
 
 [[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
 name = "security-framework"
 version = "3.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2857,6 +2913,27 @@
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
+name = "signal-hook"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-mio"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
+dependencies = [
+ "libc",
+ "mio",
+ "signal-hook",
+]
+
+[[package]]
 name = "signal-hook-registry"
 version = "1.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2883,10 +2960,26 @@
 checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
 
 [[package]]
+name = "simd_cesu8"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
+dependencies = [
+ "rustc_version",
+ "simdutf8",
+]
+
+[[package]]
+name = "simdutf8"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
+
+[[package]]
 name = "siphasher"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
+checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
 
 [[package]]
 name = "slab"
@@ -3025,6 +3118,16 @@
 ]
 
 [[package]]
+name = "system_shutdown"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "29396e5e1b637d102ec5037bf7fbb8da78264fa299101ced9ce827756b1bac02"
+dependencies = [
+ "windows 0.62.2",
+ "zbus",
+]
+
+[[package]]
 name = "tar"
 version = "0.4.45"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -3176,9 +3279,9 @@
 
 [[package]]
 name = "tokio"
-version = "1.52.1"
+version = "1.52.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
 dependencies = [
  "bytes",
  "libc",
@@ -3236,7 +3339,7 @@
  "toml_datetime 1.1.1+spec-1.1.0",
  "toml_parser",
  "toml_writer",
- "winnow 1.0.1",
+ "winnow 1.0.2",
 ]
 
 [[package]]
@@ -3280,7 +3383,7 @@
  "indexmap",
  "toml_datetime 1.1.1+spec-1.1.0",
  "toml_parser",
- "winnow 1.0.1",
+ "winnow 1.0.2",
 ]
 
 [[package]]
@@ -3289,7 +3392,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
 dependencies = [
- "winnow 1.0.1",
+ "winnow 1.0.2",
 ]
 
 [[package]]
@@ -3306,7 +3409,7 @@
 
 [[package]]
 name = "topgrade"
-version = "17.4.0"
+version = "17.5.0"
 dependencies = [
  "chrono",
  "clap",
@@ -3315,6 +3418,7 @@
  "clap_mangen",
  "color-eyre",
  "console",
+ "crossterm",
  "edit",
  "etcetera",
  "futures",
@@ -3340,6 +3444,7 @@
  "shellexpand",
  "strum",
  "sys-locale",
+ "system_shutdown",
  "tempfile",
  "thiserror 2.0.18",
  "tokio",
@@ -3370,20 +3475,20 @@
 
 [[package]]
 name = "tower-http"
-version = "0.6.8"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
+checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51"
 dependencies = [
  "bitflags 2.11.1",
  "bytes",
  "futures-util",
  "http",
  "http-body",
- "iri-string",
  "pin-project-lite",
  "tower",
  "tower-layer",
  "tower-service",
+ "url",
 ]
 
 [[package]]
@@ -3685,9 +3790,9 @@
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.118"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
+checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -3698,9 +3803,9 @@
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.68"
+version = "0.4.71"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8"
+checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -3708,9 +3813,9 @@
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.118"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
+checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -3718,9 +3823,9 @@
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.118"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
+checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
 dependencies = [
  "bumpalo",
  "proc-macro2",
@@ -3731,9 +3836,9 @@
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.118"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
+checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
 dependencies = [
  "unicode-ident",
 ]
@@ -3774,9 +3879,9 @@
 
 [[package]]
 name = "web-sys"
-version = "0.3.95"
+version = "0.3.98"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
+checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -4068,15 +4173,6 @@
 
 [[package]]
 name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
@@ -4113,21 +4209,6 @@
 
 [[package]]
 name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
@@ -4188,12 +4269,6 @@
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
@@ -4206,12 +4281,6 @@
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
@@ -4224,12 +4293,6 @@
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
@@ -4254,12 +4317,6 @@
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
@@ -4272,12 +4329,6 @@
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
@@ -4290,12 +4341,6 @@
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
@@ -4308,12 +4353,6 @@
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
@@ -4335,9 +4374,9 @@
 
 [[package]]
 name = "winnow"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5"
+checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0"
 dependencies = [
  "memchr",
 ]
@@ -4483,9 +4522,9 @@
 
 [[package]]
 name = "zbus"
-version = "5.14.0"
+version = "5.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc"
+checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1"
 dependencies = [
  "async-broadcast",
  "async-executor",
@@ -4510,7 +4549,7 @@
  "uds_windows",
  "uuid",
  "windows-sys 0.61.2",
- "winnow 0.7.15",
+ "winnow 1.0.2",
  "zbus_macros",
  "zbus_names",
  "zvariant",
@@ -4518,9 +4557,9 @@
 
 [[package]]
 name = "zbus_macros"
-version = "5.14.0"
+version = "5.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222"
+checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -4533,12 +4572,12 @@
 
 [[package]]
 name = "zbus_names"
-version = "4.3.1"
+version = "4.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f"
+checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
 dependencies = [
  "serde",
- "winnow 0.7.15",
+ "winnow 1.0.2",
  "zvariant",
 ]
 
@@ -4674,23 +4713,23 @@
 
 [[package]]
 name = "zvariant"
-version = "5.10.0"
+version = "5.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b"
+checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
 dependencies = [
  "endi",
  "enumflags2",
  "serde",
- "winnow 0.7.15",
+ "winnow 1.0.2",
  "zvariant_derive",
  "zvariant_utils",
 ]
 
 [[package]]
 name = "zvariant_derive"
-version = "5.10.0"
+version = "5.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c"
+checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -4701,13 +4740,13 @@
 
 [[package]]
 name = "zvariant_utils"
-version = "3.3.0"
+version = "3.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9"
+checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691"
 dependencies = [
  "proc-macro2",
  "quote",
  "serde",
  "syn",
- "winnow 0.7.15",
+ "winnow 1.0.2",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/Cargo.toml 
new/topgrade-17.5.0/Cargo.toml
--- old/topgrade-17.4.0/Cargo.toml      2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/Cargo.toml      2026-05-15 20:54:34.000000000 +0200
@@ -6,7 +6,7 @@
 license = "GPL-3.0-or-later"
 repository = "https://github.com/topgrade-rs/topgrade";
 rust-version = "1.88.0"
-version = "17.4.0"
+version = "17.5.0"
 exclude = ["doc/screenshot.gif", "BREAKINGCHANGES_dev.md"]
 edition = "2024"
 
@@ -23,6 +23,7 @@
 clap_mangen = "0.3"
 walkdir = "2.5"
 console = "0.16"
+crossterm = { version = "0.29", default-features = false, features = 
["bracketed-paste", "events", "use-dev-tty", "windows"] }
 chrono = "0.4"
 glob = "0.3"
 strum = { version = "0.28.0", features = ["derive"] }
@@ -77,6 +78,9 @@
   ["deployment/deb/_topgrade", "usr/share/zsh/vendor-completions/", "644"],
 ]
 
+[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = 
"windows"))'.dependencies]
+system_shutdown = "4.1.0"
+
 [target.'cfg(unix)'.dependencies]
 nix = { version = "0.31", features = ["hostname", "signal", "user"] }
 rust-ini = "0.21"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/config.example.toml 
new/topgrade-17.5.0/config.example.toml
--- old/topgrade-17.4.0/config.example.toml     2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/config.example.toml     2026-05-15 20:54:34.000000000 
+0200
@@ -336,6 +336,19 @@
 # (default: false)
 # interactive = false
 
+# Suppress non-error messages
+# (default: false)
+# quiet = false
+
+# Suppress all task output and mise non-error messages
+# (default: false)
+# silent = false
+
+# Show extra output
+# (default: false)
+# verbose = false
+
+
 [go]
 # Exclude specified binaries from `gup update`
 # gup_exclude = ["kind", "pkgsite"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/locales/app.yml 
new/topgrade-17.5.0/locales/app.yml
--- old/topgrade-17.4.0/locales/app.yml 2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/locales/app.yml 2026-05-15 20:54:34.000000000 +0200
@@ -48,6 +48,14 @@
   zh_CN: "正在重新启动..."
   zh_TW: "正在重新啟動..."
   de: "Neustart..."
+"Shutting down...":
+  en: "Shutting down..."
+  lt: "Išjungiamas..."
+  es: "Apagando..."
+  fr: "Arrêt..."
+  zh_CN: "正在关机..."
+  zh_TW: "正在關機..."
+  de: "Herunterfahren..."
 "Plugins upgraded":
   en: "Plugins upgraded"
   lt: "Įskiepiai atnaujinti"
@@ -1159,15 +1167,15 @@
   zh_TW: "再試一次? (y)是/(N)否/(s)Shell/(q)退出"
   de: "Wiederholen? (y) Ja / (n) Nein / (s) Shell / (q) Beenden"
 
-# 'R', 'S', 'Q'  have to stay the same throughout all translations. Eg German 
would look like "\n(R) Neustarten\n(S) Konsole\n(Q) Beenden"
-"\n(R)eboot\n(S)hell\n(Q)uit":
-  en: "\n(R)eboot\n(S)hell\n(Q)uit"
-  lt: "\n(R)perkrovimas\n(S)shell\n(Q)išeiti"
-  es: "\n(R) Reiniciar\n(S) Shell\n(Q) Salir"
-  fr: "\n(R) Redémarrer\n(S) Shell\n(Q) Quitter"
-  zh_CN: "\n(R)重启\n(S)Shell\n(Q)退出"
-  zh_TW: "\n(R)重新啟動\n(S)shell\n(Q)退出"
-  de: "\n(R) Neustarten\n(S)hell\n(Q)uit beenden"
+# 'R', 'P', 'S', 'Q' have to stay the same throughout all translations. Eg 
German would look like "\n(R) Neustarten\n(P) Herunterfahren\n(S) Konsole\n(Q) 
Beenden"
+"\n(R)eboot\n(P)oweroff\n(S)hell\n(Q)uit":
+  en: "\n(R)eboot\n(P)oweroff\n(S)hell\n(Q)uit"
+  lt: "\n(R)perkrovimas\n(P)risijungti\n(S)shell\n(Q)išeiti"
+  es: "\n(R) Reiniciar\n(P) Apagar\n(S) Shell\n(Q) Salir"
+  fr: "\n(R) Redémarrer\n(P) Éteindre\n(S) Shell\n(Q) Quitter"
+  zh_CN: "\n(R)重启\n(P)关机\n(S)Shell\n(Q)退出"
+  zh_TW: "\n(R)重新啟動\n(P)關機\n(S)shell\n(Q)退出"
+  de: "\n(R) Neustarten\n(P) Herunterfahren\n(S)hell\n(Q)uit beenden"
 
 "Continue?":
   en: "Continue?"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/config.rs 
new/topgrade-17.5.0/src/config.rs
--- old/topgrade-17.4.0/src/config.rs   2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/src/config.rs   2026-05-15 20:54:34.000000000 +0200
@@ -220,6 +220,12 @@
     interactive: Option<bool>,
     #[merge(strategy = merge::option::overwrite_none)]
     jobs: Option<u32>,
+    #[merge(strategy = merge::option::overwrite_none)]
+    verbose: Option<bool>,
+    #[merge(strategy = merge::option::overwrite_none)]
+    quiet: Option<bool>,
+    #[merge(strategy = merge::option::overwrite_none)]
+    silent: Option<bool>,
 }
 
 #[derive(Deserialize, Default, Debug, Merge)]
@@ -566,6 +572,8 @@
     git: Option<bool>,
     #[merge(strategy = merge::option::overwrite_none)]
     quiet: Option<bool>,
+    #[merge(strategy = merge::option::overwrite_none)]
+    locked: Option<bool>,
 }
 
 #[derive(Deserialize, Default, Debug, Merge)]
@@ -1878,6 +1886,14 @@
             .unwrap_or(false)
     }
 
+    pub fn cargo_update_locked(&self) -> bool {
+        self.config_file
+            .cargo
+            .as_ref()
+            .and_then(|cargo| cargo.locked)
+            .unwrap_or(false)
+    }
+
     pub fn rustup_channels(&self) -> Vec<String> {
         self.config_file
             .rustup
@@ -2190,6 +2206,30 @@
             .unwrap_or(false)
     }
 
+    pub fn mise_quiet(&self) -> bool {
+        self.config_file
+            .mise
+            .as_ref()
+            .and_then(|mise| mise.quiet)
+            .unwrap_or(false)
+    }
+
+    pub fn mise_silent(&self) -> bool {
+        self.config_file
+            .mise
+            .as_ref()
+            .and_then(|mise| mise.silent)
+            .unwrap_or(false)
+    }
+
+    pub fn mise_verbose(&self) -> bool {
+        self.config_file
+            .mise
+            .as_ref()
+            .and_then(|mise| mise.verbose)
+            .unwrap_or(false)
+    }
+
     pub fn vscode_profile(&self) -> Option<&str> {
         let vscode_cfg = self.config_file.vscode.as_ref()?;
         let profile = vscode_cfg.profile.as_ref()?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/main.rs 
new/topgrade-17.5.0/src/main.rs
--- old/topgrade-17.4.0/src/main.rs     2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/src/main.rs     2026-05-15 20:54:34.000000000 +0200
@@ -11,7 +11,7 @@
 use clap::{Parser, crate_version};
 use color_eyre::eyre::Context;
 use color_eyre::eyre::Result;
-use console::Key;
+use crossterm::event::KeyCode;
 #[cfg(windows)]
 use etcetera::base_strategy::Windows;
 #[cfg(unix)]
@@ -281,17 +281,21 @@
     }
 
     if config.keep_at_end() {
-        print_info(t!("\n(R)eboot\n(S)hell\n(Q)uit"));
+        print_info(t!("\n(R)eboot\n(P)oweroff\n(S)hell\n(Q)uit"));
         loop {
             match get_key() {
-                Ok(Key::Char('s' | 'S')) => {
+                Ok(KeyCode::Char('s' | 'S')) => {
                     run_shell().context("Failed to execute shell")?;
                 }
-                Ok(Key::Char('r' | 'R')) => {
+                Ok(KeyCode::Char('r' | 'R')) => {
                     println!("{}", t!("Rebooting..."));
                     reboot(&ctx).context("Failed to reboot")?;
                 }
-                Ok(Key::Char('q' | 'Q')) => (),
+                Ok(KeyCode::Char('p' | 'P')) => {
+                    println!("{}", t!("Shutting down..."));
+                    shutdown(&ctx).context("Failed to shut down")?;
+                }
+                Ok(KeyCode::Char('q' | 'Q')) => (),
                 _ => {
                     continue;
                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/step.rs 
new/topgrade-17.5.0/src/step.rs
--- old/topgrade-17.4.0/src/step.rs     2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/src/step.rs     2026-05-15 20:54:34.000000000 +0200
@@ -82,6 +82,7 @@
     Helm,
     HomeManager,
     Hyprpm,
+    InstallRelease,
     // These names are miscapitalized on purpose, so the CLI name is
     //  `jetbrains_pycharm` instead of `jet_brains_py_charm`.
     JetbrainsAqua,
@@ -387,6 +388,11 @@
                 #[cfg(unix)]
                 runner.execute(*self, "hyprpm", || unix::run_hyprpm(ctx))?
             }
+            InstallRelease =>
+            {
+                #[cfg(unix)]
+                runner.execute(*self, "Install Release", || 
unix::run_install_release(ctx))?
+            }
             JetbrainsAqua => runner.execute(*self, "JetBrains Aqua Plugins", 
|| generic::run_jetbrains_aqua(ctx))?,
             JetbrainsClion => runner.execute(*self, "JetBrains CL", || 
generic::run_jetbrains_clion(ctx))?,
             JetbrainsDatagrip => {
@@ -930,5 +936,6 @@
         CustomCommands,
         Vagrant,
         Typst,
+        InstallRelease,
     ]
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/generic.rs 
new/topgrade-17.5.0/src/steps/generic.rs
--- old/topgrade-17.4.0/src/steps/generic.rs    2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/generic.rs    2026-05-15 20:54:34.000000000 
+0200
@@ -80,6 +80,9 @@
     if ctx.config().cargo_update_quiet() {
         command.arg("--quiet");
     }
+    if ctx.config().cargo_update_locked() {
+        command.arg("--locked");
+    }
     command.status_checked()?;
 
     if ctx.config().cleanup() {
@@ -1434,6 +1437,22 @@
 /// doc: 
https://docs.clamav.net/manual/Usage/SignatureManagement.html#freshclam
 pub fn run_freshclam(ctx: &ExecutionContext) -> Result<()> {
     let freshclam = require("freshclam")?;
+
+    #[cfg(target_os = "linux")]
+    if let Ok(systemctl) = require("systemctl") {
+        for unit in ["clamav-freshclam.service", 
"clamav-freshclam-once.timer"] {
+            if ctx
+                .execute(&systemctl)
+                .always()
+                .args(["is-active", "--quiet", unit])
+                .status_checked()
+                .is_ok()
+            {
+                return Err(SkipStep("ClamAV freshclam autoupdate is active via 
systemd".to_string()).into());
+            }
+        }
+    }
+
     print_separator(t!("Update ClamAV Database(FreshClam)"));
 
     let output = ctx.execute(&freshclam).output()?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/os/linux.rs 
new/topgrade-17.5.0/src/steps/os/linux.rs
--- old/topgrade-17.4.0/src/steps/os/linux.rs   2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/os/linux.rs   2026-05-15 20:54:34.000000000 
+0200
@@ -1259,18 +1259,31 @@
 }
 
 pub fn run_protonplus_update(ctx: &ExecutionContext) -> Result<()> {
-    let protonplus = require("protonplus")?;
+    let (program, flatpak) = match require("protonplus") {
+        Ok(protonplus) => (protonplus, false),
+        Err(_) => {
+            require_flatpak(ctx, "com.vysp3r.ProtonPlus")?;
+            (require("flatpak")?, true)
+        }
+    };
+    let cmd = || {
+        let mut cmd = ctx.execute(&program);
+        if flatpak {
+            cmd.args(["run", "com.vysp3r.ProtonPlus"]);
+        }
+        cmd
+    };
 
-    if let Err(e) = 
ctx.execute(&protonplus).args(["invalidarg67"]).output_checked()
+    if let Err(e) = cmd().args(["invalidarg67"]).output_checked()
         && let Some(TopgradeError::ProcessFailedWithOutput(_, _, stderr)) = 
e.downcast_ref()
         && stderr.contains("This application can not open files")
     {
         return Err(SkipStep("Updates unsupported for ProtonPlus versions under 
v0.5.17".to_string()).into());
     }
 
-    print_separator("ProtonPlus");
+    print_separator(if flatpak { "ProtonPlus (Flatpak)" } else { "ProtonPlus" 
});
 
-    ctx.execute(&protonplus).args(["update", "all"]).status_checked()
+    cmd().args(["update", "all"]).status_checked()
 }
 
 #[cfg(test)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/os/mod.rs 
new/topgrade-17.5.0/src/steps/os/mod.rs
--- old/topgrade-17.4.0/src/steps/os/mod.rs     2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/os/mod.rs     2026-05-15 20:54:34.000000000 
+0200
@@ -18,7 +18,7 @@
 pub mod windows;
 
 #[cfg(windows)]
-pub use windows::reboot;
+pub use windows::{reboot, shutdown};
 
 #[cfg(unix)]
-pub use unix::reboot;
+pub use unix::{reboot, shutdown};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/os/unix.rs 
new/topgrade-17.5.0/src/steps/os/unix.rs
--- old/topgrade-17.4.0/src/steps/os/unix.rs    2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/os/unix.rs    2026-05-15 20:54:34.000000000 
+0200
@@ -249,10 +249,15 @@
 
     print_separator("oh-my-bash");
 
-    let mut update_script = oh_my_bash;
+    let mut update_script = oh_my_bash.clone();
     update_script.push_str("/tools/upgrade.sh");
 
-    ctx.execute("bash").arg(update_script).status_checked()
+    ctx.execute("bash")
+        .arg(update_script)
+        // oh-my-bash fails if $OSH does not point to its installation path.
+        // if $OSH was unset (e.g. if we run from zsh) but we found OMB 
anyway, we want to tell it where.
+        .env("OSH", oh_my_bash)
+        .status_checked()
 }
 
 pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
@@ -898,6 +903,22 @@
         cmd.arg("--bump");
     }
 
+    if ctx.config().mise_silent() {
+        cmd.arg("--silent");
+    }
+
+    if ctx.config().mise_quiet() {
+        cmd.arg("--quiet");
+    }
+
+    if ctx.config().mise_verbose() {
+        cmd.arg("--verbose");
+    }
+
+    if ctx.config().yes(Step::Mise) {
+        cmd.arg("--yes");
+    }
+
     if ctx.config().mise_jobs() != 4 {
         cmd.args(["--jobs", &ctx.config().mise_jobs().to_string()]);
     }
@@ -1081,8 +1102,45 @@
 }
 
 pub fn reboot(ctx: &ExecutionContext) -> Result<()> {
+    #[cfg(any(target_os = "linux", target_os = "macos"))]
+    if let Ok(()) = system_shutdown::reboot() {
+        return Ok(());
+    }
     match ctx.sudo() {
         Some(sudo) => sudo.execute(ctx, "reboot")?.status_checked(),
         None => ctx.execute("reboot").status_checked(),
     }
 }
+
+pub fn shutdown(ctx: &ExecutionContext) -> Result<()> {
+    #[cfg(any(target_os = "linux", target_os = "macos"))]
+    if let Ok(()) = system_shutdown::shutdown() {
+        return Ok(());
+    }
+    match ctx.sudo() {
+        Some(sudo) => sudo.execute(ctx, 
"shutdown")?.args(["now"]).status_checked(),
+        None => ctx.execute("shutdown").args(["now"]).status_checked(),
+    }
+}
+
+/// See: <https://github.com/Rishang/install-release>
+pub fn run_install_release(ctx: &ExecutionContext) -> Result<()> {
+    let ir = require_one(["ir", "install-release"])?;
+
+    print_separator("Install Release");
+
+    let mut command = ctx.execute(&ir);
+    command.args(["upgrade", "--pkg"]);
+    if ctx.config().yes(Step::InstallRelease) {
+        command.arg("-y");
+    }
+    command.status_checked()?;
+
+    let mut command = ctx.execute(&ir);
+    command.arg("upgrade");
+    if ctx.config().yes(Step::InstallRelease) {
+        command.arg("-y");
+    }
+    command.status_checked()?;
+    Ok(())
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/os/windows.rs 
new/topgrade-17.5.0/src/steps/os/windows.rs
--- old/topgrade-17.4.0/src/steps/os/windows.rs 2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/os/windows.rs 2026-05-15 20:54:34.000000000 
+0200
@@ -270,10 +270,12 @@
     Ok(())
 }
 
-pub fn reboot(ctx: &ExecutionContext) -> Result<()> {
-    // If this works, it won't return, but if it doesn't work, it may return a 
useful error
-    // message.
-    ctx.execute("shutdown.exe").args(["/R", "/T", "0"]).status_checked()
+pub fn reboot(_ctx: &ExecutionContext) -> Result<()> {
+    system_shutdown::reboot().map_err(Into::into)
+}
+
+pub fn shutdown(_ctx: &ExecutionContext) -> Result<()> {
+    system_shutdown::shutdown().map_err(Into::into)
 }
 
 pub fn insert_startup_scripts(ctx: &ExecutionContext, git_repos: &mut 
RepoStep) -> Result<()> {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/steps/upgrade.vim 
new/topgrade-17.5.0/src/steps/upgrade.vim
--- old/topgrade-17.4.0/src/steps/upgrade.vim   2026-04-24 11:04:18.000000000 
+0200
+++ new/topgrade-17.5.0/src/steps/upgrade.vim   2026-05-15 20:54:34.000000000 
+0200
@@ -11,6 +11,10 @@
     finish
 endif
 
+if has("nvim")
+    lua if vim.pack and next(vim.pack.get(nil, { info = false })) ~= nil then 
vim.pack.update(nil, { force = true }) end
+endif
+
 if exists(":MasonUpdate")
        echo "MasonUpdate"
        MasonUpdate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/topgrade-17.4.0/src/terminal.rs 
new/topgrade-17.5.0/src/terminal.rs
--- old/topgrade-17.4.0/src/terminal.rs 2026-04-24 11:04:18.000000000 +0200
+++ new/topgrade-17.5.0/src/terminal.rs 2026-05-15 20:54:34.000000000 +0200
@@ -8,7 +8,9 @@
 use chrono::{Local, Timelike};
 use color_eyre::eyre;
 use color_eyre::eyre::Context;
-use console::{Key, Term, measure_text_width, style};
+use console::{Term, measure_text_width, style};
+use crossterm::event::{DisableBracketedPaste, EnableBracketedPaste, Event, 
KeyCode, KeyEventKind, read};
+use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
 use notify_rust::{Notification, Timeout};
 use rust_i18n::t;
 use tracing::{debug, error};
@@ -44,6 +46,24 @@
     desktop_notification: bool,
 }
 
+struct RawTerminalMode;
+
+impl RawTerminalMode {
+    fn enter() -> io::Result<Self> {
+        enable_raw_mode()?;
+        let guard = Self;
+        crossterm::execute!(io::stdout(), EnableBracketedPaste)?;
+        Ok(guard)
+    }
+}
+
+impl Drop for RawTerminalMode {
+    fn drop(&mut self) {
+        crossterm::execute!(io::stdout(), DisableBracketedPaste).unwrap();
+        disable_raw_mode().unwrap();
+    }
+}
+
 impl Terminal {
     fn new() -> Self {
         let term = Term::stdout();
@@ -195,9 +215,9 @@
             .ok();
 
         loop {
-            match self.term.read_char()? {
-                'y' | 'Y' => break Ok(true),
-                'n' | 'N' | '\r' | '\n' => break Ok(false),
+            match self.get_char()? {
+                KeyCode::Char('y' | 'Y') => break Ok(true),
+                KeyCode::Char('n' | 'N') | KeyCode::Enter => break Ok(false),
                 _ => (),
             }
         }
@@ -222,9 +242,9 @@
 
         let answer = loop {
             self.term.write_fmt(format_args!("\n{prompt_inner}")).ok();
-            match self.term.read_key() {
-                Ok(Key::Char('y' | 'Y')) => break Ok(ShouldRetry::Yes),
-                Ok(Key::Char('s' | 'S')) => {
+            match self.get_char() {
+                Ok(KeyCode::Char('y' | 'Y')) => break Ok(ShouldRetry::Yes),
+                Ok(KeyCode::Char('s' | 'S')) => {
                     println!(
                         "\n\n{}\n",
                         t!("Dropping you to shell. Fix what you need and then 
exit the shell.")
@@ -235,7 +255,7 @@
                         break Ok(ShouldRetry::Yes);
                     }
                 }
-                Ok(Key::Char('n' | 'N') | Key::Enter) => break 
Ok(ShouldRetry::No),
+                Ok(KeyCode::Char('n' | 'N') | KeyCode::Enter) => break 
Ok(ShouldRetry::No),
                 Err(e) => {
                     if let io::ErrorKind::Interrupted = e.kind() {
                         println!();
@@ -245,7 +265,7 @@
                     error!("Error reading from terminal: {}", e);
                     break Ok(ShouldRetry::No);
                 }
-                Ok(Key::Char('q' | 'Q')) => {
+                Ok(KeyCode::Char('q' | 'Q')) => {
                     break Ok(ShouldRetry::Quit);
                 }
                 _ => (),
@@ -257,8 +277,15 @@
         answer
     }
 
-    fn get_char(&self) -> Result<Key, io::Error> {
-        self.term.read_key()
+    fn get_char(&self) -> io::Result<KeyCode> {
+        let _raw_mode_guard = RawTerminalMode::enter()?;
+        loop {
+            let Event::Key(key) = read()? else { continue };
+            if key.kind != KeyEventKind::Press {
+                continue;
+            }
+            break Ok(key.code);
+        }
     }
 }
 
@@ -307,7 +334,7 @@
     TERMINAL.lock().unwrap().width.is_none()
 }
 
-pub fn get_key() -> Result<Key, io::Error> {
+pub fn get_key() -> io::Result<KeyCode> {
     TERMINAL.lock().unwrap().get_char()
 }
 

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/topgrade/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.topgrade.new.1966/vendor.tar.zst differ: char 7, 
line 1

Reply via email to