Skip to content

alanfeng99/cyberpunk-performance-monitor

Repository files navigation

Cyberpunk Performance Monitor

A cyberpunk-styled macOS menu bar monitor for CPU, memory, disk, and Claude process usage.

The repository is named cyberpunk-performance-monitor, while the built app bundle is still named Performance Monitor.

macOS 14+ Swift 5.9 License

Screenshots

Widget

System Monitor widget
Menu bar popover

System Monitor menu bar popover

Why This Exists

Most system monitors are either too heavyweight for quick menu bar checks, too generic to explain what Claude is doing, or disconnected from macOS widgets.

This project is intentionally narrow:

  • It is menu bar first, so you can check system pressure without opening a full dashboard.
  • It is Claude-aware, so you can quickly tell whether CPU or memory pressure is coming from Claude-related process groups.
  • It is local only, using native macOS APIs instead of background agents or remote services.
  • It is widget-friendly, so the desktop widget can act as a quick entry point back into the menu bar HUD.

Features

  • Menu bar HUD: A translucent popover with circular gauges and usage bars for CPU, memory, and disk.
  • 2-second live refresh: The menu bar app refreshes system stats every 2 seconds while it is running.
  • Process list: Running regular apps are searchable and sorted by memory usage.
  • Process controls: Each process row exposes Quit and Force Quit in a context menu.
  • Claude monitoring: Aggregates CPU and RSS memory usage for Claude CLI and Claude desktop related process groups.
  • Stale Claude detection: Flags runaway Claude process groups when a single process group exceeds 15 Claude processes.
  • Release Memory: Kills stale Claude process groups, then asks the kernel to purge reclaimable memory.
  • Widget support: Includes small and medium desktop widgets for CPU, memory, and disk at a glance.
  • Widget deep link: Clicking the widget opens the menu bar popover through perfmonitor://show.
  • Launch at Login: Can be toggled from the gear menu.
  • Optional disk cleanup shortcut: The CLEAN UP DISK button tries to open /Applications/DiskCleanupTool.app if it exists.

Architecture

Core monitoring uses native Darwin and AppKit APIs. It does not shell out to external tools for CPU, memory, disk, or Claude process inspection.

PerformanceMonitor/
├── App/                    # NSStatusItem app delegate and widget URL handler
├── Services/
│   ├── MemoryPurgeService  # Stale Claude cleanup + vm_purgable_control
│   └── ProcessManager      # Claude process discovery, grouping, and termination
├── ViewModels/
│   └── MonitorViewModel    # 2s app refresh + 30s widget push
└── Views/                  # Popover UI, overview cards, process list

PerformanceMonitorWidget/   # WidgetKit extension and widget views
Shared/
├── Extensions/             # Theme and formatting helpers
├── Models/                 # SystemStats and AppProcessInfo
└── Services/               # CPU, memory, disk, and shared stats store

Technical Notes

  • CPU monitoring: Uses host_statistics(..., HOST_CPU_LOAD_INFO, ...) and computes a delta between samples.
  • Memory monitoring: Uses host_statistics64(..., HOST_VM_INFO64, ...) and reports active + wired + compressed memory.
  • Disk monitoring: Reads filesystem attributes from NSHomeDirectory() via FileManager.
  • Claude process detection: Uses proc_listallpids, proc_pidinfo, and proc_pidpath to find Claude-related process groups.
  • Stale cleanup threshold: Any single process group with more than 15 Claude processes is treated as stale.
  • Widget data sharing: The app and widget share latestStats.json through the app group group.com.alanfeng.performance-monitor.
  • Widget freshness model:
    • When the menu bar app is running, it pushes fresh stats to the shared store every 30 seconds and reloads widget timelines.
    • When the app is not running, the widget falls back to its own timeline refresh, scheduled every 15 minutes.
  • Permissions: Core monitoring itself does not require shell access, Accessibility, or osascript. App icon lookup and macOS policy checks are still subject to normal platform behavior.

Installation

