Skip to content

fix: make launch at login toggle register app - #77

Merged
Peyton-Spencer merged 3 commits into
mainfrom
codex/fix-launch-at-login-toggle
Jul 19, 2026
Merged

fix: make launch at login toggle register app#77
Peyton-Spencer merged 3 commits into
mainfrom
codex/fix-launch-at-login-toggle

Conversation

@Peyton-Spencer

@Peyton-Spencer Peyton-Spencer commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • separate login-item state reconciliation at app startup from user-driven registration
  • ensure enabling Launch at Login calls SMAppService.register() instead of immediately reverting the toggle
  • add regression coverage for register and unregister decisions

Root cause

The settings handler persisted the requested value, then syncLoginItem() immediately treated the old macOS login-item state as authoritative. Enabling the toggle was overwritten back to false before registration could run.

Validation

  • reproduced the installed-app behavior with native macOS UI automation: clicking the disabled toggle left it disabled
  • swift test -Xswiftc -swift-version -Xswiftc 5 --filter 'MacRunnerTests.test(Enabling|Disabling)LaunchAtLogin' (2 passed)\n- full suite: 104 passed; one unrelated environment-sensitive failure in testHomebrewInstallDetectionUsesCellarPaths because this machine has the Homebrew cask installed\n- git diff --check

Summary by CodeRabbit

  • Bug Fixes
    • Improved “Launch at Login” synchronization by separating preference reconciliation from system login-item updates.
    • Avoids unnecessary register/unregister operations when the saved preference already matches the system state.
  • Tests
    • Added unit coverage to confirm correct behavior when enabling/disabling “Launch at Login” under enabled/disabled system states.
    • Updated an update-source detection test to use a controlled file-existence check.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

RunnerManager separates login-item reconciliation from applying login-item changes. ContainerIsolationService updates concurrency isolation and container configuration closure handling. An install-source test now controls file existence explicitly.

Changes

Login item synchronization

Layer / File(s) Summary
Separate reconciliation and synchronization
Sources/Services/RunnerManager.swift, Tests/MacRunnerTests/MacRunnerTests.swift
RunnerManager adds LoginItemAction, reconciles persisted settings with SMAppService during initialization, applies register/unregister actions through syncLoginItem(), and tests both state transitions.

Container service concurrency

Layer / File(s) Summary
Update container isolation and configuration
Sources/Services/ContainerIsolationService.swift
ContainerIsolationService adopts @preconcurrency import handling and @MainActor isolation, passes a separate @Sendable configuration closure to container creation, and leaves nested virtualization reserved for framework support.

Install-source test control

Layer / File(s) Summary
Make install-source detection deterministic
Tests/MacRunnerTests/UpdateCheckerTests.swift
The install-source test injects a fileExists closure returning false while retaining the .directDownload expectation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing Launch at Login so enabling the toggle registers the app.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-launch-at-login-toggle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Peyton-Spencer
Peyton-Spencer marked this pull request as ready for review July 18, 2026 23:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/Services/RunnerManager.swift`:
- Around line 390-392: Update the catch block handling register/unregister
failures in RunnerManager so currentSettings.startOnLogin is reverted to its
prior value and the configuration is saved before recording the error. Preserve
the existing error message while ensuring the UI and persisted settings reflect
the OS state after failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe22f397-2de7-470d-9cd2-63b05968f54e

📥 Commits

Reviewing files that changed from the base of the PR and between 0125355 and ab7d18c.

📒 Files selected for processing (2)
  • Sources/Services/RunnerManager.swift
  • Tests/MacRunnerTests/MacRunnerTests.swift

Comment thread Sources/Services/RunnerManager.swift
@Peyton-Spencer
Peyton-Spencer merged commit b576f47 into main Jul 19, 2026
1 of 2 checks passed
@Peyton-Spencer
Peyton-Spencer deleted the codex/fix-launch-at-login-toggle branch July 19, 2026 02:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/Services/ContainerIsolationService.swift (1)

135-135: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Prevent shell command injection.

Interpolating unescaped variables directly into a shell script makes the script vulnerable to command injection and syntax errors if the variables contain spaces or shell metacharacters.
Wrap the interpolated variables in single quotes to ensure they are treated as literal strings.

🛡️ Proposed fix
-                ./config.sh --unattended --url \(config.repositoryURL) --token \(config.registrationToken)
+                ./config.sh --unattended --url '\(config.repositoryURL)' --token '\(config.registrationToken)'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Services/ContainerIsolationService.swift` at line 135, Update the
command construction in ContainerIsolationService to single-quote the
interpolated config.repositoryURL and config.registrationToken arguments passed
to ./config.sh, ensuring values with spaces or shell metacharacters remain
literal and cannot alter shell execution.
🧹 Nitpick comments (1)
Sources/Services/ContainerIsolationService.swift (1)

145-147: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove empty conditional block.

The if config.enableNestedVirtualization block is empty. If nested virtualization is intentionally unsupported at the moment, consider replacing this with a TODO comment or removing the block entirely to avoid linter warnings for empty statements.

♻️ Proposed fix
-            if config.enableNestedVirtualization {
-                // Reserved for framework support.
-            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Services/ContainerIsolationService.swift` around lines 145 - 147,
Remove the empty config.enableNestedVirtualization conditional block in the
surrounding isolation-service logic; if the unsupported setting must remain
documented, replace it with a concise TODO comment without retaining an empty
statement.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/Services/ContainerIsolationService.swift`:
- Around line 151-157: Serialize concurrent createRunnerContainer operations so
reentrant calls cannot capture and later overwrite stale containerManager state.
Update the container creation flow around manager and the awaited manager.create
call, using an asynchronous queue or equivalent guard, and preserve all manager
mutations from earlier creations.

---

Outside diff comments:
In `@Sources/Services/ContainerIsolationService.swift`:
- Line 135: Update the command construction in ContainerIsolationService to
single-quote the interpolated config.repositoryURL and config.registrationToken
arguments passed to ./config.sh, ensuring values with spaces or shell
metacharacters remain literal and cannot alter shell execution.

---

Nitpick comments:
In `@Sources/Services/ContainerIsolationService.swift`:
- Around line 145-147: Remove the empty config.enableNestedVirtualization
conditional block in the surrounding isolation-service logic; if the unsupported
setting must remain documented, replace it with a concise TODO comment without
retaining an empty statement.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b93ae38d-d643-4d60-aeb2-d1e563a62148

📥 Commits

Reviewing files that changed from the base of the PR and between ab7d18c and a96c807.

📒 Files selected for processing (3)
  • Sources/Services/ContainerIsolationService.swift
  • Sources/Services/RunnerManager.swift
  • Tests/MacRunnerTests/UpdateCheckerTests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • Sources/Services/RunnerManager.swift

Comment on lines +151 to +157
let container = try await manager.create(
id,
reference: imageReference,
rootfsSizeInBytes: config.diskSizeInBytes,
configuration: configuration
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | 🏗️ Heavy lift

Reentrancy hazard causing a lost update on containerManager.

Because ContainerIsolationService is a reentrant @MainActor class, reading containerManager into a local manager variable before an await and reassigning self.containerManager = manager afterward (on line 159) creates a Time-Of-Check to Time-Of-Use (TOCTOU) race condition.

If createRunnerContainer is called concurrently (e.g., when launching multiple runners), the concurrent tasks will capture the same initial containerManager state. When they resume from suspension, the later task will blindly overwrite self.containerManager, destroying the internal state (such as tracked containers or resource allocations) mutated by the earlier task.

Consider ensuring that calls to createRunnerContainer are strictly serialized to prevent reentrancy (e.g., using an asynchronous task queue or an isCreating guard), or use a reference-type manager if the Containerization framework supports it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Services/ContainerIsolationService.swift` around lines 151 - 157,
Serialize concurrent createRunnerContainer operations so reentrant calls cannot
capture and later overwrite stale containerManager state. Update the container
creation flow around manager and the awaited manager.create call, using an
asynchronous queue or equivalent guard, and preserve all manager mutations from
earlier creations.

github-actions Bot pushed a commit that referenced this pull request Jul 19, 2026
## [1.17.4](v1.17.3...v1.17.4) (2026-07-19)

### Bug Fixes

* make launch at login toggle register app ([#77](#77)) ([b576f47](b576f47))
* refresh stale runner PATH snapshots ([0125355](0125355))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.17.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant