@dahch/heimdall 1.1.0 โ†’ 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +55 -7
  2. package/dist/cli.js +1446 -396
  3. package/package.json +14 -3
package/README.md CHANGED
@@ -19,8 +19,10 @@
19
19
  1. **Detection & Bounded Scan**: Available package managers are checked concurrently using an internal worker pool (concurrency limit of 4) to query pending updates without overloading CPU or network.
20
20
  2. **Aggregated Review & Confirmation**: Shows an interactive tabular overview comparing current and latest package versions across all managers, prompting for confirmation before modifying the system.
21
21
  - ๐Ÿงช **True Simulated Dry-Run (`--dry-run`)**: Traverses the full engine lifecycle, formats outdated packages, and executes mock update routines step-by-step with real-time feedback without touching system files.
22
- - โšก **High-Speed Registry Queries**: Yarn and pipx bypass heavy CLI subprocess spawning by querying the npm Registry and PyPI JSON APIs directly over HTTP with strict 3-second abort timeouts.
23
- - ๐Ÿ” **Non-Interactive Sudo Pre-Checks**: Privileged managers (MacPorts, Linux APT, Linux DNF) verify cached credentials using `sudo -n true` beforehand, preventing terminal lockups and password prompt hangs.
22
+ - โšก **High-Speed Registry Queries**: Yarn, pipx, uv and Poetry bypass heavy CLI subprocess spawning by querying the npm Registry and PyPI JSON APIs directly over HTTP with strict 3-second abort timeouts.
23
+ - ๐Ÿ”ง **Firmware Updates (Linux)**: Detects pending firmware through `fwupd` (`fwupdmgr refresh` + `fwupdmgr --json get-updates`) and applies it with `sudo fwupdmgr update`, never rebooting the machine on its own.
24
+ - ๐Ÿš€ **Distribution Release Upgrades**: At the end of every run, checks whether a newer OS release exists (Fedora n+1 via Bodhi, Ubuntu via `do-release-upgrade -c`, Debian via the stable suite) and offers to stage it โ€” reporting the exact command instead of applying it silently, and never rebooting for you.
25
+ - ๐Ÿ” **Interactive Sudo Acquisition**: When a selected manager requires elevation (`requiresSudo`), `hmd` verifies the cached ticket with `sudo -n true` and, if missing, prompts for the password exactly once through `sudo -v` on the controlling terminal before any spinner takes over the TTY. A background keep-alive refreshes the ticket during long upgrades, and every privileged step re-verifies non-interactive credentials so subprocesses can never hang on a hidden password prompt. Running `sudo hmd` is neither required nor supported (the CLI lives under the user's `PATH`, which root's `secure_path` does not include).
24
26
  - ๐ŸŽจ **Modern Minimalist UX**: Terminal interface powered by `@clack/prompts`, micro-border tabular layouts with directional version transitions (`current โ†’ latest`), persistent real-time step progression with elapsed durations, and actionable error extraction.
25
27
  - ๐Ÿท **Dynamic Version Resolution**: Reads package name and version dynamically from `package.json` at runtime via `import.meta.url`, ensuring banners and `--version` flags remain in sync with repository releases.
26
28
  - โš™ **Flexible Targeting**: Run interactively, execute non-interactively with `--yes`, or filter target managers using `--only` and `--exclude`.
@@ -29,7 +31,7 @@
29
31
 
30
32
  ## ๐Ÿ“ฆ Supported Package Managers
31
33
 
32
- Heimdall (`hmd`) supports 14 package managers across system, runtime, language, and application store categories:
34
+ Heimdall (`hmd`) supports 18 package managers across system, runtime, language, and application store categories:
33
35
 
34
36
  | Manager | Icon | Category | Detection Strategy | Update Routine & Resilience Rules |
35
37
  | :--- | :---: | :---: | :--- | :--- |
