Repository navigation
Phase 1: foundations + XPC + permission lifecycle (M0–M3) - #1
Merged
Merged
Conversation
Also fix LD_RUNPATH_SEARCH_PATHS in project.yml: embedded LoginItem executable is 5 levels deep from Sleev.app/Contents/Frameworks, not 4.
Add GitHub Actions CI on macos-14 running swiftlint --strict, swiftformat --lint, xcodegen, xcodebuild build + test for every push or PR targeting master/main. Fix swiftformat violations in source files and extend .swiftformat with --exclude for internal/ examples.
… duplicate menubar items
- Extract SleeveGlyph helper (proportionally-scaled dots + triangle) - StatusBarController draws custom NSImage via SleeveGlyph instead of SF Symbol chevron; isTemplate = true for system menubar theming - OnboardingViewController: 520×420, NSVisualEffectView background, SF typography hierarchy (22pt semibold title, 13pt secondary body), accent-colored logo, primary blue Open System Settings button - OnboardingWindowController: content rect updated to 520×420
… vibrancy - SleeveGlyph: add naturalSize(forHeight:) helper so callers derive width from intrinsic aspect ratio, eliminating the negative-startX clip bug - SleeveGlyph: add image(height:) convenience that uses naturalSize - StatusBarController: switch to image(height:14) signature - OnboardingViewController: use image(height:60) for logo (no clipping); enable body label multi-line wrapping; center vstack vertically; align button stack centerX; constrain vstack top >= 56pt for traffic lights; wire NSVisualEffectView with Auto Layout pinned to all edges, state=.active - OnboardingWindowController: shrink window to 520×380; add .fullSizeContentView, transparent titlebar, hidden title, clear/non-opaque background for vibrancy
…ht buttons - Logo shrunk from 60pt to 36pt for a less-hero appearance - Title bumped from 22pt semibold to 26pt bold for clearer hierarchy - Body label switched to left-alignment in a fixed 400pt column - Button row extracted from vstack and pinned to bottom-right (24pt insets) - Window narrowed from 520×380 to 500×340 to match tighter layout
Adds a subtle rounded-rect pill (5pt radius, 0.5pt border at 10% white alpha, 6% white fill, 7pt × 2pt padding) around the status-bar glyph. Uses dynamic NSColor.labelColor so the pill resolves correctly in both light and dark menubars. Onboarding logo is unaffected (wrapped: false default). Removes the stale image(size:) overload; extracts drawPill and drawGlyph helpers to stay within swiftlint function_body_length limits.
- Add AXService wrapping AXIsProcessTrusted(WithOptions) for real state checks - Add AXPermissionMonitor polling every 1 s and firing onChange on transitions - Wire AgentService with AXService injection and uiProxy for reverse push - Wire XPCListener to set remoteObjectInterface + uiProxy on each connection - AgentMain composes all three and keeps monitor alive for the run loop
…oarding close button - Agent observes com.apple.accessibility.api and exits so launchd respawns it; the fresh process queries AXIsProcessTrusted() without the per-process stale cache, fixing the onboarding-never-dismisses bug. - AgentClient invalidationHandler schedules a reconnect instead of a no-op log; AgentClientObserver gains agentClientDidReconnect so the app layer re-evaluates AX state after the agent restarts. - SleevApp implements applicationShouldHandleReopen so clicking the Dock icon re-runs evaluatePermissionAndPresentUI instead of doing nothing. - OnboardingWindowController removes .closable from the style mask so the [X] button is gone; users must use Quit. - Add OnboardingWindowControllerTests (2 tests) as a regression guard; total test count is now 12.
On connection accept, call pushCurrentAXState() so the UI immediately learns the live permission state without polling. Fixes onboarding not dismissing after AX is already granted when a fresh agent spawns. Also emit initial state on first monitor tick as belt-and-suspenders, and remove dead reconnect() code path that never fired under launchd KeepAlive seamless reconnection.
…ache AXIsProcessTrusted() is stale-cached for the entire agent process lifetime. When the user grants Accessibility while sleev is already running, the long-lived agent always returns undetermined. Fix: while onboarding is visible the UI asks the agent to exit (launchd respawns it); each fresh agent process reads the real TCC state and pushes it via the existing connection-accept mechanism.
…ache Replace polling-based agent restart (launchd KeepAlive throttle degrades reliability) with a full-app self-relaunch: arm an NSWorkspace activation observer when the user clicks Open System Settings, then relaunch via a detached shell the moment sleev is re-activated so the new process reads fresh AXIsProcessTrusted state. Remove the now-dead restartForFreshAXCheck XPC method from protocol, agent, and client.
Match the standard menubar app pattern (Hidden Bar, AltTab, Rectangle):
the UI process holds the Accessibility grant and polls AXIsProcessTrusted
directly, rather than routing through a helper's reverse XPC push.
The previous helper-based push model proved unreliable when the agent
process restarted: pushes from a dying agent were dropped before XPC
could deliver them, leaving the onboarding window stuck even after the
user granted permission. UI-side polling eliminates the cross-process
complexity entirely.
- Add AccessibilityService in UI for AXIsProcessTrusted{,WithOptions}
- UI polls every 1.5s while onboarding is shown; stops on grant
- "Sleev" (not "SleevAgent") now appears in System Settings
- Remove SleevUIProtocol reverse channel, AXService, AXPermissionMonitor
- Agent simplified to just ping (preserved for Phase 2 work)
Migrate all bundle IDs, XPC mach service name, app group identifier, OSLog subsystem, launchd plist, entitlements, tests, and Makefile from the dev.sleev prefix to com.thanhhaudev.sleev. Also add -allowProvisioningUpdates to local build/test targets so Xcode can register the new bundle IDs automatically.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implementation of Phase 1 per docs/superpowers/plans/2026-05-17-sleev-implementation-plan.md (local-only). M0.1 scaffold; M0.2 source stubs; M0.3 XPC contract; M0.4 XPC ping + agent launchd registration (M2.3 merged); M0.5 CI. Subsequent commits will land M1–M3.