Fluxa icon

Fluxa

Essential macOS system controls, one click away in your menu bar.

Fifteen quick actions, every one backed by a real system API — no fake toggles. Built in Swift + SwiftUI with zero third-party runtime dependencies.

macOS 14+ Swift 5.9 SwiftUI Apache-2.0 Sparkle 2
⬇ Download the DMG Source

Apple silicon · macOS 14+ · ≈3 MB · release notes and checksums

Scroll
PopoverRootView.swift CPU 7%
Fluxa menu-bar panel with system readings and quick actions Fluxa System Dashboard with CPU, GPU, memory and temperature charts Agent Usage window with Codex and Claude quota meters and daily token contribution grids Fluxa Lid Angle window Fluxa Trackpad Scale window Customize General tab with appearance, startup and permissions controls Customize Actions tab with per-action visibility switches and drag reordering Customize System tab with hardware readings, destinations and sampling interval Customize Agents tab with quota windows, refresh interval and Claude permission guidance Customize Updates tab with automatic-check preference and manual update button Fluxa About page with version, updates, GitHub details and support link
One fluid menu-bar surface — no separate settings window.

Fifteen real controls

Keep Awake, Dark Mode, Screen Clean, Lock Keyboard, Audio Output, Microphone Mute — every action calls a real system API. Keep Awake registers an IOKit power assertion; it doesn't fake a state and hope the display stays on.

SwiftUI IOKit MenuBarExtra @MainActor
// Services/KeepAwakeService.swift
let result = IOPMAssertionCreateWithName(
    kIOPMAssertionTypeNoDisplaySleep as CFString,
    IOPMAssertionLevel(kIOPMAssertionLevelOn),
    "Fluxa Keep Awake — user requested" as CFString,
    &assertionID
)
guard result == kIOReturnSuccess else { assertionID = 0; throw … }

Hardware you can watch

CPU, GPU, memory and temperature pin to the popover, the menu bar, or both. Click the strip and the readings expand into a 30-minute dashboard with separate percentage and degree axes, so neither unit is visually compressed. A failed sensor pass leaves a gap — it never repeats an old value as if it had been measured again.

Swift Charts IOKit / SMC @Observable 1–10 s sampling
// Services/SystemStatsService.swift — rolling window, in memory only
static let historyDuration: TimeInterval = 30 * 60

history.append(SystemStatsHistorySample(timestamp: timestamp, values: measuredValues))
let cutoff = timestamp.addingTimeInterval(-Self.historyDuration)
if let firstRetained = history.firstIndex(where: { $0.timestamp >= cutoff }),
   firstRetained > 0 {
    history.removeFirst(firstRetained)
}

Your agent quota, in the menu bar

Session and weekly meters with reset countdowns, plus six months of daily token history as a contribution grid per agent. The quotas come from the same endpoints each CLI calls; the history is rebuilt from the agents' own session logs, which is why the grid is already populated the first time you open it. Fluxa never refreshes those tokens — both providers rotate the refresh token on use, so renewing one here would break the very login being read.

async/await URLSession Keychain JSONL scanning
// Services/AgentUsageReaders.swift
// Deliberately not refreshed here — using the agent once renews it.
guard !credentials.isExpired else {
    throw AgentUsageReadError.tokenExpired(agent: Self.agentName,
                                           hint: Self.loginHint)
}
let (json, _) = try await AgentHTTP.getJSON(url: Self.usageURL, …)

The hinge, at 60 fps

On Apple Silicon the lid angle is a HID sensor whose feature report returns whole degrees; on Intel it's an IORegistry property in raw units. Fluxa tries both and animates a goniometer from whichever answers. On a desktop Mac the feature simply reports itself unavailable.

IOKit.hid CADisplayLink Apple Silicon + Intel
// Services/LidAngleMonitor.swift
/// 1. Apple Silicon: HID device (usage page 0x20 Sensor, usage 0x8A).
///    Feature report 1 returns [reportID, lo, hi] — lo|hi<<8 = degrees.
/// 2. Intel: the `LidAngle` IORegistry property (~16384 = 180°).
init() {
    if openHIDSensor() { isAvailable = true }
    else { … }
}

A scale hiding in your trackpad

Force Touch strain gauges already report pressure in grams — but only under a capacitive touch, and NSEvent.pressure only fires during a click. Fluxa dlopens the private MultitouchSupport framework, validates the frame layout at runtime, and hides the feature entirely if that layout ever changes.

dlopen MultitouchSupport UnsafeRawPointer
// Services/TrackpadWeightService.swift
// off 8  double timestamp   |   off 52  float pressure (GRAMS)
let pressure = record.loadUnaligned(fromByteOffset: offsetPressure,
                                    as: Float.self)