@@ -40,13 +42,46 @@ Heimdall (`hmd`) supports 14 package managers across system, runtime, language,
40
42
  | **[Yarn (global)](https://yarnpkg.com)** | ๐Ÿงถ | `runtime` | `yarn global list --depth=0` + native npm registry HTTP checks | 1. `yarn global add <pkg>@latest` (bypasses global semver lockouts)<br>2. `yarn global upgrade` |
41
43
  | **[Python (pip user)](https://pip.pypa.io)** | ๐Ÿ | `language` | `pip3 list --user --outdated --format=json` (targets user site-packages) | `pip3 install --user --upgrade <pkgs>` (complies with PEP 668 externally managed environment protections) |
42
44
  | **[pipx](https://pipx.pypa.io)** | ๐Ÿ“ฆ | `language` | `pipx list --json` + native PyPI JSON API lookups | `pipx upgrade-all` |
45
+ | **[uv](https://astral.sh/uv)** | ๐Ÿงช | `language` | `uv tool list` + native PyPI JSON API lookups | 1. `uv tool upgrade --all`<br>2. `uv tool install <pkg>@latest` for tools pinned to an older major (uv respects install-time constraints) |
46
+ | **[Poetry](https://python-poetry.org)** | ๐Ÿ“œ | `language` | `poetry --version` + native PyPI JSON API lookups | `poetry self update` |
47
+ | **[Conda](https://conda.io)** | ๐Ÿ…’ | `language` | `conda update --all --dry-run --json` (solver `LINK`/`UNLINK` actions paired by package name, 60s solver budget) | `conda update --all -y` |
43
48
  | **[Rust (Cargo & Rustup)](https://doc.rust-lang.org/cargo/)** | ๐Ÿฆ€ | `language` | `rustup check` (toolchains) + `cargo install-update -l` (crates) | 1. `rustup update` (if `rustup` exists)<br>2. `cargo install-update -a` (if `cargo-update` is installed) |
44
49
  | **[Ruby Gem](https://rubygems.org)** | ๐Ÿ’Ž | `language` | `gem outdated` (skips deprecated Apple System Ruby `/usr/bin/gem`) | 1. `gem update --user-install`<br>2. `gem cleanup` |
45
50
  | **[MacPorts](https://www.macports.org)** | โš“ | `system` | `port outdated` + non-interactive `sudo -n true` verification | 1. `sudo port selfupdate`<br>2. `sudo port upgrade outdated` |
46
51
  | **[Mac App Store (mas)](https://github.com/mas-cli/mas)** | ๐ŸŽ | `appstore` | `mas outdated` | `mas upgrade` |
47
- | **[APT (Debian/Ubuntu)](https://wiki.debian.org/Apt)** | ๐Ÿง | `system` | `apt list --upgradable` + non-interactive `sudo -n true` check | 1. `sudo apt-get update -y`<br>2. `sudo apt-get upgrade -y`<br>3. `sudo apt-get autoremove -y` |
52
+ | **[APT (Debian/Ubuntu)](https://wiki.debian.org/Apt)** | ๐Ÿง | `system` | `apt list --upgradable` + non-interactive `sudo -n true` check | 1. `sudo apt-get update -y`<br>2. `sudo apt-get upgrade -y --with-new-pkgs` (avoids leaving dependency-gaining upgrades `kept back`)<br>3. `sudo apt-get autoremove -y` (prompted interactively with confirmation prompt, auto-approved with `--yes` or `--dry-run`, skipped when declined or after a failed upgrade) |
48
53
  | **[DNF (Fedora/RHEL)](https://docs.fedoraproject.org/en-US/quick-docs/dnf/)** | ๐Ÿ“ฆ | `system` | `dnf check-update -y` (exit code 100 signals updates) + `sudo -n true` check | 1. `sudo dnf upgrade -y --refresh`<br>2. `sudo dnf autoremove -y` (prompted interactively with confirmation prompt, auto-approved with `--yes` or `--dry-run`) |
49
- | **[Flatpak](https://flatpak.org)** | ๐Ÿ“ฆ | `system` | `flatpak remote-ls --updates` | `flatpak update -y --noninteractive` |
54
+ | **[Flatpak](https://flatpak.org)** | ๐Ÿ“ฆ | `system` | `flatpak remote-ls --user --updates` + `flatpak remote-ls --system --updates` (both scopes, deduplicated) | 1. `flatpak update --user -y --noninteractive`<br>2. `sudo flatpak update --system -y --noninteractive` (marked `failed` with sudo guidance when system apps exist but privileges are unavailable, `skipped` when no system-scope apps are installed) |
55
+ | **[Firmware (fwupd)](https://fwupd.org)** | ๐Ÿ”ง | `system` | Linux only: `fwupdmgr refresh` (best-effort) + `fwupdmgr --json get-updates` + `sudo -n true` check | 1. `sudo fwupdmgr refresh --force`<br>2. `sudo fwupdmgr update -y --no-reboot-check --no-unreported-check --no-metadata-check` (installs every pending device update; never reboots by itself, so the machine reboots only when you decide to) |
56
+
57
+ ---
58
+
59
+ ## ๐Ÿš€ Distribution Release Upgrades
60
+
61
+ Package updates are not the only maintenance task: the operating system itself gets a new release. After the package summary (and also when everything was already up to date), `hmd` checks whether a newer distribution release exists, reports it, and asks before touching anything.
62
+
63
+ | Family | Detection | Upgrade Routine |
64
+ | :--- | :--- | :--- |
65
+ | **Fedora** | Bodhi `releases?state=current` (GA releases only; EPEL/ELN ignored) | `sudo dnf system-upgrade download --releasever=<next> -y` โ€” stages the offline transaction |
66
+ | **Ubuntu** | Authoritative `do-release-upgrade -c`; fallback to `changelogs.ubuntu.com/meta-release` | `sudo do-release-upgrade -f DistUpgradeViewNonInteractive` (when the upgrader is installed) |
67
+ | **Debian** | `deb.debian.org/debian/dists/stable/Release` vs. `VERSION_ID` | *Report only*: no unattended in-place path; guidance to switch suites then `sudo apt update && sudo apt full-upgrade` |
68
+
69
+ Safety rules:
70
+
71
+ - **Never reboots**: Fedora stages the packages and tells you to run `sudo dnf system-upgrade reboot`; Ubuntu reports its own restart requirement. You decide when to reboot.
72
+ - **`--yes` does not auto-apply it**: distribution upgrades are heavier than package updates, so an unattended run only reports the availability and the exact command. Use `-U`/`--upgrade-distro` to opt in explicitly.
73
+ - **`--dry-run`** prints the exact command that would run; **`--no-distro-upgrade`** disables the check entirely.
74
+ - Sudo is acquired once, just before applying, with a keep-alive for the (potentially hour-long) upgrade.
75
+
76
+ Example output:
77
+
78
+ ```text
79
+ โ—‡ Distribution upgrade available โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
80
+ โ”‚ Fedora Linux 45 is available (current: 44). โ”‚
81
+ โ”‚ Heimdall can stage/apply the upgrade; it never reboots. โ”‚
82
+ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
83
+ โ—‡ โ†ณ Reboot to apply it: sudo dnf system-upgrade reboot
84
+ ```
50
85
 
51
86
  ---
52
87
 
@@ -107,6 +142,8 @@ heimdall [options]
107
142
  | `-x` | `--exclude <mgrs>` | Comma-separated list of managers to exclude (e.g. `gem,macports`) | *None* |
108
143
  | `-t` | `--timeout <ms>` | Network/subprocess timeout per check phase in milliseconds | `25000` |
109
144
  | `-v` | `--verbose` | Output detailed diagnostic messages and skipped manager listings | `false` |
145
+ | โ€” | `--no-distro-upgrade` | Skip the distribution release upgrade check at the end of the run | `false` |
146
+ | `-U` | `--upgrade-distro` | Apply a detected distribution release upgrade without asking (never reboots) | `false` |
110
147
  | `-h` | `--help` | Display command help and option summary | โ€” |
111
148
  | `-V` | `--version` | Output CLI version (dynamically resolved from `package.json`) | Dynamic |
112
149
 
@@ -135,6 +172,12 @@ hmd --timeout 40000 --verbose
135
172
 
136
173
  # 7. Using the Canonical Alias
137
174
  heimdall --dry-run
175
+
176
+ # 8. Stage a distribution release upgrade without asking (never reboots)
177
+ hmd --upgrade-distro
178
+
179
+ # 9. Skip the distribution release upgrade check
180
+ hmd --no-distro-upgrade
138
181
  ```
139
182
 
140
183
  ---
@@ -157,8 +200,13 @@ Test coverage includes:
157
200
  - Concurrency pool bounds and error isolation in [`UpdaterEngine`](src/core/engine.ts).
158
201
  - `NpmManager` targeted batch installation, fallback trigger handling, and `--ignore-scripts` resilience.
159
202
  - `HomebrewManager` selective formula vs. cask execution branches.
160
- - Pre-check behaviors (skipping `/usr/bin/gem`, sudo privilege checks for MacPorts and APT).
161
- - HTTP registry lookup error handling for Yarn and pipx.
203
+ - Pre-check behaviors (skipping `/usr/bin/gem`, sudo privilege checks for MacPorts, APT and DNF, interactive sudo acquisition with ticket keep-alive).
204
+ - `FlatpakManager` dual-scope querying (user + system installations) and system-step sudo gating.
205
+ - `AptManager` upgradable parsing (epochs, architecture-qualified names, header/warning lines) and its consent-gated autoremove branch.
206
+ - `UvManager` tool-list parsing, cross-major reinstalls and PyPI lookups; `PoetryManager` version banner parsing; `CondaManager` dry-run `LINK`/`UNLINK` pairing.
207
+ - `FirmwareManager` fwupd JSON parsing (including the legacy non-zero "no updates" exit code), sudo fast-fail and reboot-safe update flags.
208
+ - `detectDistroUpgrade()`/`applyDistroUpgrade()`: os-release parsing, Fedora Bodhi, Ubuntu `do-release-upgrade -c` + meta-release fallback, Debian stable-suite detection, sudo fast-fail and no-reboot guarantees.
209
+ - HTTP registry lookup error handling for Yarn, pipx, uv and Poetry.
162
210
  - Formatting renderers (micro-border table, directional version diffs, execution summary metrics).
163
211
 
164
212
  ---