Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Stats Administrator & Developer Guide

Generated June 2026 from exelban/stats at 89ac79e

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide is for administrators, power users, and developers who want to understand how Stats is built, how to deploy or build it, how it uses your system, and how to contribute. For day-to-day usage, see the companion User Guide.

Stats is a native macOS menu bar system monitor written in Swift for AppKit (Cocoa). It has no server component and no external runtime dependencies beyond Apple's own frameworks. Its defining architectural trait is a plugin-style module system: a shared framework (Kit) defines the contracts, and each monitor (CPU, RAM, GPU, …) is an independent module/target that plugs into it.


Table of Contents

  1. Executive Summary
  2. Architecture Overview
  3. Repository Structure
  4. The Kit Framework
  5. Module Lifecycle
  6. Data Persistence
  7. The SMC Subsystem & Privileged Helper
  8. Remote / System Stats Integration
  9. The Updater
  10. Building From Source
  11. Configuration Reference
  12. Security Analysis
  13. Code Patterns & Conventions
  14. Operations & Troubleshooting
  15. Potential Improvements
  16. Contributing
  17. Quick Reference

1. Executive Summary

Aspect Detail
Purpose macOS menu bar system monitor (CPU, GPU, RAM, Disk, Network, Battery, Sensors, Bluetooth, Clock, Remote)
Language Swift 5 (some files Swift 6)
UI framework AppKit / Cocoa (programmatic, no Storyboards for the modules)
Minimum OS macOS 12 (Monterey)
Architectures Apple Silicon (arm64) and Intel (x86_64)
Distribution Signed .dmg from GitHub Releases; Homebrew cask stats
External services api.mac-stats.com, api.github.com, app.system-stats.com (optional)
License MIT
Privileged component Optional SMC helper (XPC, /Library/PrivilegedHelperTools) for fan control

The codebase is organized as an Xcode workspace of many targets: the main app (Stats), a shared framework (Kit), one framework target per monitor under Modules/, an SMC helper toolset (SMC/), a WidgetKit extension (Widgets/), and a LaunchAtLogin helper.

Note

There is no package-manager manifest with third-party dependencies — Stats relies entirely on Apple frameworks (Cocoa, IOKit, CoreBluetooth, SystemConfiguration, Metal, ServiceManagement, UserNotifications, WidgetKit, WebKit, Carbon). This keeps the supply chain minimal.


2. Architecture Overview

                         ┌───────────────────────────────────────────┐
                         │              Stats.app (main)               │
                         │  AppDelegate                                │
                         │   • holds `modules: [Module]`               │
                         │   • global key monitor, updater, support    │
                         │   • SettingsWindow / Setup / Update / Support│
                         │   • CombinedView (merged menu bar item)     │
                         └───────────────┬─────────────────────────────┘
                                         │ imports
        ┌────────────────────────────────┼─────────────────────────────────┐
        │                                 │                                  │
   ┌────▼─────┐   ┌──────────┐   ┌────────▼────────┐   ...   ┌─────────────┐
   │  CPU     │   │  RAM     │   │   Network        │         │  Remote     │
   │ (Module) │   │ (Module) │   │   (Module)       │         │ (Module)    │
   └────┬─────┘   └────┬─────┘   └────────┬─────────┘         └──────┬──────┘
        │ subclass of  │                  │                          │
        └──────────────┴───────┬──────────┴──────────────────────────┘
                               ▼
                   ┌──────────────────────────┐
                   │        Kit (framework)    │
                   │  Module / Reader / Widget │
                   │  Popup / Portal / Settings│
                   │  Store / DB / Notifications│
                   │  SMC client / SystemKit   │
                   └─────────────┬─────────────┘
                                 │ XPC (fan control only)
                                 ▼
                   ┌──────────────────────────┐
                   │  SMC Helper (privileged)  │
                   │  /Library/PrivilegedHelperTools │
                   └──────────────────────────┘