guard total.isFinite, pressure.isFinite,
      (0...20_000).contains(pressure) else { continue }

Customize · 5 tabs

Settings that stopped being one list

Preferences are grouped into General, Actions, System, Agents and Updates — and all of it still transitions in place inside the MenuBarExtra instead of opening a settings window, so the popover never loses focus. General holds the three visual styles, subtitles, Launch at Login and the door into Permissions & First Run.

In-panel navigation SMAppService Classic · Cyber · Cyber Dark

Actions — order and visibility

Every action gets a tinted icon tile and a switch in its own colour. Drag to reorder, turn one off to hide it from the dashboard; the layout survives relaunches through UserDefaults.

// Models/AppSettings.swift — one @Observable source of truth
@Observable
final class AppSettings {
    var actionOrder: [ActionID] = ActionCatalog.defaultOrder
    var hiddenActions: Set<ActionID> = []
    var controlStyle: ControlStyle = .classic
}

System — pick the readings and where they go

CPU, GPU, memory and die temperature each carry their current value right in the row, with two separate toggles: one for the popover, one for the menu bar. Sampling runs at 1, 2, 5 or 10 seconds — and the dashboard reuses that same loop rather than doubling the sensor work.

3 readings in the popover 4 in the menu bar

Agents — quota windows and refresh rate

Each detected quota window is listed with its live percentage. The refresh choices aren't round numbers: a 5-hour session window spends 100 points over 300 minutes, so one percentage point takes three minutes. Polling faster can't return a different integer — it only spends requests. The tab spells out the cost of the interval you picked.

// Models/UsageRefreshInterval.swift
// "About 1.7% of a session window between reads."
case everyFiveMinutes   // ≈1.7%   ← default
case everyThreeMinutes  // the fastest that can show a new number

Updates — checked daily, installed on your word

Automatic checking is a consent toggle, not a default that acts on its own: it checks daily, and downloading and installing still require confirmation. Updates arrive over an HTTPS feed as Ed25519-signed archives, and the updater's windows stay independent of the menu-bar popover.

Sparkle 2.9.4 Ed25519 HTTPS appcast

No ads · No analytics · No system profiling

That line sits at the bottom of the About screen, and it's the whole policy. There is no Fluxa server of any kind. The only network calls are the agent quota endpoints and — only while About is open — GitHub's public API for the developer card. Token counts, the scan cache and your preferences live in Application Support and UserDefaults, never in a release artifact.

About now fits it all on one screen: version and build, the live GitHub profile card with stars, repos and followers, Check for Updates… with its last-checked timestamp, and the optional coffee link — no scrolling, no second window.

Local first No telemetry Apache-2.0 Zero dependencies

Screenshots show 2.6.2 (13) in the Cyber Dark appearance — the current release.

All fifteen actions

Every one backed by a real system API.

Keep Awake

IOKit power assertion — indefinitely or 15 min / 1 h / 4 h with auto-off.

🌗

Dark Mode

Switches the system appearance instantly via System Events.

🖥

Hide Desktop Icons

Clean screenshots and presentations, one toggle away.

👁

Show Hidden Files

Reveals dotfiles in Finder.

📥

Auto-hide Dock

Shows the Dock only on hover.

🌙

Screen Saver

Launches the system screen saver.

Screen Clean

Black overlay on every display; hot-plug aware, exits on click or ESC.

⌨️

Lock Keyboard

Blocks keyboard input globally; the mouse stays free to unlock.

🎯

Focus Mode

Do Not Disturb through two user-created Shortcuts.

🔊

Audio Output

CoreAudio device switching, hot-plug aware.

🎧

Bluetooth Audio

Connect paired AirPods without digging through menus.

🎤

Microphone Mute

Mutes the default input device via CoreAudio.

📐

Lid Angle

Live hinge readout on Apple Silicon and Intel.

⚖️

Trackpad Scale

Weighs small objects on the Force Touch strain gauges.

📊

Agent Usage

Live Claude & Codex quotas plus token history charts.

Install it in a minute

Download the DMG and drag Fluxa.app into Applications.

Or build from source

git clone https://github.com/zEhmsy/fluxa.git
cd fluxa
./build.sh
cp -r Fluxa.app /Applications/

⚠️ Fluxa is ad-hoc signed, not notarized. If macOS blocks the first launch, verify the download's origin and use System Settings → Privacy & Security → Open Anyway, if offered. Don't disable Gatekeeper. Requires macOS 14 (Sonoma) or later.

⬇ Download Fluxa.dmg

Already running Fluxa? About → Check for Updates… installs it in place. · All releases