alin23/Lunar
Intelligent adaptive brightness for your external monitors
Solo project — review before adopting
worst of 4 axessingle-maintainer (no co-maintainers visible); no tests detected…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓MIT licensed
- ⚠Solo or near-solo (1 contributor active in recent commits)
Show 2 more →Show less
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: onboard a second core maintainer; add a test suite
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/alin23/lunar)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/alin23/lunar on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: alin23/Lunar
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alin23/Lunar shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Solo project — review before adopting
- Last commit 2d ago
- MIT licensed
- ⚠ Solo or near-solo (1 contributor active in recent commits)
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live alin23/Lunar
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/alin23/Lunar.
What it runs against: a local clone of alin23/Lunar — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in alin23/Lunar | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alin23/Lunar. If you don't
# have one yet, run these first:
#
# git clone https://github.com/alin23/Lunar.git
# cd Lunar
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of alin23/Lunar and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alin23/Lunar(\\.git)?\\b" \\
&& ok "origin remote is alin23/Lunar" \\
|| miss "origin remote is not alin23/Lunar (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Lunar/AppDelegate.swift" \\
&& ok "Lunar/AppDelegate.swift" \\
|| miss "missing critical file: Lunar/AppDelegate.swift"
test -f "Lunar.xcodeproj/project.pbxproj" \\
&& ok "Lunar.xcodeproj/project.pbxproj" \\
|| miss "missing critical file: Lunar.xcodeproj/project.pbxproj"
test -f "Lunar.xcworkspace/contents.xcworkspacedata" \\
&& ok "Lunar.xcworkspace/contents.xcworkspacedata" \\
|| miss "missing critical file: Lunar.xcworkspace/contents.xcworkspacedata"
test -f "Lunar/ALS/lunar.yaml" \\
&& ok "Lunar/ALS/lunar.yaml" \\
|| miss "missing critical file: Lunar/ALS/lunar.yaml"
test -f ".swiftformat" \\
&& ok ".swiftformat" \\
|| miss "missing critical file: .swiftformat"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alin23/Lunar"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Lunar is a native macOS app that intelligently controls external monitor brightness, volume, and contrast via DDC/CI protocol in real hardware (not software overlays). It supports adaptive brightness modes triggered by ambient light sensors, built-in MacBook/iMac sensors, or location-based sunrise/sunset timing, plus XDR/HDR displays reaching 1000-1600 nits and sub-zero dimming for late-night work. Xcode workspace project (Lunar.xcworkspace) combining multiple targets, likely split into UI (Swift/SwiftUI), system integration (DDC/Objective-C), and monitor detection layers. Pre-commit hooks (.pre-commit.sh, .pre-push.sh) enforce code quality. Localization structure (Localization/Lunar/Base.lproj, en.lproj) supports multi-language UI. Frameworks bundled as .tar.gz (Frameworks/frameworks.tar.gz) rather than SPM dependencies.
👥Who it's for
macOS users with external monitors (especially professionals doing design, video, or development work) who want hardware-level brightness control via keyboard hotkeys, and contributors working in Swift/Objective-C on system-level monitor APIs and DDC protocol implementation.
🌱Maturity & risk
Production-ready and actively maintained: 2M+ lines of Swift code, native support for both Intel and Apple Silicon, distributed via Homebrew and direct .dmg download, with a visible Discord community. Recent project structure (Lunar.xcworkspace, .pre-commit.sh, git-secret integration) and TypeScript-based web presence (Stylus/web assets) indicate ongoing active development.
Single-author maintainer (alin23) poses succession risk. Large codebase (2M Swift lines) with C/Objective-C system-level code (106K C, 28K ObjC) requires deep macOS graphics/DDC protocol knowledge. git-secret usage suggests credential management complexity. No visible test directory in top 60 files indicates potential test coverage gaps for hardware interaction code.
Active areas of work
No recent commit or PR data visible in provided file structure, but active maintenance indicated by workspace organization, pre-commit infrastructure, and web updates. Check GitHub Actions in .github/workflows (not shown) and Discord for current focus areas.
🚀Get running
- Clone:
git clone https://github.com/alin23/Lunar.git && cd Lunar2) Open workspace:open Lunar.xcworkspace3) Select Lunar scheme in Xcode 4) Run target on macOS 10.15+ (check Deployment Target in Lunar.xcodeproj/project.pbxproj)
Daily commands: Open Lunar.xcworkspace in Xcode → Select 'Lunar' scheme → Product → Run (⌘R). Requires macOS 10.15+ and may need Accessibility permissions at runtime. For building CLI tools, check Makefile (5.8K lines, likely build helpers).
🗺️Map of the codebase
Lunar/AppDelegate.swift— Main application entry point and lifecycle management; controls app startup, window initialization, and system integration.Lunar.xcodeproj/project.pbxproj— Xcode project configuration defining all build targets, dependencies, and compilation settings for macOS app.Lunar.xcworkspace/contents.xcworkspacedata— Workspace configuration that orchestrates multiple projects and CocoaPods dependencies into a cohesive build environment.Lunar/ALS/lunar.yaml— Core configuration for Ambient Light Sensor integration defining sensor types, I2C communication, and brightness calibration..swiftformat— Swift code formatting rules enforced across the codebase; essential for maintaining consistent code style among contributors.
🧩Components & responsibilities
- AppDelegate (Lunar/AppDelegate.swift) (Swift, Cocoa, AppKit) — Orchestrates app lifecycle, initializes core services, manages window and menu bar UI
- Failure mode: App crashes or fails to launch; system integration lost
- DDC/CI Controller (DDC/CI, I2C, macOS IOKit) — Sends brightness commands to monitors using DDC protocol over I2C/serial
- Failure mode: Monitor does not respond; brightness adjustment fails silently or with timeout
- ALS Sensor Hub (MicroPython) (MicroPython, I2C, Adafruit sensor drivers) — Reads ambient light values from I2C sensor array and reports lux values to macOS app
- Failure mode: Sensor disconnected or malfunctioning; adaptive brightness unavailable
- Brightness Calculation Engine (Swift, YAML parsing) — Maps lux readings to brightness levels using calibration curves defined in YAML profiles
- Failure mode: Incorrect brightness mapping; adaptive adjustments too aggressive or too subtle
- Monitor Profile Manager (Lunar/ALS/lunar.yaml) (YAML configuration) — Centralizes DDC command definitions and brightness range limits for all supported monitors
- Failure mode: Unsupported monitor; incorrect DDC codes sent; app cannot adjust specific model
🔀Data flow
ALS Sensor Hub (I2C)→Lunar App— Ambient light lux values polled periodically (~1-5s intervals)Lunar App→Brightness Calculation Engine— Lux value + current monitor profile → computed brightness target (0–100%)Brightness Calculation Engine→DDC/CI Controller— Target brightness level → DDC command formatted for monitorDDC/CI Controller→External Monitor— DDC command sent over I2C/serial → hardware brightness PWM adjustedLunar App→UI / Menu Bar— Current brightness state displayed; user can manually override or enable/disable auto-adjustYAML Config Files (Lunar/ALS/*.yaml)→App at Launch— Sensor and monitor profiles loaded into memory; calibration curves parsed
🛠️How to make changes
Add Support for a New Ambient Light Sensor
- Create a new YAML configuration file in Lunar/ALS/ following the pattern of existing sensors (e.g., tsl2591.yaml) (
Lunar/ALS/[new-sensor-name].yaml) - Define I2C address, register offsets, and calibration curves in the YAML file (
Lunar/ALS/[new-sensor-name].yaml) - Add sensor integration entry to Lunar/ALS/lunar.yaml mapping it to display profiles (
Lunar/ALS/lunar.yaml) - Update Lunar/ALS/lib/ with any new Adafruit MicroPython sensor drivers required (
Lunar/ALS/lib/adafruit_[sensor_name].mpy)
Add a New Monitor Configuration Profile
- Define DDC/CI communication parameters in a new profile within Lunar/ALS/lunar.yaml (
Lunar/ALS/lunar.yaml) - Specify brightness range limits and DDC command codes for the target monitor model (
Lunar/ALS/lunar.yaml)
Maintain Code Quality & Formatting Standards
- Ensure all Swift code follows the formatting rules defined in .swiftformat before committing (
.swiftformat) - Run pre-commit hooks automatically via .pre-commit.sh to catch issues early (
.pre-commit.sh) - Update CHANGELOG.md with user-facing changes for each release (
CHANGELOG.md)
🔧Why these technologies
- Swift + Xcode — Native macOS development for system-level hardware control, DDC/CI protocol access, and native UI integration
- DDC/CI Protocol — Standard hardware protocol for controlling external monitor brightness, contrast, and inputs via I2C/serial communication
- MicroPython + I2C Sensors — Lightweight firmware for ambient light sensor hub; Adafruit libraries provide sensor abstraction and calibration
- CocoaPods / Swift Package Manager — Dependency management for macOS frameworks and third-party libraries while maintaining reproducible builds
⚖️Trade-offs already made
-
Hardware brightness via DDC/CI instead of software overlay
- Why: Provides true monitor hardware control, reducing power consumption and avoiding image quality degradation
- Consequence: Requires monitor support for DDC/CI; not all older or budget monitors implement it
-
Separate ALS hardware module vs. built-in sensors
- Why: Allows users to add ambient light sensing without upgrading monitors; flexible hardware integration
- Consequence: Adds complexity with I2C/MicroPython stack; requires optional hardware purchase for auto-adjust feature
-
YAML-based sensor and profile configuration
- Why: Easy extension without code recompilation; centralized hardware definitions
- Consequence: Requires users or contributors to understand YAML syntax and I2C register mappings
-
macOS-only application
- Why: Tight integration with macOS system APIs for monitor control and menu bar UI
- Consequence: Windows and Linux users cannot use Lunar; limited addressable market
🚫Non-goals (don't propose these)
- Does not provide brightness control for built-in laptop displays (external monitors only)
- Does not implement authentication or cloud sync (local-only application)
- Does not support Windows or Linux operating systems
- Does not replace manual monitor controls; adaptive adjustment is optional enhancement
⚠️Anti-patterns to avoid
- Hardcoded I2C Addresses in YAML —
Lunar/ALS/bh1750.yaml, tsl2591.yaml, tcs34725.yaml, etc.: undefined
🪤Traps & gotchas
- Frameworks bundled as .tar.gz (Frameworks/frameworks.tar.gz) rather than CocoaPods/SPM—must extract before build. 2) git-secret required: setup GPG keys from .gitsecret/keys/ before committing sensitive changes. 3) DDC protocol communication likely requires Accessibility permissions at runtime; simulator may not support hardware DDC. 4) macOS version constraints: check Lunar.xcodeproj for Deployment Target (likely 10.15+); Apple Silicon dual binary support adds build complexity. 5) Pre-commit hooks (.pre-commit.sh) may block commits if .swiftformat violations detected.
🏗️Architecture
💡Concepts to learn
- DDC/CI Protocol — Core to Lunar's functionality; understanding DDC (Display Data Channel over I2C) is essential to grasp how brightness commands reach monitor hardware instead of using software overlays
- Ambient Light Sensor (ALS) Integration — Lunar's adaptive brightness feature relies on reading sensor data from MacBook/iMac built-in sensors via IOKit; critical for implementing auto-adjust modes
- Objective-C/Swift Bridging — 106K C code and 28K Objective-C for system APIs must interop with 2M Swift lines; understanding bridging headers and method swizzling is essential
- I2C (Inter-Integrated Circuit) — DDC protocol runs over I2C bus; understanding I2C transactions and device enumeration explains how Lunar discovers and communicates with monitors
- macOS Accessibility APIs — Required for keyboard hotkey capture and input switching; Lunar likely needs AXIsProcessTrustedWithOptions and CGEventTap for global shortcut handling
- HDR/XDR Display Capabilities — Lunar supports 1000-1600 nits XDR brightness; requires understanding Extended Dynamic Range APIs and display capability queries beyond standard 100-nit SDR
- Git-secret Encryption — Credentials and API keys encrypted in .gitsecret/; contributors must understand GPG key setup and secret file filtering to avoid leaking sensitive data
🔗Related repos
MonitorControl/MonitorControl— Native macOS DDC monitor controller written in Swift; direct competitor using same DDC protocol and Objective-C system APIsacidanthera/WhateverGreen— Kernel extension for graphics/display support on macOS; complements Lunar by enabling display detection on unsupported hardwareorbitalflux/displayplacer— macOS display configuration utility using similar system APIs for monitor detection and resolution switchingjakehilborn/displayplacer— Alternative display arrangement tool; shares same DDC/I2C protocol challenges on modern macOS versionsalin23/Codeshot— Sibling project by same author (alin23); demonstrates Swift/system integration patterns used in Lunar's UI and menu bar integration
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for ALS (Ambient Light Sensor) Python module
The Lunar/ALS directory contains Python code for ambient light sensor integration (bh1750.yaml, adafruit libraries), but there are no visible test files. Adding tests would ensure the sensor communication logic is robust across different hardware configurations and prevent regressions as the ALS module evolves.
- [ ] Create Lunar/ALS/tests/ directory structure
- [ ] Add unit tests for bh1750 sensor reading and calibration logic
- [ ] Add integration tests mocking I2C communication with adafruit_bus_device
- [ ] Configure pytest in setup.py or pyproject.toml for the ALS module
- [ ] Add test execution to pre-commit hook (.pre-commit.sh)
Create GitHub Actions workflow for Swift linting and formatting checks
The repo has .swiftformat config file and pre-commit hooks (.pre-commit.sh, .pre-push.sh) but no CI workflow to enforce Swift code quality on PRs. This prevents inconsistent formatting from being merged and catches style issues early without local setup.
- [ ] Create .github/workflows/swift-lint.yml workflow file
- [ ] Configure swiftformat to run on all .swift files in Lunar/ directory
- [ ] Add step to fail CI if formatting issues are detected
- [ ] Optionally add step to suggest automatic fixes as PR comments
- [ ] Document the workflow in CONTRIBUTING.md or README
Add shell script tests for .pre-commit.sh and .pre-push.sh hooks
The repo has pre-commit and pre-push shell scripts but no test coverage to verify they execute correctly and don't break in edge cases. Given the git-secret integration (.gitsecret/ directory), testing these hooks is critical to prevent accidental secret exposure.
- [ ] Create tests/ directory with bash/shell test framework (bats or similar)
- [ ] Write tests for .pre-commit.sh verifying git-secret integration works
- [ ] Write tests for .pre-push.sh ensuring it blocks commits with detected secrets
- [ ] Add mock encrypted files to test paths in .gitsecret/paths
- [ ] Integrate shell script tests into CI workflow or pre-push validation
🌿Good first issues
- Add unit tests for DDC command parsing/sending logic (C code at 106K lines has no visible test targets in top 60 files). 2) Expand localization coverage: add missing language .lproj folders beyond Base and en (check Localization/ structure). 3) Document the Frameworks/.tar.gz extraction process in README with exact shell commands for new contributors (currently undocumented dependency setup).
📝Recent commits
Click to expand
Recent commits
f3f3b50— Changelog (alin23)3ab3992— Reduce energy impact when UI is not visible (alin23)22e899d— Fix Auto Mode selecting Sensor instead of Sync in specific cases (alin23)aab237f— Changelog (alin23)352e872— 6.10.1 (alin23)1836597— Changelog (alin23)47c1416— Fix package resolution (alin23)95f6446— Sync mode after blackout fixes (alin23)9b2a10d— Fix Sync Mode getting wrongly enabled after coming out of sleep in blackout (alin23)df5ee9f— Fixes (alin23)
🔒Security observations
The Lunar codebase shows moderate security posture with several concerns primarily around configuration management and version control practices. The most critical issue is the exposure of GPG keys in .gitsecret configuration. User-specific Xcode data files are unnecessarily tracked in version control. The presence of binary files and unreviewed git hooks adds minor risks. Dependency management through Swift Package Manager appears in place but should be regularly audited. The application lacks a security policy document for responsible vulnerability disclosure. Overall, the codebase would benefit from improved .gitignore configuration, key management practices, and security documentation.
- High · Git Secrets Configuration Exposed —
.gitsecret/keys/. The .gitsecret directory contains GPG keys and trust database files (.gitsecret/keys/pubring.kbx, trustdb.gpg, etc.). While git-secrets is a security tool, storing encrypted keys in the repository and committing them creates a management burden and potential key compromise vector. Backup files like pubring.kbx~ should not be tracked. Fix: 1) Add .gitsecret/keys to .gitignore. 2) Store GPG keys securely outside the repository using a secrets manager. 3) Remove all backup files (*.bak, *~) from version control. 4) Rotate any potentially compromised keys. - Medium · Pre-commit and Pre-push Hooks Present —
.pre-commit.sh, .pre-push.sh. The presence of .pre-commit.sh and .pre-push.sh hooks suggests custom git hooks. Without reviewing the content, these files could execute arbitrary code during git operations. If compromised or misconfigured, they could enforce weak security policies or leak secrets. Fix: 1) Review hook contents for security issues. 2) Ensure hooks follow the principle of least privilege. 3) Document what each hook does. 4) Consider using a hook framework like Husky with audit trails. 5) Use signed commits to prevent unauthorized hook modifications. - Medium · Xcode Project Files and Workspace User Data Tracked —
Lunar.xcodeproj/xcuserdata/, Lunar.xcworkspace/xcuserdata/. User-specific Xcode configuration files (.xcuserdatad directories) are tracked in version control. These can contain sensitive information like build configurations, scheme settings, breakpoint data, and debugger expressions. Fix: Add the following patterns to .gitignore: xcuserdata/, *.xcworkspace/xcuserdata/, *.pbxuser, *.mode1v3, *.mode2v3, *.perspectivev3 - Medium · Package Manager Lock Files May Contain Vulnerabilities —
Lunar.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved, Lunar.xcworkspace/xcshareddata/swiftpm/Package.resolved. Package.resolved files are present for Swift Package Manager dependencies but cannot be analyzed without content. Dependencies should be regularly audited for known vulnerabilities. Fix: 1) Regularly run 'swift package resolve' and check for security updates. 2) Use tools like Swift Package Index vulnerability scanner. 3) Keep all dependencies updated to patched versions. 4) Review changelog/release notes for security fixes in updates. - Low · Compiled Binary Files in Repository —
Frameworks/frameworks.tar.gz. The Frameworks/frameworks.tar.gz contains pre-compiled frameworks. Binary files in version control can conceal malicious code and increase repository size. Fix: 1) Consider using a binary package manager or CDN for distributing precompiled frameworks. 2) If keeping in repo, implement code signing verification. 3) Use Git LFS (Large File Storage) for binary files. 4) Document checksum verification procedures. - Low · Lack of Security Policy Documentation —
Repository root. No SECURITY.md or security policy file found in root directory, making it unclear how security vulnerabilities should be reported. Fix: Create a SECURITY.md file documenting: 1) How to report security vulnerabilities responsibly. 2) Supported versions receiving security updates. 3) Expected response timeframes. 4) Preferred communication channels (e.g., security@lunar.fyi)
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.