feat(perf): always-visible main-process heap + rss badge in header#76
Merged
Conversation
Adds a 1 Hz live readout of the Electron main-process v8 heap and RSS to the header strip, gated on CC_SHELL_PERF=1. Renders null when the flag is off, so default users see no change. The badge shows: - heap used / heap cap with color zones (green <60%, yellow 60–80%, red >80% of v8.heap_size_limit) - a 60-second sparkline of heap-used ratio (matches the zone color) - RSS in muted text Click expands to a PerformancePanel-sized popover (430px, same border/shadow/positioning) with: - current heap / RSS / external / arrayBuffers values - peak heap + RSS over the buffered 10-minute window - 60s growth rate for each metric (positive growth highlighted) - overlaid SVG line chart of heap-used (green) + RSS (sky) with a dashed red heap-cap reference line Motivation: today's OOM crashed at ~2.69 GiB / 2.78 GiB cap with GC freeing 0 MB twice and a node::Buffer::New frame in the stack. With the badge in red 30+ minutes earlier, the user would have had a visible warning instead of a sudden kill. PR #48's heap-watchdog already dumps a forensic snapshot at the same 80% threshold; this PR is the user-facing counterpart so they can SEE growth before the snapshot fires. Implementation: - New SystemPerformanceStats type in shared/performance/types.ts - New IPC handler performance:system-stats in main/ipc/performance.ts (returns process.memoryUsage + v8.getHeapStatistics on every call) - New preload API getSystemPerformanceStats - New feature dir src/renderer/src/features/system-perf/ with: - useSystemPerfPoller hook (probe-then-poll, ring buffer of 600 samples, fail-silent if IPC throws) - SystemPerfBadge (header strip with inline sparkline) - SystemPerfPopover (mirrors PerformancePanel chrome) - SystemPerfHeader (orchestrator, owns local open state) - App.tsx mounts <SystemPerfHeader /> next to the existing perf toggle in the title bar No new test scripts, no changes to existing perf telemetry pipeline, no new persisted state, no command-palette entry (YAGNI — single click on the badge is the only entry point users need). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 a 1 Hz live readout of the Electron main-process v8 heap and RSS to the header strip, gated on `CC_SHELL_PERF=1`. Renders null when the flag is off, so default users see no change.
Motivated by today's OOM that crashed at ~2.69 GiB / 2.78 GiB cap with two back-to-back Mark-Compact GCs freeing 0 MB each — i.e. fully-retained heap, not a classic leak. With this badge sitting in red 30+ minutes earlier, you'd have had a visible warning instead of a sudden kill. PR #48's heap-watchdog already dumps a forensic snapshot at the same 80% threshold; this PR is the user-facing counterpart so growth is visible BEFORE the snapshot fires.
What you see
Badge in header (always visible when CC_SHELL_PERF=1):
```
heap 2.10 GB / 4.00 GB ▁▂▃▄▅▆▇ rss 3.2 GB
```
Click expands to popover (same 430px / border / shadow / position as the existing PerformancePanel):
Implementation
What this is NOT
Test plan
🤖 Generated with Claude Code