# TR-300
[](https://github.com/QubeTX/qube-machine-report/actions/workflows/ci.yml)
[](https://github.com/QubeTX/qube-machine-report/actions/workflows/release.yml)
[](LICENSE)
Cross-platform system information report with Unicode box-drawing tables.
TR-300 is a standalone Rust CLI for fast, reliable, and readable terminal machine reports.
Latest release: [v3.15.1](https://github.com/QubeTX/qube-machine-report/releases/tag/v3.15.1) (2026-05-15). Windows users get four installer options — Global / Corporate Editions, each in MSI and EXE formats — none of which require Rust on the install machine. macOS / Linux ship via cargo-dist's shell installer. The crates.io package is [`tr300`](https://crates.io/crates/tr300).
## Features
- Cross-platform support (Windows, macOS, Linux)
- Beautiful Unicode box-drawing tables with ASCII fallback
- ASCII fallback mode for legacy terminals
- Bar graphs for CPU load, memory, and disk usage
- VPN-aware network information on Windows — `MACHINE IP` and `DNS IP` rows reflect the active default route (`GetBestInterfaceEx`-driven) so Tailscale / WireGuard / OpenVPN / corporate VPN tunnels are reported correctly instead of a coin-flip pick
- Hypervisor / virtualization detection (CPUID-based; disambiguates Win11 VBS from real VMs)
- Session info with last-login/current-session tracking; Windows uses WTS APIs with a boot-time fallback
- Disk encryption status (BitLocker on Windows when readable)
- Fast Startup-aware uptime on Windows — when the kernel session age and the WMI cold-boot time diverge by >1h (typical on Win10/Win11 laptops with `HiberbootEnabled`), the `UPTIME` row renders both as `9d 4h 12m (session: 7h 14m)`
- 5-state battery awareness on Windows — distinguishes `AC Power` (plugged in, fully topped up), `X% (Charging)`, `X% (Plugged in)` (gaming-laptop case where peak GPU draw exceeds the brick wattage, OR firmware-limited charging modes like ThinkPad battery longevity), `X% (Discharging)`, plus `Critical` / `Low` overrides
- Smart terminal detection on Windows — env-var pre-checks (`WT_SESSION`, `TERM_PROGRAM`, `CURSOR_TRACE_ID`) then a parent-process walk via Toolhelp32 that recognizes Windows Terminal, WezTerm, Alacritty, VS Code, Cursor, Windsurf, Hyper, Tabby, Ghostty, Kitty, MinTTY, Claude Code, and Antigravity even when env vars are absent
- PowerShell 7+ ("PowerShell Core") detection on Windows — reads `HKLM\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\<GUID>\SemanticVersion` so `pwsh` users see the actual installed version instead of falling back to Windows PowerShell 5.x
- JSON output for scripting
- Auto-save markdown report to Downloads folder on manual runs
- Fast mode (`--fast`) for sub-second auto-run startup
- Positional action syntax (`tr300 update`, `tr300 install`, `tr300 uninstall`) with legacy flag compatibility
- Resilient self-update with cargo-first probing and shell/PowerShell installer fallbacks
- Conditional platform detail rows for machine model, CPU core topology, ZFS health, motherboard, BIOS, and RAM slots when the host exposes them
- Self-installation with shell alias and auto-run
## Installation
TR-300 ships **prebuilt binaries** — no Rust toolchain required to install or
run. Pick the installer that matches your operating system and (on Windows)
whether you have admin rights on the machine.
### Windows — Global Edition (recommended for personal machines)
Installs to `C:\Program Files\tr300\bin\tr300.exe` and adds it to **system PATH**
so every terminal on the machine can find it. **Requires admin (UAC prompt).**
Two equivalent download options — **pick one**, not both. Both install to the
same location; installing both creates duplicate Add/Remove Programs entries.
| MSI | [tr300-x86_64-pc-windows-msvc.msi](https://github.com/QubeTX/qube-machine-report/releases/latest/download/tr300-x86_64-pc-windows-msvc.msi) | IT-managed deployment (Intune, SCCM, Group Policy) and most personal installs. The default. |
| EXE | [tr300-x86_64-pc-windows-msvc-setup.exe](https://github.com/QubeTX/qube-machine-report/releases/latest/download/tr300-x86_64-pc-windows-msvc-setup.exe) | If you prefer a familiar `setup.exe`. Same outcome as the MSI. |
After install, open a new terminal and run `tr300`. The binary is unsigned, so
SmartScreen will show **"Windows protected your PC"** the first time —
click **More info → Run anyway**. (Code signing is on the roadmap;
see [Releases](https://github.com/QubeTX/qube-machine-report/releases) for
status.)
### Windows — Corporate Edition (recommended for locked-down work machines)
Installs to `%LocalAppData%\Programs\tr300\bin\tr300.exe` and adds it to your
**user PATH** only — no admin, no UAC, no system-wide changes. Use this on
machines managed by Intune / Active Directory / Group Policy when you don't
have admin rights but still need to install software.
| MSI | [tr300-x86_64-pc-windows-msvc-corporate.msi](https://github.com/QubeTX/qube-machine-report/releases/latest/download/tr300-x86_64-pc-windows-msvc-corporate.msi) | IT can push this via Intune assignment; works under AppLocker / managed-installer policy when allowlisted. |
| EXE | [tr300-x86_64-pc-windows-msvc-corporate-setup.exe](https://github.com/QubeTX/qube-machine-report/releases/latest/download/tr300-x86_64-pc-windows-msvc-corporate-setup.exe) | Familiar `setup.exe` for end users on restricted machines. |
Same "pick ONE format" rule as the Global Edition. If WDAC / AppLocker blocks
both, your only options are the bare-EXE path below or asking IT to allowlist
one of these installers.
### Choosing between Global and Corporate Edition
| Your own laptop / desktop, you have admin | **Global** |
| A work machine where you have admin | **Global** |
| A work machine where you don't have admin but can install apps to your user profile | **Corporate** |
| A locked-down machine that blocks `C:\Program Files` writes | **Corporate** |
| A server, ARM Windows, or anything else | Use the bare EXE / shell installer below |
If you accidentally install both editions, they coexist (different
Add/Remove Programs entries) but PATH ordering picks which one wins. Uninstall
one before installing the other for a clean state.
### macOS / Linux
```bash
Installs to `~/.cargo/bin/tr300` and modifies your shell's PATH. **Does not
require Rust** — downloads the prebuilt binary from the GitHub Release.
### Alternative install methods
<details>
<summary>Windows PowerShell one-liner (downloads the prebuilt binary, no Rust)</summary>
```powershell
Installs to `%USERPROFILE%\.cargo\bin\tr300.exe` (the directory is created
automatically — Rust is not required). Modifies user PATH only. Fails if
PowerShell `ExecutionPolicy` is `Restricted` and not overridden; the MSI /
EXE installers above don't have that limitation.
</details>
<details>
<summary>Windows — bare EXE (no installer, no PATH modification)</summary>
Download [tr300-x86_64-pc-windows-msvc.zip](https://github.com/QubeTX/qube-machine-report/releases/latest/download/tr300-x86_64-pc-windows-msvc.zip),
extract `tr300.exe`, place it anywhere you can write to (your Desktop, a
USB stick, `C:\bin`, etc.). Run by typing the full path or by adding the
containing directory to your PATH manually. Useful for portable use, USB
sticks, and scenarios where any installer is blocked.
</details>
<details>
<summary>Build from source — for developers / contributors</summary>
Requires Rust **1.95.0 or later** (`rustup update stable` if needed).
Most users should NOT use these paths — they download and compile the
source instead of using the prebuilt binary, which is slower and requires
the Rust toolchain.
**From crates.io:**
```bash
cargo install tr300
```
**From a specific Git tag:**
```bash
rustup update stable
cargo install --git https://github.com/QubeTX/qube-machine-report.git --tag v3.15.1
```
**Local clone for development:**
```bash
git clone https://github.com/QubeTX/qube-machine-report.git
cd qube-machine-report
cargo build --release
```
</details>
## Usage
```bash
# Display system report (default)
tr300
# Use ASCII characters instead of Unicode
tr300 --ascii
# Output as JSON
tr300 --json
# Custom title
tr300 --title "MY SERVER"
# Disable colors
tr300 --no-color
# Self-update to the latest release
tr300 update
# Legacy form still works:
tr300 --update
# Install to shell profile (adds 'report' alias + auto-run)
tr300 install
# Legacy form still works:
tr300 --install
# Remove from shell profile
tr300 uninstall
# Legacy form still works:
tr300 --uninstall
# Show help
tr300 --help
```
## Example Output
```
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
├┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┤
│ QUBETX DEVELOPER TOOLS │
│ TR-300 MACHINE REPORT │
├──────────────┬────────────────────────────────────┤
│ OS │ Windows 11 24H2 │
│ KERNEL │ Windows 10.0.26200 │
├──────────────┼────────────────────────────────────┤
│ HOSTNAME │ DESKTOP-ABC123 │
│ MACHINE IP │ 192.168.1.100 │
│ CLIENT IP │ Not connected │
│ DNS IP 1 │ 192.168.1.1 │
│ USER │ emmett │
├──────────────┼────────────────────────────────────┤
│ PROCESSOR │ Intel Core Ultra 7 155H │
│ CORES │ 22 vCPU(s) / 1 Socket(s) │
│ HYPERVISOR │ Bare Metal │
│ CPU FREQ │ 1.4 GHz │
│ LOAD 1m │ ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ LOAD 5m │ █████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ LOAD 15m │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
├──────────────┼────────────────────────────────────┤
│ VOLUME │ 848.18/935.54 GB [90.66%] │
│ DISK USAGE │ █████████████████████████████░░░░░ │
├──────────────┼────────────────────────────────────┤
│ MEMORY │ 18.00/31.52 GiB [57.1%] │
│ USAGE │ ██████████████████░░░░░░░░░░░░░░░░ │
├──────────────┼────────────────────────────────────┤
│ LAST LOGIN │ Login tracking unavailable │
│ UPTIME │ 5h 38m │
├──────────────┴────────────────────────────────────┤
└──────────────┴────────────────────────────────────┘
```
## Command Line Options
Positional actions can be written without a double dash. They are mutually
exclusive with each other and with the legacy action flags.
| `update` | Check for updates and install the latest version |
| `install` | Add to shell profile with alias and auto-run |
| `uninstall` | Remove from shell profile |
| `--ascii` | Use ASCII characters instead of Unicode |
| `--json` | Output in JSON format |
| `-t, --title <TITLE>` | Custom title for the report header |
| `--no-color` | Disable colored output |
| `--fast` | Fast mode: skip slow collectors for quick auto-run |
| `--no-elevation-hint` | Suppress the "Run with sudo / Administrator" footer hint |
| `--update` | Legacy flag form of `tr300 update` |
| `--install` | Add to shell profile with alias and auto-run |
| `--uninstall` | Remove from shell profile |
| `-h, --help` | Print help information |
| `-V, --version` | Print version information |
## Self-Update
Both action forms update to the latest release:
```bash
tr300 update
tr300 --update
```
`tr300 update` detects how this binary was installed and downloads the matching
installer for an **in-place upgrade** — no manual download required.
**On Windows (v3.15.0+):**
| Global MSI | Downloads the new Global MSI, runs `msiexec /i` | Yes |
| Corporate MSI | Downloads the new Corporate MSI, runs `msiexec /i` | No |
| Global EXE | Downloads the new Global EXE installer, runs `/SILENT` | Yes |
| Corporate EXE | Downloads the new Corporate EXE installer, runs `/SILENT` | No |
| `cargo install` / PowerShell installer | Falls through to the legacy chain (cargo first, then `irm \| iex` PowerShell installer) | No |
Detection uses a `HKCU\Software\TR300\InstallSource` registry marker that the
four first-class installers write at install time. If the marker is missing
(legacy install from before v3.15.0), the updater falls back to inspecting the
running binary's path: `C:\Program Files\tr300\` → MSI Global, `%LocalAppData%
\Programs\tr300\` → MSI Corporate, `~\.cargo\bin\` → legacy chain.
**Security (v3.15.2+):** every downloaded MSI / EXE installer is checked against
its published `.sha256` sidecar before launching. A network MITM (corporate
TLS-inspection proxy with trusted root CA, hostile public WiFi, captive
portal) that swaps the installer bytes is now caught and refused with a
clear error.
**Post-install verification (v3.15.2+):** after the installer reports success,
`tr300 update` re-execs the on-disk binary's `--version` and confirms the
upgrade actually took effect. If Windows Installer's Restart Manager
scheduled a delete-on-reboot (msiexec exit code 3010) rather than replacing
the locked binary in-place, the JSON `attempts[].message` contains an
actionable "Reboot, then verify with `tr300 --version`" rather than a
false-positive success.
**On macOS / Linux:**
1. Checks the latest release on GitHub. If you're already current, exits 0
without changing anything.
2. Tries `cargo install tr300 --force` first when `cargo --version` succeeds.
If `rustup` is present, it runs `rustup update stable` best-effort first so
cargo installs against the current MSRV.
3. Falls through to the cargo-dist shell installer: `curl | sh` then `wget | sh`.
**Manual fallback (any platform):** if `tr300 update` fails, you can always
re-download the installer for your platform from the
[Releases page](https://github.com/QubeTX/qube-machine-report/releases) and
re-run it — WiX `MajorUpgrade` (MSI) and Inno Setup's AppId-based upgrade
detection (EXE) handle in-place upgrades cleanly.
In `--json` mode, every response includes a top-level `install_origin` field
on Windows (`msi-global` / `msi-corporate` / `exe-global` / `exe-corporate` /
`cargo-or-installer` / `unknown`). Successful updates include the legacy
`"method"` field plus a precise `"strategy"` value (`msi_global`,
`msi_corporate`, `exe_global`, `exe_corporate`, or the legacy installer IDs).
Failed updates include an `"attempts"` array with each strategy result and
diagnostic message.
## Release Automation
GitHub Actions handles both release assets and crates.io publishing:
- `CI` runs formatting, clippy, tests, release builds, speed checks, audit, and
cargo-dist planning on pushes to the default branch.
- `Crates.io Publish` runs only after `CI` succeeds for that default-branch
commit, checks whether the manifest version is already on crates.io with a
descriptive data-access `User-Agent`, reruns fmt/clippy/tests/package/dry-run
with `--locked`, and publishes `tr300` only when the repository
`CARGO_REGISTRY_TOKEN` Actions secret is configured.
- `Release` is the cargo-dist workflow triggered by an explicit version tag such
as `v3.14.3`; it builds the cross-platform archives and installers. New
installer assets use `tr300-installer.*`; the workflow also publishes
`tr-300-installer.*` compatibility aliases so v3.14.2 binaries can
self-update after the old package name was removed. The cargo-dist config
permits that checked-in workflow customization with `allow-dirty = ["ci"]`.
`Cargo.lock` is tracked so the crates.io publish workflow uses the same resolved
dependency set that local release verification used.
## Elevation Tier
TR-300 detects whether it is running with elevated privileges (root on Unix /
Administrator on Windows) and surfaces additional data when it is.
- **Default (unelevated)** — the report renders exactly as it always has, with one
small addition on Linux and Windows: a single dim line below the table noting that
running with sudo / Administrator would unlock more details (motherboard / BIOS /
RAM slots on Linux; BitLocker status on Windows). This hint is **never** shown
during `--fast` auto-run, so the prompt-ready experience is unchanged.
- **Elevated** — extra rows render inline (motherboard, BIOS, RAM slot summary on
Linux when `dmidecode` is available; BitLocker status when readable on Windows).
- **macOS** — no elevation tier; everything TR-300 needs is accessible without sudo.
To opt out of the hint, run `tr300 --no-elevation-hint` (or wire the flag into your
shell alias). The hint is rendered with ANSI dim, so respects `--no-color` as well.
The JSON output exposes this state under top-level keys `elevated` and
`elevation_unlocks_more` for scripted consumers.
## Installation to Shell Profile
Running `tr300 install` or `tr300 --install` will:
1. **Remove existing TR-300 configuration** (if present)
2. Add a `report` alias so you can type `report` instead of `tr300`
3. Configure auto-run on new interactive shell sessions
This means you can safely run `tr300 install` multiple times without duplicating profile blocks.
**Safety (v3.15.2+):** every modification to your rc files / `$PROFILE`
is written via a temp-then-atomic-rename. A Ctrl-C, power loss, or
antivirus quarantine mid-write can no longer leave your profile
truncated. The first install also writes a one-time `.tr300-backup`
copy of your original profile so you have a recovery option. If the
TR-300 marker block in your profile has been hand-edited into an
unbalanced state (e.g. `# End TR-300` line accidentally removed),
`tr300 install` refuses up-front with an actionable error rather
than silently dropping the rest of your profile.
**Auto-run guards (v3.15.2+):** the injected snippet now guards
the `tr300 --fast` call with `command -v tr300` (POSIX) /
`Get-Command tr300 -ErrorAction SilentlyContinue` (Windows), so a
missing binary no longer prints an error at every new shell start.
A `TR300_AUTORUN_RAN` sentinel prevents recursion in nested shells
(vim `:term`, `bash -i -c …`, Windows Terminal nested tabs). On
Windows, the snippet uses `[Environment]::UserInteractive` instead
of the older `$Host.Name -eq 'ConsoleHost'` check, so scripted
`pwsh -Command "..."` invocations from CI / VS Code / scheduled
tasks no longer dump the table into log streams.
**On Unix/macOS:** Modifies `~/.bashrc` and/or `~/.zshrc`. On a
fresh-account macOS machine where neither file exists, `tr300
install` creates `.zshrc` (macOS has defaulted to zsh since 10.15,
Catalina, 2019). `sudo tr300 install` is refused — TR-300 modifies
your personal shell profile, and running as root either targets
root's profile (no benefit to your shell) or leaves root-owned
files in your home that break subsequent non-sudo installs.
**On Windows:** Modifies the PowerShell `$PROFILE`. When both
Windows PowerShell 5.1 (`powershell`) and PowerShell 7 (`pwsh`)
are installed, `tr300 install` writes to BOTH profile paths
(`Documents\WindowsPowerShell\…` and `Documents\PowerShell\…`)
since the two shell flavors don't cross-source each other.
Pre-v3.15.2, pwsh-only users got a silent no-op install because
the snippet went to a profile their actual shell never read.
Fresh Windows machines default `ExecutionPolicy` to `Restricted`,
which blocks every `.ps1` including the profile itself, so
`tr300 install` runs a preflight that adjusts the `CurrentUser`
scope to `RemoteSigned` when needed. `RemoteSigned` is the minimum
policy that lets the local profile load — it still requires
downloaded `.ps1` files to be Authenticode-signed. The change is
HKCU-only, affects only your user account, and does not require
admin. If you have deliberately set `AllSigned`, `tr300 install`
will not silently downgrade it; it prints a notice explaining the
auto-run will not fire and leaves the policy alone.
See [Microsoft Learn — about_Execution_Policies](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies).
To remove these additions, run `tr300 uninstall` or `tr300 --uninstall`.
The uninstall does not roll back your execution policy — other PowerShell
tooling typically relies on `RemoteSigned`, so restoring it would surprise
users.
**`uninstall` → Complete** on Windows handles the self-EXE delete case
(v3.15.2+). When you run `tr300 uninstall` from a Windows install
location (e.g. `%LocalAppData%\Programs\tr300\bin\tr300.exe`) and
choose "Complete", the OS would normally refuse to delete the
running binary. TR-300 detects this and schedules a detached
background job that waits 2 seconds for our process to exit, then
removes the binary and its empty parent folder. You'll see
"Scheduled deferred cleanup of: …" and your shell returns to a
prompt; the file is gone within a couple seconds.
If `tr300 install` (or `uninstall`) hits a permissions error on Windows —
common on work machines managed by Intune, Group Policy, AppLocker, or
WDAC, and on personal machines where Documents is redirected to OneDrive
— the tool prints a multi-paragraph explanation of what likely caused the
failure (OneDrive offline / online-only files, an MDM lockdown, antivirus
blocking the profile edit, a sharing violation, a disk-full condition, or
a MAX_PATH overflow) along with concrete next steps: which path to ask IT
to allowlist, where to add an antivirus exclusion, or how to `takeown`
ownership. Manual `tr300` invocations from the prompt always continue to
work in this case; only the auto-run on new shells is affected, and you
can re-run `tr300 install` once the underlying restriction is addressed.
## Building from Source
Requirements:
- Rust 1.95.0 or later (`rustup update stable`)
- Cargo
```bash
# Debug build
cargo build
# Release build
cargo build --release
# Run tests
cargo test --workspace --all-targets
# Run clippy
cargo clippy --all-targets --workspace -- -D warnings
# Check formatting
cargo fmt --all -- --check
# Run with arguments
cargo run -- --ascii
```
### Man Page (Linux/macOS)
A man page is auto-generated during build via `clap_mangen`. After building from source:
```bash
sudo cp man/tr300.1 /usr/local/share/man/man1/
man tr300
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the PolyForm Noncommercial License 1.0.0 - see the [LICENSE](LICENSE) file for details. This license permits noncommercial use, personal use, and use by charitable organizations, educational institutions, and government agencies.