制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗BatteryPill is a Windows desktop battery widget built with PowerShell and WinForms. It displays a floating, draggable pill-shaped indicator on the desktop showing time remaining, a detailed information popup on hover (the tray icon opens a modal version on click), and a system tray icon. It is designed for Windows users who want a persistent, glanceable view of their battery status using smoothed estimates rather than just a percentage.
One command takes a fresh clone to a running widget:
./scripts/setup.sh
It checks prerequisites, installs the ps2exe dependency (bootstrapping TLS 1.2 and the NuGet provider that stock PowerShell 5.1 lacks), builds BatteryPill-<version>.exe, and launches it. It is idempotent — re-run it any time. Use ./scripts/setup.sh --no-run to build without launching, and --help for usage.
The only prerequisites are Windows, Windows PowerShell 5.1 (powershell.exe on PATH), and a bash shell (Git Bash works). Everything else is installed for you.
Quit from the tray icon's Exit item. To start it again afterwards, run the compiled executable (the version suffix comes from $script:appVersion in the source; end users grab the stable-named BatteryPill.exe from the latest release instead):
.\BatteryPill-<version>.exe
The release exe is unsigned, so SmartScreen warns on first run and some AV engines flag PS2EXE output — see DISTRIBUTION.md for what users hit and the signing/rewrite decision record.
To run the widget from source without building (assembles the src/ modules to a staging file and runs it):
powershell -ExecutionPolicy Bypass -File .\BatteryWidget.Run.ps1
To rebuild the executable on its own:
.\Build.ps1
Quick battery status check via CLI:
CheckBattery.bat
or
.\CheckBattery.ps1
scripts/verify.sh is the single gate for this repo: it runs lint, the full test suite, and a real build, and exits nonzero if any stage fails. Run it before committing.
./scripts/verify.sh
It runs (cheapest signal first, each with a wall-clock timeout so the whole run stays well under 10 minutes):
tools/check-source.ps1: verifies every src/*.ps1 module still carries its UTF-8 BOM, parse-checks each module plus the assembled whole and every shipped .ps1, runs PSScriptAnalyzer (settings in PSScriptAnalyzerSettings.psd1), checks that every .ps1 is autoformatted, and runs the type gate (tools/check-types.ps1, below). The gate fails on any warning, so the build log stays warning-free — write new non-ASCII display characters as [char]0xNNNN rather than literals.scripts/run-tests.ps1: runs every tests/*.Tests.ps1, each in its own powershell.exe.Build.ps1: assembles src/*.ps1 and compiles the result to BatteryPill-<version>.exe with ps2exe.Requires Windows PowerShell 5.1 (powershell.exe on PATH) and a bash shell (Git Bash works). Typical runtime on a dev machine is a few seconds.
To run just the tests, or one file:
.\scripts\run-tests.ps1
.\scripts\run-tests.ps1 -Filter Formatting
Tests dot-source individual functions out of the assembled widget source via the PowerShell AST (Import-WidgetFunction in tests/_harness.ps1) — the script itself ends in a WinForms message loop, so it can never be dot-sourced whole.
House style is enforced by an autoformatter, so layout is never a review topic. If the lint stage reports unformatted files, fix them mechanically:
.\tools\format-source.ps1 # rewrite every .ps1 in place
.\tools\format-source.ps1 -Check # what verify.sh runs; exits 1 if anything is unformatted
It wraps PSScriptAnalyzer's Invoke-Formatter (K&R braces, 4-space indent, aligned hashtable assignments), preserves each file's UTF-8 BOM and line endings, and refuses to write a file whose token stream changed — a reformat can only move whitespace.
PowerShell has no compiler, so signatures are held to a written standard instead:
.\tools\check-types.ps1 # also run by the lint stage; exits 1 on any violation
It reads every .ps1 with the AST and enforces four rules repo-wide, with no per-file allowlist:
param() block, carries an explicit type constraint.[OutputType(...)]; functions that emit nothing declare [OutputType([void])].[object] — rule 1 cannot be satisfied by typing everything [object]. A genuinely polymorphic parameter needs an # any-typed: ... comment on its own line or the line above, saying what it holds.[void] — a function declaring [OutputType([void])] must not return a value from its own body (returns inside nested functions and event-handler scriptblocks belong to those and are ignored). This is what keeps declared return types from drifting as the code changes.Releases are one command. Bump $script:appVersion in src/010-init.ps1, commit, then:
.\release.ps1
It refuses to run on a dirty tree or an already-released version, runs the full scripts/verify.sh gate, builds via Build.ps1, tags v<version>, pushes the tag, and creates the GitHub release with two assets: the versioned BatteryPill-<version>.exe and a stable-named BatteryPill.exe. The website's download button points at .../releases/latest/download/BatteryPill.exe, so it always serves the newest release without any site edit. Requires git, gh (authenticated), and bash on PATH.
BatteryWidget.config.json on drag and exit.Win32_Battery) and .NET APIs (System.Windows.Forms.SystemInformation).R_EMA_t = α × R_raw_t + (1 - α) × R_EMA_(t-1)) with α=0.15 to stabilize discharge/charge rates.SetProcessDPIAware() to ensure consistent scaling across different monitor setups.src/: The widget source, split into ordered modules (010-init.ps1 … 140-main.ps1) that concatenate byte-exactly into the shipped script (tools/_assemble.ps1).BatteryWidget.Run.ps1: Runs the widget straight from src/ without building.Build.ps1: Script that assembles src/ and compiles it into a standalone .exe using ps2exe.release.ps1: One-command GitHub release (verify, build, tag, upload assets).CheckBattery.ps1 / .bat: Standalone CLI scripts for battery status.DISTRIBUTION.md: SmartScreen/AV expectations for the unsigned exe and the signing/rewrite decision record.scripts/: setup.sh (one-command setup), verify.sh (the lint + tests + build gate), and run-tests.ps1 (test runner).tests/: Test suite - _harness.ps1 (assertions + AST function loader) plus *.Tests.ps1 files.tools/: Dev harness - check-source.ps1 (BOM + parse + PSScriptAnalyzer + formatting + typing gate), format-source.ps1 (autoformatter), check-types.ps1 (type gate), and render-states.ps1 (headless renderer of popup/pill/settings states)..github/workflows/: CI - verify.yml runs scripts/verify.sh on windows-latest for every push and PR.docs/: Website files for the project landing page.history/: Archived mission records and evidence from past improvement loops (historical reference only).