A native macOS menu-bar item with one colored light each for DeepSeek and Z.ai.
Green = off-peak. Red = peak. Compact labels are DS and Z. Click the item for rates, local-time countdowns, the next shared off-peak period, and official pricing sources.
Source only. This repository does not ship a notarized binary. Build on a Mac, or use peaklights-check on Linux.
Requires macOS 13+ and Apple developer tools providing Swift 5.9 or newer. No Homebrew, third-party libraries, API keys, account login, or administrator access is required by the app.
git clone https://github.com/zw3rk/peaklights.git
cd peaklights
make installmake install runs the tests, compiles the native app, creates its icon, applies a local ad-hoc signature, installs ~/Applications/Peak Lights.app, and opens it. Double-click Install.command if you prefer. The installer does not change system security settings.
When developer tools are missing:
xcode-select --installComplete Apple's installer and rerun make install. A current Xcode installation also works. If a Swift-tools-version error appears, update the selected Apple developer tools to a version with Swift 5.9+.
Enable automatic startup using the lights → Options → Launch at Login. The app has no Dock icon and no normal window.
Rules were reviewed against official provider documentation on 10 September 2026. Sources and scope decisions are in docs/SOURCES.md.
Peak windows are the provider billing zones, not the Mac timezone. The menu prints upcoming times in the system timezone (TimeZone.autoupdatingCurrent).
| Indicator | Peak hours, Monday–Friday | Billing zone | Green means |
|---|---|---|---|
| DeepSeek | 01:00–04:00 and 06:00–10:00 | UTC | Half the peak V4 API token rate |
| Z.ai | 14:00–18:00 | UTC+8 | Half the standard Coding Plan model-credit consumption |
All other times, including weekends, are off-peak under these baseline rules. Z.ai's indicator is not a claim about ordinary pay-as-you-go API prices. Separate model/agent promotional campaigns and MCP tool-credit consumption are not modeled.
This is a schedule calculator, not an availability monitor, billing meter, or live pricing scraper. The provider's actual billing is authoritative. Boundaries are represented as start-inclusive and end-exclusive; this does not predict how a provider bills a request that spans a boundary.
The compact item always carries both labeled lights. Options add full provider names, countdowns directly in the menu bar, or ↑/↓ phase symbols. Tooltips and VoiceOver labels state each phase explicitly.
Click a provider's Schedule & pricing details submenu to see the billing-zone schedule, the next six changes in your local timezone, and its official documentation. The main menu shows the next change for each provider and when both will be off-peak.
Timers refresh at minute boundaries and pricing transitions. Wake, screen-wake, system-clock, locale, and timezone notifications trigger recalculation. All calculations use the provider's fixed UTC offset; changing your Mac's timezone or traveling does not shift the billing window. Upcoming-change submenu entries are refreshed when the menu reopens.
The app makes no network requests, reads no API keys, and uses no telemetry. Official documentation opens in your browser only after you select its menu command. There is no automatic rule update. A menu warning appears when the rule review date is at least 30 days old; the lights continue to reflect the stored schedule.
Choose Options → Edit pricing configuration…. This creates and opens:
~/Library/Application Support/PeakLights/pricing.json
Save plain-text JSON, then choose Reload pricing configuration. The app also reloads when the menu opens and on its regular minute refresh. Consult official provider documentation before changing reviewedOn.
The format uses ISO weekdays (1 = Monday through 7 = Sunday), fixed UTC offsets in minutes, and HH:mm windows. The end may be 24:00; overnight windows belong to their start day. Overlapping or touching windows merge. An empty window array means always off-peak.
Invalid custom configuration produces gray lights with question marks, not a silent fallback to green. The menu shows the error. Restore bundled pricing rules preserves the edited file as a backup. Exactly the two provider IDs deepseek and zai are required.
The Makefile is the project driver. See USAGE.md for flags, runtime paths, and the full target list.
make help
make check # PeakCore tests, CLI tests, installer script syntax
make peek # bundled-rule snapshot in the local timezoneswift run peaklights-check --at 2026-09-10T02:00:00Z --timezone Asia/Seoul --json
swift run peaklights-check --config "$HOME/Library/Application Support/PeakLights/pricing.json" --jsonThe CLI defaults to bundled rules and the host timezone for display. --timezone changes printed times only. On a Mac, after Apple's developer tools are installed:
make build # native release .app in dist/
make universal # Apple Silicon + Intel .app
make install # test, build, install and launchNix is optional (nix develop / direnv). It does not replace the macOS SDK.
nix run github:zw3rk/peaklights
nix run github:zw3rk/peaklights -- --jsonThat runs peaklights-check (portable CLI). The menu-bar .app is still make install on a Mac.
Open Package.swift in Xcode to work on the source. For testing application identity, menu-only activation, bundled resources, and Launch at Login, use the actual .app generated by the build script rather than swift run PeakLights.
Architecture: PeakCore is a pure, tested scheduling library; PeakLights is the AppKit/ServiceManagement shell; peaklights-check is the portable diagnostic CLI. No package dependencies are declared.
GitHub Actions builds a universal ad-hoc .app on macos-latest. That artifact is not Developer-ID signed or notarized. Set CODESIGN_IDENTITY to your own certificate before make build if you intend to notarize separately. The repository contains no signing credentials.
Before upgrading, quit the existing app. The installer refuses to replace a running or unrelated application. Your configuration and preferences are kept outside the app bundle.
To remove it, turn off Launch at Login, quit, and move ~/Applications/Peak Lights.app to Trash. Optional settings remain in ~/Library/Application Support/PeakLights/ and the com.zw3rk.PeakLights preferences domain. The installer does not create a separate daemon or LaunchAgent plist.
Apache-2.0. Copyright 2026 Moritz Angermann <moritz@zw3rk.com>, zw3rk pte. ltd. See LICENSE and NOTICE.