Flow: AppDelegate instantiates all modules into a global modules array, then calls mount() on each. A mounted module starts its Readers (background pollers), which read system data and fire callbacks. Each callback updates the module's menu bar widgets, its pop-up, its portal (the row shown in the combined pop-up), and its notifications. The Kit framework supplies all of these base classes; modules subclass and specialize them.

Key design properties

  • Loose coupling via NotificationCenter. Modules and views communicate through named notifications (.toggleModule, .togglePopup, .toggleSettings, .moduleRearrange, .pause, .remoteState, …) rather than direct references. This keeps modules independent.
  • Configuration as data. Each module ships a config.plist (Name, State, Symbol, Widgets, Settings, Preview). The module_c struct parses it at init to decide the module's default state, default widget, and available widgets. Adding/removing a widget is a plist edit, not code.
  • Persistence is the source of truth. All user choices live in UserDefaults via the Store wrapper; historical samples live in a small embedded DB. There is no in-memory-only state that matters across launches.

3. Repository Structure

Stats/                 Main application target
  AppDelegate.swift      App entry, module registry, update/support scheduling
  helpers.swift          Argument parsing, version migration, dock/login setup
  Views/                 Settings UI
    Settings.swift         SettingsWindow (sidebar + toolbar), MainView, SidebarView
    AppSettings.swift      ApplicationSettings (global preferences)
    Dashboard.swift        Read-only device information panel
    CombinedView.swift     Merged single menu bar item + combined pop-up
  Supporting Files/      Info.plist, assets, .lproj localizations (40+ languages)

Kit/                   Shared framework (the plugin contract)
  constants.swift        Sizes, ModuleType enum, widget_t enum
  extensions.swift       UI helpers, color/format helpers, KeyboardShartcutView
  helpers.swift          LaunchAtLogin, Units/DiskSize, label/value views, rows
  module/                Module, Reader, Widget, Popup, Portal, notifications
  Widgets/               Widget implementations (Mini, LineChart, BarChart, …)
  plugins/               SMC client, SystemKit, sensor plugins
  Supporting Files/, lldb/

Modules/               One framework target per monitor
  CPU/ GPU/ RAM/ Disk/ Net/ Battery/ Sensors/ Bluetooth/ Clock/ Remote/
    main.swift             Module subclass + data structs + reader wiring
    readers.swift          Reader subclasses (the actual data collection)
    settings.swift         Per-module settings UI
    popup.swift            Per-module pop-up UI
    portal.swift           Combined-pop-up row
    notifications.swift    Threshold notifications
    widget.swift / preview.swift (where applicable)
    config.plist           Module manifest (name, widgets, settings, preview)

SMC/                   Command-line SMC tool (`smc`) + privileged Helper
  main.swift             CLI: list/set/fan/fans/reset/help
  Helper/                XPC privileged helper for fan control
Widgets/               WidgetKit extension (desktop / Notification Center)
LaunchAtLogin/         Tiny helper binary that relaunches the main app
Stats.xcodeproj/       Xcode project & shared schemes
Tests/                 Unit tests

Note

The bulk of the file count is localization (*.lproj for 40+ languages) and asset catalogs (device icons). The hand-written Swift source is concentrated in Kit/, Modules/*/, and Stats/.


4. The Kit Framework

Kit is the contract every module obeys. Understanding these five abstractions explains the whole app.

4.1 Module (base class)

Module (in Kit/module/module.swift) is the superclass of every monitor. It owns:

  • a module_c config (parsed from the target's config.plist),
  • a MenuBar of SWidgets,
  • an optional Window (settings), PopupWindow, Portal, NotificationsWrapper, and PreviewWrapper,
  • a list of Reader_p pollers.

module_c reads the plist keys:

Plist key Meaning
Name Module display name (required)
State Default enabled state
Symbol / AlternativeSymbol SF Symbol for the module icon
Widgets Dictionary of available widgets, each with Default and Order
Settings Settings metadata
Preview Preview availability

4.2 Reader<T> (data collection)

Reader<T: Codable> (in Kit/module/reader.swift) is a generic, thread-safe poller:

  • Holds a typed value: T? behind a serial dispatch queue.
  • Runs on a configurable interval ({module}_updateInterval, default 1s) via an internal Repeater, with an optional second-boundary aligned mode for clocks.
  • Persists the last value to DB and forwards it to SystemStats.shared.send(...) for remote monitoring.
  • Supports start / pause / stop / lock / unlock and a sleep mode so readers stop when the Mac sleeps.
  • popup/preview readers run only while their UI is visible, saving energy.

Each module defines its own readers (e.g. CPU has LoadReader, ProcessReader, TemperatureReader, FrequencyReader/LimitReader, AverageLoadReader).

Note

LimitReader (Intel) vs. FrequencyReader (Apple Silicon) are selected with #if arch(x86_64) / #else. This compile-time branching for architecture-specific metrics recurs throughout the modules.

4.3 widget_t (widget catalog)

The widget_t enum enumerates all widget styles. Each maps to a concrete WidgetWrapper subclass:

widget_t Raw value Class
mini mini Mini
lineChart line_chart LineChart
barChart bar_chart BarChart
pieChart pie_chart PieChart
networkChart network_chart NetworkChart
speed speed SpeedWidget
battery battery BatteryWidget
batteryDetails battery_details BatteryDetailsWidget
stack sensors StackWidget
memory memory MemoryWidget
label label Label
tachometer tachometer Tachometer
state state DotWidget
text text TextWidget

widget_t.new(...) instantiates both a live widget and a preview image. A module's data callback then switches on the concrete widget type to push values — this switch is the authoritative list of which widgets a module actually feeds.

4.4 Popup, Portal, Settings

  • Popup_p / PopupWrapper — the detail panel. A PopupWindow (borderless NSPanel) hosts a PopupView with a header (HeaderView) offering Activity Monitor/Calendar/System Stats shortcuts and a settings button. Popups support a per-module keyboard shortcut (stored as {module}_popup_keyboardShortcut).
  • Portal_p / PortalWrapper — a compact module summary row shown in the combined pop-up.
  • Settings_v — per-module settings view, wired to the module via callbacks (callback, setInterval, setTopInterval, selection handlers, etc.).

4.5 Helpers

Kit also provides reusable UI builders (popupRow, portalRow, separatorView, switchView, selectView, sliderView, colorSelectView), formatting types (Units, DiskSize), a KeyboardShartcutView recorder, and LaunchAtLogin (using SMAppService on macOS 13+ and the legacy SMLoginItemSetEnabled below that, with a migrate() path).


5. Module Lifecycle

init()        Parse config.plist → build menuBar widgets, popup, settings,
              portal, notifications. Read enabled state from Store.
              isAvailable() decides if the module can run at all.
   │
mount()       Called by AppDelegate at startup (in reverse order). If enabled,
              start all readers and enable the menu bar item.
   │
enable()      Persist enabled=true, start readers, show widgets.
disable()     Persist enabled=false, stop readers, hide widgets & popup.
   │
terminate()   willTerminate() hook, stop+terminate readers, disable menu bar.

isAvailable() is overridden per module — e.g. Battery checks IOPSCopyPowerSourcesList, Network checks for any SCNetworkInterface. Unavailable modules are forced off.

A module is shown in the menu bar only when enabled and has at least one active widget; AppDelegate.showSettingsIfNoActiveWidgets() opens Settings on launch when nothing is active.

Pause is global: posting .pause disables every enabled module and swaps the menu bar for a single app icon, restoring state when unpaused.


6. Data Persistence

Store Backing Holds
Store.shared UserDefaults All user preferences (module states, colors, intervals, widget choices, thresholds, clocks, etc.)
DB.shared Embedded key/value DB Last value per Reader ({Module}@{ReaderName}), optional time-series history
Widget defaults App-group UserDefaults ({TeamId}.eu.exelban.Stats.widgets) Data shared with the WidgetKit extension
  • Preference keys follow {ModuleName}_{option} (e.g. CPU_splitValue, Disk_<uuid>_popup, Network_publicIPRefreshInterval).
  • Store supports export(to:) / import(from:) (the Stats.plist backup) and reset().
  • Readers throttle DB writes (roughly every interval × 10 seconds) to limit disk churn.
  • On version change, parseVersion() migrates or, if no prior version is recorded, resets the store.

Tip

The app-group suite name embeds the developer Team ID ({TeamId}.eu.exelban.Stats.widgets). If you re-sign Stats under a different team for a custom build, the WidgetKit extension must use the matching app group or widgets won't receive data.


7. The SMC Subsystem & Privileged Helper

Stats reads hardware sensors (temperatures, voltages, power, fans) through the System Management Controller (SMC). Reading is unprivileged; changing fan speed/mode is privileged and goes through a separate helper.

7.1 The smc CLI tool

SMC/main.swift builds a small command-line tool bundled with the app:

./smc [command]

Commands:
  list     list keys and values
  set      set value to a key            (-k <4-char key> -v <int>)
  fan      set fan speed / mode          (<id> -v <speed> | -m <0|1>)
  fans     list fans (count, actual/min/max/target speed, mode)
  reset    reset Ftst — Apple Silicon only
  help     help menu

Flags (for list):
  -t  temperature sensors    -v  voltage sensors
  -p  power sensors          -f  fans

Fan mode 0 = automatic, 1 = manual. SMC keys are 4 characters (e.g. FNum, F0Ac, F0Mx).

7.2 The privileged Helper (fan control)

Fan writes are performed by an XPC helper installed at /Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper, registered as a launch daemon (/Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist).

Stats.app  ──XPC──►  SMC.Helper  ──shells──►  smc fan <id> -m/-v ...
                       │
                       └─ validates caller code signature on every connection

Security-relevant behavior in SMC/Helper/main.swift:

  • The helper listens on a Mach service (NSXPCListener(machServiceName: "eu.exelban.Stats.SMC.Helper")).
  • Every incoming XPC connection is validated with CodesignCheck.codeSigningMatches(pid:) — the caller's signing certificates must match the helper's own. Mismatched callers are rejected. This prevents arbitrary processes from driving fan control.
  • The helper exposes only setFanMode, setFanSpeed, resetFanControl, version, and uninstall over the HelperProtocol.
  • It self-terminates when the last connection drops, and uninstall unloads the daemon via launchctl and removes both the daemon plist and the helper binary.

Warning

Fan control is in legacy maintenance mode — no new features or fixes. The privileged helper is the highest-risk component in the app's threat model; the code-signature check on each connection is the primary mitigation. Review it carefully before shipping a re-signed build.

To remove the helper, the app calls SMCHelper.shared.uninstall() (surfaced as Uninstall fan helper in Settings).


8. Remote / System Stats Integration

The Remote module and SystemStats client connect Stats to the optional System Stats cloud service.

Endpoint base Constant Purpose
API host SystemStats.host REST + SSE data
App host SystemStats.appHost = app.system-stats.com Web links for machines/hosts

Key behaviors:

  • Auth: OAuth-style device flow (access_token/refresh_token/device_code/user_code/verification_uri_complete). Requests attach Authorization: Bearer <accessToken>.
  • Outbound monitoring: when Monitoring is enabled, each Reader calls SystemStats.shared.send(key:value:), serializing a compact remote() representation per data type (RemoteType).
  • Inbound dashboard: the Remote module fetches /remote/machine, /host, /group, /account and renders machines/hosts grouped per the account's order. A State dot aggregates overall up/down/mixed status.
  • Live updates: RemoteMachineStream opens an SSE connection (/remote/machine/<id>/sse) with exponential-backoff reconnect (capped at 60s) and parses data: frames into RemoteUpdates.
  • Control: disabled by default and gated behind an explicit warning dialog; enabling it allows the service to issue control actions.

Caution

All Remote functionality is opt-in and requires login. The Control capability widens the trust boundary (the cloud can act on the machine); document and default it off in any managed deployment.


9. The Updater

Stats self-updates via Updater(github: "exelban/stats", url: "https://api.mac-stats.com/release/latest").

  • Check cadence is the update-interval preference: silent (background install), atStart, oncePerDay, oncePerWeek, oncePerMonth (AppUpdateInterval). Background activity is scheduled with NSBackgroundActivityScheduler.
  • On a new version it either installs silently, posts a notification (clicking it downloads+installs), or shows the update window, depending on notification authorization.
  • After installing, the new app is relaunched and the updater cleans up the temporary DMG mount and downloaded .dmg via the --mount-path / --dmg-path arguments (both are path-validated to temp/Downloads to avoid deleting arbitrary files).
  • api.github.com is the fallback update source.

Note

The public-IP lookup also uses api.mac-stats.com. The maintainer runs this server specifically to avoid third-party IP providers; both update and IP requests can be blocked with a network filter at the cost of those features.


10. Building From Source

Prerequisites

  • macOS with Xcode (recent enough to target macOS 12+, Swift 5/6).
  • The repository: git clone https://github.com/exelban/stats.git.
  • For full builds: an Apple Developer Team ID for code signing (required for the app group, WidgetKit extension, and the privileged helper).

Build steps

git clone https://github.com/exelban/stats.git
cd stats
open Stats.xcodeproj
  1. Open Stats.xcodeproj in Xcode.
  2. Select the Stats scheme.
  3. Set your Team in Signing & Capabilities for each signed target (app, widgets extension, helper).
  4. Product → Run (⌘R) to build and launch, or Product → Archive to produce a distributable build.

Important

Several capabilities depend on correct signing: the app group ({TeamId}.eu.exelban.Stats.widgets) that feeds macOS widgets, and the privileged helper (which validates that callers share its signing identity). Building with a personal team works for local runs, but widgets and fan control require the entitlements/app group to line up.

Code style

The repo uses SwiftLint (.swiftlint.yml). Notable limits: line_length: 200, file_length warning at 1400 / error at 1800, type_body_length 700/1000. Several rules are disabled or opt-in; many data-model type names are excluded from identifier_name.

Tip

Run swiftlint before submitting a PR. The config disables force_cast, cyclomatic_complexity, and a few others as "todo", so don't be surprised by existing force-casts in older code.


11. Configuration Reference

All configuration is UserDefaults (via Store). There is no config file for end users — preferences are set in the UI and can be exported to Stats.plist.

Global keys

Key Default Values
update-interval silent silent, atStart, oncePerDay, oncePerWeek, oncePerMonth
temperature_units system system, plus Celsius/Fahrenheit options
dockIcon false bool
keep_menubar_positions false bool
CombinedModules false bool
CombinedModules_spacing none spacing option
CombinedModules_separator false bool
CombinedModules_popup true bool
version — last-run version (migration)
pause false global pause
support_ts — last support-window timestamp

The macOS-widgets switch (systemWidgetsUpdates_state) lives in the app-group suite, not the main store.

Representative per-module keys

Pattern Example Meaning
{Module}_state CPU_state Module enabled
{Module}_updateInterval RAM_updateInterval Reader interval (sec)
{Module}_popup_keyboardShortcut CPU_popup_keyboardShortcut Pop-up hotkey
{Module}_position GPU_position Order in combined item
CPU CPU_usagePerCore, CPU_splitValue, CPU_clustersGroup, CPU_systemColor, CPU_userColor, CPU_eCoresColor, CPU_pCoresColor, CPU_sCoresColor CPU display options
RAM RAM_splitValue, RAM_appColor, RAM_wiredColor, RAM_compressedColor, RAM_textWidgetValue RAM display options
Disk Disk_disk, Disk_mainColor, Disk_textWidgetValue, Disk_<uuid>_popup Disk selection & display
GPU GPU_gpu, GPU_showType GPU selection & label
Network Network_publicIPRefreshInterval, Network_usageReset, Network_widgetActivationThreshold(State/Size), Network_textWidgetValue Network behavior
Sensors Sensors_sensor, Sensors_fanValue Selected sensor / fan unit
Bluetooth ble_<id>, ble_<id>_notification Per-device visibility/threshold
Clock Clock_list, clock_<id>_popupState, clock_<id>_popupIndex Clock definitions
Remote Remote_machine_<id>, Remote_host_<id> Per-machine/host visibility

12. Security Analysis

Area Assessment
Privilege boundary Fan control runs in a separate root helper. Every XPC connection is gated by CodesignCheck (caller's signing certs must equal the helper's). This is the central security control — preserve it in forks.
Code execution The helper shells out to the bundled smc tool (/bin/sh -c "<smc> fan <id> ..."). Inputs are integers from internal calls, not user free-text, limiting injection surface.
Network Outbound only. Update checks (api.mac-stats.com, fallback api.github.com), public IP (api.mac-stats.com), and — only if logged in — System Stats (app.system-stats.com). Remote requests use Authorization: Bearer over HTTPS.
Auth tokens Remote uses OAuth device flow; access_token/refresh_token are held by the SystemStats.auth client. Treat the token store as sensitive.
Data exfiltration Monitoring data leaves the machine only when the user enables Monitoring in System Stats. Control must be explicitly enabled behind a warning.
Argument handling --mount-path / --dmg-path are validated to temp/Downloads and reject .. traversal before deleting anything.
App Transport Security Community issue #3320 requested hardening ATS (avoiding a global NSAllowsArbitraryLoads). Verify the shipped Info.plist ATS posture when auditing.

Caution

For managed/enterprise deployments: keep Control disabled, consider blocking api.mac-stats.com if you don't want update/IP calls, and audit the privileged helper's signing identity. The helper is installed system-wide (/Library/...) and persists until explicitly uninstalled.


13. Code Patterns & Conventions

  • Programmatic AppKit. Views are built in code (NSStackView, NSGridView, custom NSView subclasses). No SwiftUI in the core app (SwiftUI/WidgetKit only in the widget extension).
  • Notification-driven coordination. Cross-component events flow through NotificationCenter with Notification.Name extensions (.toggleModule, .togglePopup, .toggleSettings, .pause, .moduleRearrange, .remoteState, etc.).
  • Thread-safe value holders. Shared mutable collections (e.g. Disks, GPUs, Reader.value) are guarded by dedicated serial DispatchQueues with sync get/set.
  • Codable everywhere. Data models conform to Codable for DB persistence and remote serialization; many implement a compact remote() string for the wire format.
  • Architecture branching. #if arch(x86_64) / #if arch(arm64) selects Intel vs. Apple Silicon code paths (frequency vs. scheduler limits, fan reset).
  • Config-as-plist. Module capabilities (widgets, default state) are declared in config.plist, parsed by module_c.
  • Localization-first. All user-facing strings pass through localizedString(...); 40+ .lproj bundles are maintained by the community.

14. Operations & Troubleshooting

Where things live at runtime

Item Location
Preferences UserDefaults for eu.exelban.Stats
Widget data App group {TeamId}.eu.exelban.Stats.widgets
Privileged helper /Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper
Helper launch daemon /Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist
Login item Registered via SMAppService.mainApp (macOS 13+)

Common operational tasks

# Reset all settings (clean slate)
/Applications/Stats.app/Contents/MacOS/Stats --reset

# Launch with certain modules disabled
/Applications/Stats.app/Contents/MacOS/Stats --disable sensors,bluetooth

# Remove the privileged fan helper
sudo launchctl unload /Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist
sudo rm /Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist
sudo rm /Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper

Tip

Prefer the in-app Uninstall fan helper button over manual rm; it performs the same launchctl unload and file removal in the correct order.

Diagnostics

Symptom Check
Menu bar icons missing (macOS 26) System Settings → Menu Bar → Stats = ON
Desktop widget empty macOS widgets setting enabled; app group/Team ID match
High CPU Disable Sensors/Bluetooth; raise update intervals
Network falsely DOWN Restart Stats; update to latest
Fan helper install fails Approve admin prompt; uninstall stale helper, retry
Update breaks app (Gatekeeper) Reinstall from Stats.dmg

15. Potential Improvements

These are drawn from the public issue tracker and visible code structure — candidates for contribution.

  • Fan control modernization. It's explicitly legacy. A maintained, well-tested fan-control path (and clearer install UX, given issues #3330/#3331/#3332) would close a recurring pain point.
  • ATS hardening (#3320) — avoid any global arbitrary-loads allowance.
  • Network interface status robustness (#2545, #3293) — eliminate false "DOWN" without requiring a restart.
  • Apple Silicon sensor mapping — sensor keys change per SoC; a maintained mapping (and handling for the M5 "super cores" frequency gap, #3325) would improve accuracy.
  • Per-monitor multi-display windows and richer RAM data (#3327).
  • CPU core frequencies on the menu bar (#3333) and usage history in an expanded window (#1194).
  • Fan-read debounce on startup to avoid spurious 100% notifications (#3211).
  • Code-health items the lint config flags as "todo": re-enable cyclomatic_complexity, type_name, and reduce force_cast usage.

16. Contributing

The project has a deliberate workflow (from the repository README):

  1. Open an issue first to discuss the feature or bug. PRs are expected to map to a discussed issue, or they may be closed automatically.
  2. Exceptions that can skip discussion: localization/translation changes, and contributions from established contributors whose work aligns with the project.
  3. Translations are community-driven — add a new .lproj or improve an existing one.
  4. Follow the existing SwiftLint configuration and the programmatic-AppKit, notification-driven, Codable-model conventions.

To add a new module: create a target under Modules/, subclass Module, add a config.plist declaring its widgets/settings, implement one or more Readers plus the popup/settings/portal/notifications views, and register an instance in the modules array in Stats/AppDelegate.swift.

To add a new widget: add a case to widget_t, implement a WidgetWrapper subclass, wire it in widget_t.new(...), and handle it in each relevant module's data callback.


17. Quick Reference

Targets

Target Role
Stats Main menu bar app
Kit Shared framework (Module/Reader/Widget/Popup/Portal/Settings/Store/DB/SMC client)
Modules/* One framework per monitor (CPU, GPU, RAM, Disk, Net, Battery, Sensors, Bluetooth, Clock, Remote)
SMC smc CLI tool
SMC/Helper Privileged XPC fan-control helper
Widgets WidgetKit extension
LaunchAtLogin Relaunch helper

smc commands

Command Purpose
list [-t/-v/-p/-f] List keys/values (filterable)
set -k <key> -v <int> Write a 4-char SMC key
fan <id> -v <speed> / -m <0|1> Set fan speed / mode
fans List fans and their speeds/mode
reset Reset fan control (Apple Silicon)
help Usage

Launch arguments

Argument Effect
--reset Reset all settings
--disable a,b Disable named modules
--mount-path <p> (updater) unmount temp DMG
--dmg-path <p> (updater) delete downloaded DMG

External hosts

Host Purpose
api.mac-stats.com Updates + public IP
api.github.com Fallback update check
app.system-stats.com Remote dashboard (opt-in)

Key notifications

.toggleModule, .togglePopup, .toggleSettings, .openModuleSettings, .togglePreview, .pause, .moduleRearrange, .toggleOneView, .combinedModulesPopup, .remoteState, .remoteAuthenticated, .fanHelperState, .refreshPublicIP, .resetTotalNetworkUsage, .clickInSettings.