feat(status-bar): add /battery toggle for a color-coded battery read-out - #68860
Merged
Conversation
Add an opt-in battery indicator to the CLI and TUI status bars, shown as the first element and colour-coded by charge (green/yellow/orange/red, or green while charging). Off by default and a no-op on machines without a battery. - agent/battery.py: shared psutil-backed reader with a short TTL cache, category bucketing, and a compact 🔋/⚡ label. Fails open to "unavailable" everywhere. - CLI: /battery [on|off|status] toggle persisted to display.battery, rendered first in every status-bar width tier. - TUI: /battery slash command, config sync, a system.battery RPC polled while enabled, and a pinned first segment in StatusRule.
Contributor
૮ >ﻌ< ა ci reviewrunning on 3c2903a looks good to me! |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an opt-in, color-coded battery indicator to Hermes’ CLI and TUI status bars, backed by a shared psutil reader and surfaced via a new /battery toggle plus a TUI JSON-RPC endpoint.
Changes:
- Introduces
agent/battery.pyto read/cache battery state and derive a color category + compact label. - Wires the battery segment into the CLI status bar (text + fragments) and adds
/battery [on|off|status]with persistence viadisplay.battery. - Adds TUI support via
system.battery, a polling hook, status-bar rendering updates, and accompanying Python/TS tests + docs.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
agent/battery.py |
New shared battery reader/category/formatter with short TTL caching. |
cli.py |
Adds /battery handler, persists display.battery, and prepends battery segment in status bar rendering. |
hermes_cli/commands.py |
Registers the new CLI-only /battery slash command. |
hermes_cli/config.py |
Adds display.battery default config key (off by default). |
tui_gateway/server.py |
Adds system.battery RPC and supports config.set for battery persistence. |
tests/agent/test_battery.py |
Unit tests for battery reading/clamping/caching, category thresholds, and formatting. |
tests/test_tui_gateway_server.py |
Tests system.battery fail-open behavior and config.set battery persistence. |
ui-tui/src/gatewayTypes.ts |
Adds display.battery typing and SystemBatteryResponse RPC type. |
ui-tui/src/app/interfaces.ts |
Introduces BatteryInfo / BatteryCategory and stores them in UiState. |
ui-tui/src/app/uiStore.ts |
Initializes battery UI state (battery, batteryStatus). |
ui-tui/src/app/useConfigSync.ts |
Syncs display.battery from gateway config into UI state. |
ui-tui/src/app/useBatteryPoll.ts |
New polling hook + coercion helper for system.battery payloads. |
ui-tui/src/app/useMainApp.ts |
Enables the battery poller alongside other config-driven hooks. |
ui-tui/src/app/slash/commands/core.ts |
Adds TUI /battery command to toggle the indicator and persist via config.set. |
ui-tui/src/components/appLayout.tsx |
Plumbs battery state into StatusRule. |
ui-tui/src/components/appChrome.tsx |
Renders a pinned first battery segment with category-based coloring. |
ui-tui/src/__tests__/useBatteryPoll.test.ts |
Tests payload coercion/clamping and category normalization. |
ui-tui/src/__tests__/appChromeStatusRule.test.tsx |
Verifies StatusRule battery segment rendering/coloring/omission behavior. |
website/docs/reference/slash-commands.md |
Documents /battery and marks it CLI-only in the notes section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- TUI /battery matches the CLI surface: adds `status` (live reading via system.battery), and the help/usage strings now consistently read [on|off|status]. - batteryLabel() renders `--` for an unknown percent so a null can never surface as "null%" even without the showBattery guard. - Move the system.battery RPC out of the config section into "Methods: tools & system" where system.* RPCs belong.
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
…atus feat(status-bar): add /battery toggle for a color-coded battery read-out
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in battery indicator to the CLI and TUI status bars, rendered as the first element and color-coded by charge — the way many shell prompts show it. Off by default; a no-op on machines without a battery (desktops/servers/VMs).
⚡ 82%while charging,🔋 82%on battery.What's in it
agent/battery.py— a small shared,psutil-backed reader (psutilis already a dependency). Memoises the reading for a few seconds so the status bar can poll it on every repaint cheaply, buckets the level into a color category, and formats a compact label. Every failure path degrades to "unavailable" and simply renders nothing./battery [on|off|status]toggles the read-out and persists todisplay.battery(survives restarts). Prepended ahead of the⚕marker in every status-bar width tier (both the fragment and plain-text renderers)./batteryslash command,display.batteryconfig sync, asystem.batteryJSON-RPC method that returns the reading, a poller that runs only while the indicator is enabled, and a pinned first segment inStatusRule(width-budgeted so it never crushes model/context).website/docs/reference/slash-commands.md.Footprint
No new core model tool and no new
.envvar — this is a display setting inconfig.yaml(display.battery, defaultfalse) toggled by a CLI-only slash command, consistent with/statusbar,show_cost, etc.Test plan
tests/agent/test_battery.py— reader (no psutil / no battery / clamp / cache) + category thresholds + label/glyph.tests/test_tui_gateway_server.py—system.battery(reading + fail-open) andconfig.set battery(toggle + explicit off).ui-tuivitest —StatusRulebattery rendering/coloring/omission +toBatteryInfocoercion.npm run typecheck+eslintclean on changed TUI files./battery onon a laptop (charging + on battery), and confirm it's a no-op on a desktop.