This repo is currently source-first. There is no packaged installer or notarized release flow documented in the repo yet.

For a working local install:

  1. Install Xcode 15 or newer.
  2. Make sure you have an Apple Developer account available for signing the app, widget extension, and app group container.
  3. Build the app locally.
  4. Copy Performance Monitor.app into /Applications.
  5. Launch the app once before adding or testing the widget.
  6. If macOS blocks the first launch, go to System Settings > Privacy & Security and click Open Anyway for Performance Monitor.

This project currently ships DMGs signed with a local Apple Development identity and not notarized, so the first launch on another Mac may require that manual Open Anyway step.

If you only want to hack on the code, building from Xcode is enough. If you want the widget deep link to behave like a normal installed app, keep the signed build in /Applications.

Build And Run

The repo already includes a generated PerformanceMonitor.xcodeproj. You only need XcodeGen if you change project.yml.

# Optional: install XcodeGen if you plan to regenerate the project
brew install xcodegen

# Optional: regenerate the Xcode project after editing project.yml
xcodegen generate

# Build a signed Debug app
xcodebuild -scheme PerformanceMonitor -configuration Debug build -allowProvisioningUpdates

# Install the built app into /Applications
cp -R "$(xcodebuild -scheme PerformanceMonitor -configuration Debug -showBuildSettings 2>/dev/null | grep ' BUILT_PRODUCTS_DIR' | awk '{print $3}')/Performance Monitor.app" "/Applications/Performance Monitor.app"

# Launch it
open -a "/Applications/Performance Monitor.app"

If macOS warns that the app cannot be opened because it is from an unidentified or unverified developer, move it into /Applications, try launching it once, then go to System Settings > Privacy & Security and use Open Anyway.

You can also open PerformanceMonitor.xcodeproj in Xcode and run the PerformanceMonitor scheme directly.

Requirements

  • macOS 14.0+
  • Xcode 15.0+
  • Swift 5.9+
  • An Apple Developer account for signing the app, widget extension, and app group container
  • Optional: /Applications/DiskCleanupTool.app if you want the disk cleanup shortcut to do something

Known Limitations

  • No release packaging workflow yet: The documented install path is still local build plus local signing.
  • Widget updates are best when the app is running: Without the menu bar app pushing fresh data, widget refresh falls back to a slower 15-minute timeline.
  • Widget deep linking depends on a healthy signed install: Expired local provisioning profiles or multiple registered copies can break widget launch behavior.
  • Claude detection is heuristic-based: It currently identifies Claude by process path and process-group behavior, so future Claude packaging changes may require code updates.
  • Process list is intentionally scoped: It shows regular running apps, not every daemon, helper, or launch agent on the machine.
  • Disk cleanup is external: The CLEAN UP DISK button only opens /Applications/DiskCleanupTool.app; this repo does not implement disk cleanup itself.

Troubleshooting

  • The widget says the app cannot be opened: Rebuild with -allowProvisioningUpdates, reinstall the app to /Applications, then remove and re-add the widget if needed. Local development provisioning profiles for the widget can expire.
  • The widget looks stale: Launch the menu bar app once. While the app is running, it refreshes the shared widget data every 30 seconds.
  • The CLEAN UP DISK button does nothing: Install DiskCleanupTool.app into /Applications or remove that integration from the UI.
  • Widget deep link opens the wrong copy during development: Keep the signed app in /Applications and avoid leaving multiple registered copies in DerivedData and /Applications at the same time.

Contributing

Issues and pull requests are welcome.

If you are filing a bug, include:

  • macOS version
  • Xcode version
  • whether you ran the app from Xcode or from /Applications
  • whether the problem is in the menu bar app, the widget, or the deep link between them
  • screenshots or logs when available

If you are sending a PR:

  • keep changes aligned with the current native SwiftUI/AppKit/Darwin approach
  • update project.yml if you change project structure, then regenerate PerformanceMonitor.xcodeproj
  • update this README when behavior, installation steps, or limitations change

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages