Skip to content

Phase 2.5: extract LaunchAtLoginService protocol seam - #45

Merged
initcore0 merged 1 commit into
mainfrom
feat/core-launchatlogin
Jun 23, 2026
Merged

Phase 2.5: extract LaunchAtLoginService protocol seam#45
initcore0 merged 1 commit into
mainfrom
feat/core-launchatlogin

Conversation

@initcore0

Copy link
Copy Markdown
Owner

Second platform seam (after SecretStore, #44). AppState referenced the concrete LaunchAtLogin at four sites and SettingsView at two; this puts it behind a protocol and extracts the decision logic.

Changes

  • LaunchAtLoginService protocol (isEnabled / requiresApproval / setEnabled / openSettings). LaunchAtLogin: enum of statics → final class conforming to it. The Apple-only ServiceManagement/AppKit calls stay isolated there.
  • LaunchAtLoginReconciler — the branchy toggle re-sync (reconcile what was applied vs. the real system state, decide whether to show the approval message) moved out of the didSet into a pure, Foundation-only type in OpenWhispCore, so the actual decision is unit-tested.
  • AppState injects launchAtLoginService via init(… = LaunchAtLogin()); the didSet and init read route through it. SettingsView routes through appState.launchAtLoginService. No behavior change on macOS.
  • Tests: +6 LaunchAtLoginReconcilerTests (success, blocked-needing-approval, applied-failed, diverged+approval, no-nag-when-already-matched). 98 → 104.
  • ROADMAP: marked done under Phase 2.5.

swift test 104/104 · ./build.sh clean.

🤖 Generated with Claude Code

Second platform seam (after SecretStore). AppState referenced the concrete
LaunchAtLogin (SMAppService wrapper) at four sites, and SettingsView at two.

- LaunchAtLoginService protocol (isEnabled / requiresApproval / setEnabled /
  openSettings). LaunchAtLogin: enum-of-statics -> final class conforming to it;
  the Apple-only ServiceManagement/AppKit calls stay isolated there.
- The branchy toggle re-sync (reconcile applied vs. real system state, decide
  whether to surface the approval message) moved out of the didSet into a pure,
  Foundation-only LaunchAtLoginReconciler in OpenWhispCore, so the actual decision
  logic is unit-tested.
- AppState injects launchAtLoginService via init(... = LaunchAtLogin()); didSet
  and the init read route through it. SettingsView routes through
  appState.launchAtLoginService. Behavior unchanged on macOS.
- Tests: +6 LaunchAtLoginReconcilerTests (success, blocked-needing-approval,
  applied-failed, diverged+approval, no-nag-when-matched). 98 -> 104.
- ROADMAP: mark LaunchAtLoginService done under Phase 2.5.

swift test 104/104; ./build.sh clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@initcore0
initcore0 merged commit acec89f into main Jun 23, 2026
3 checks passed
@initcore0
initcore0 deleted the feat/core-launchatlogin branch June 23, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant