Skip to content

Add launch-at-login via tauri-plugin-autostart - #22

Merged
cohogan merged 3 commits into
mainfrom
f/autostart
Jul 20, 2026
Merged

Add launch-at-login via tauri-plugin-autostart#22
cohogan merged 3 commits into
mainfrom
f/autostart

Conversation

@cohogan

@cohogan cohogan commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds the tauri-plugin-autostart plugin (LaunchAgent on macOS, HKCU\...\Run key on Windows, .desktop entry on Linux) with autostart:default granted in the desktop capability
  • Adds a Launch at Login toggle to the settings sheet: reads the OS state when the sheet opens, applies enable/disable on Save
  • Adds src-tauri/tests/autostart.rs, the first Rust integration test in the repo: round-trips enable()/disable() and independently asserts the Windows Run registry entry is created and removed
  • build.rs: embeds the Common Controls v6 manifest into test binaries only so cargo test does not crash with STATUS_ENTRYPOINT_NOT_FOUND on Windows (known issue, see tauri-apps discussion #11179); the app build is unchanged

Testing

  • cargo test --test autostart passes: enable → is_enabled() true and reg query shows the Run entry → disable → entry gone
  • Verified live in the running dev app over real Tauri IPC (via WebView2 remote debugging): plugin:autostart|enable / is_enabled / disable all succeed from the main window, and HKCU\Software\Microsoft\Windows\CurrentVersion\Run gained/lost the Labric Sync entry accordingly — confirming plugin registration and capability permissions end to end
  • cargo clippy clean, pnpm build (tsc + vite) passes
  • Not covered: clicking the toggle itself in a paired/logged-in app (the settings sheet lives behind auth); the switch calls the same plugin functions verified above

Notes

  • In dev, enabling registers the dev binary path; packaged builds register the installed exe
  • Follow-up idea: pass a --minimized launch arg and start hidden in the tray when launched at login

🤖 Generated with Claude Code

- Register autostart plugin (LaunchAgent on macOS, HKCU Run key on
  Windows) and grant autostart:default in the desktop capability
- Add a Launch at Login toggle to the settings sheet that reads the OS
  state on open and applies enable/disable on save
- Add an integration test that round-trips enable/disable and asserts
  the Windows Run registry entry is created and removed
- Embed the Common Controls v6 manifest into test binaries so cargo
  test does not crash with STATUS_ENTRYPOINT_NOT_FOUND on Windows
  (tauri-apps/tauri discussion #11179)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Claude finished @cohogan's task in 1m 46s —— View job


Code Review: Add launch-at-login via tauri-plugin-autostart

  • Read all changed files
  • Review Rust backend changes
  • Review frontend changes
  • Review test and build changes
  • Post review findings

Overall this is a clean, well-structured PR that follows the existing patterns in the codebase. The plugin wiring, capability grant, test, and UI toggle are all done correctly. A few observations below.


Findings

1. Partial save if autostart toggle failssrc/components/UploadSettingsDialog.tsx:112-119

handleSave calls updateConfig() first (which persists the upload settings), then calls enableAutostart()/disableAutostart(). If the autostart call throws, the catch block shows "Failed to save settings" — but the upload config has already been committed. The user sees an error toast, but their upload settings did change. A retry of Save would fix it (the upload config update is idempotent), so this is low-severity but worth noting.

A simple fix would be to swap the order (autostart first, then upload config) or to handle the autostart error independently:

// Option A: independent error handling
try {
  if (launchAtLogin) await enableAutostart();
  else await disableAutostart();
} catch (err) {
  console.error("Failed to toggle autostart:", err);
  toast.error("Failed to update launch-at-login setting");
}

Fix this →

2. Unconditional enable/disable on every savesrc/components/UploadSettingsDialog.tsx:115-119

handleSave always calls enableAutostart() or disableAutostart() even when the toggle hasn't changed. These calls are idempotent so this is harmless, but you could compare against the OS state read on open to skip the unnecessary IPC round-trip.

3. Missing trailing newlinesrc-tauri/capabilities/desktop.json

The diff shows \ No newline at end of file. Minor style nit — most editors and linters prefer a trailing newline.

4. Test cleanup on panicsrc-tauri/tests/autostart.rs:19-49

If the test panics between enable() (line 19) and disable() (line 45), the autostart entry is left on the test machine. Since it points at the test binary (which gets cleaned up by cargo), this is harmless in practice — just something to be aware of if this test ever runs in a shared CI environment.


What looks good

  • Plugin registration (lib.rs:434-437): Correctly uses MacosLauncher::LaunchAgent and matches the pattern of other plugins. Placed under the same cfg(not(mobile)) conditional in Cargo.toml as tauri-plugin-updater.
  • build.rs workaround (lines 14-23): Well-scoped to test binaries only via rustc-link-arg-tests, with a clear explanation and upstream issue link. Doesn't affect the app build.
  • Test (autostart.rs): Clean round-trip structure using the Tauri mock builder. The Windows-specific reg query assertion is a nice touch for verifying OS-level side effects.
  • UI toggle: Reads OS state on sheet open (not stale React state), follows the same Field + Switch pattern as the other toggles.
  • Capability: autostart:default correctly added to the desktop capability file.

Verdict: Looks good to merge. Finding #1 (partial save) is the only one I'd consider addressing before merge, but it's low-risk given that autostart calls rarely fail and a retry resolves it.

Address review: a failure in enable()/disable() no longer masks the
already-persisted upload config save; it now shows its own error toast.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 20, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @cohogan's task in 2m 2s —— View job


Code Review: Add launch-at-login via tauri-plugin-autostart

  • Read all changed files
  • Review Rust backend changes
  • Review frontend changes
  • Review test and build changes
  • Post review findings

This is a clean, well-structured PR. The second commit (3b3ce68) already addressed the main finding from the previous review by giving the autostart toggle its own try-catch. The changes are minimal and follow existing patterns throughout.


Findings

1. Missing trailing newlinesrc-tauri/capabilities/desktop.json

The file ends without a trailing newline. Most editors and linters expect one (POSIX convention), and git marks it with \ No newline at end of file. Minor style nit.

Fix this →

2. Unconditional enable/disable on every savesrc/components/UploadSettingsDialog.tsx:115-123

handleSave always calls enableAutostart() or disableAutostart() even when the toggle value hasn't changed from the OS state read on open. These calls are idempotent so it's harmless, but you could compare launchAtLogin against the value read on open to skip the unnecessary IPC round-trip:

const [initialLaunchAtLogin, setInitialLaunchAtLogin] = useState(false);
// in the useEffect:
isAutostartEnabled().then((v) => { setLaunchAtLogin(v); setInitialLaunchAtLogin(v); });
// in handleSave:
if (launchAtLogin !== initialLaunchAtLogin) { ... }

This is low-priority — the current code works correctly.

3. Test cleanup on panicsrc-tauri/tests/autostart.rs:19-45

If the test panics between enable() (line 19) and disable() (line 45), the autostart entry is left on the test machine. Since it points at a transient test binary, this is harmless in practice. If it ever matters (shared CI), a Drop guard or std::panic::catch_unwind wrapper could clean up.


What looks good

  • Independent autostart error handling (UploadSettingsDialog.tsx:115-124): The second commit cleanly separates autostart failures from upload config saves — autostart errors get their own toast and don't mask the fact that upload settings were saved successfully. This directly addresses the main concern from the first review.
  • Plugin registration (lib.rs:434-437): Correctly uses MacosLauncher::LaunchAgent and follows the same pattern as the other plugins. Placed under the same cfg(not(mobile)) conditional in Cargo.toml as tauri-plugin-updater.
  • build.rs workaround (lines 14-23): Well-scoped to test binaries only via rustc-link-arg-tests, with a clear explanation and upstream issue link. Doesn't affect the app build.
  • Test (autostart.rs): Clean round-trip structure using the Tauri mock builder. The Windows-specific reg query assertion is a nice touch for verifying OS-level side effects beyond the plugin's own is_enabled().
  • UI toggle: Reads the actual OS state on sheet open (not stale React state), and follows the same Field + Switch pattern as the existing toggles.
  • Capability: autostart:default correctly added to the desktop capability file.
  • Frontend dep (package.json): @tauri-apps/plugin-autostart version is consistent with the other @tauri-apps/plugin-* versions.

Verdict: Looks good to merge. All three findings are low-severity style/optimization nits — none are blockers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @cohogan's task in 1m 59s —— View job


Code Review: Add launch-at-login via tauri-plugin-autostart

  • Read all changed files
  • Review Rust backend changes
  • Review frontend changes
  • Review test and build changes
  • Post review findings

This is a clean, well-structured PR. The second commit (3b3ce68) already addressed the main finding from the first review round (partial save on autostart failure). The plugin wiring, capability grant, test, and UI toggle all follow existing patterns correctly.


Findings

1. Missing trailing newlinesrc-tauri/capabilities/desktop.json

The diff shows \ No newline at end of file. POSIX convention and most editors/linters expect a trailing newline.

Fix this →

2. Unconditional enable/disable on every savesrc/components/UploadSettingsDialog.tsx:115-124

handleSave always calls enableAutostart() or disableAutostart() regardless of whether the toggle value changed. These calls are idempotent so it's harmless, but you could track the initial value from the OS read and skip the IPC round-trip when unchanged:

const [initialLaunchAtLogin, setInitialLaunchAtLogin] = useState(false);
// in the useEffect:
isAutostartEnabled().then((v) => { setLaunchAtLogin(v); setInitialLaunchAtLogin(v); });
// in handleSave, only call if changed:
if (launchAtLogin !== initialLaunchAtLogin) { ... }

Low priority — current code works correctly.

3. Silent fallback could inadvertently disable autostartsrc/components/UploadSettingsDialog.tsx:62-64

If isAutostartEnabled() rejects when the sheet opens, launchAtLogin stays at its initial false. If the user then saves without touching the toggle, disableAutostart() fires and disables a previously-enabled autostart entry. In practice isAutostartEnabled() is a trivial OS API call unlikely to fail, and if it did, disableAutostart() would likely also fail — so this is self-correcting. Still, worth being aware of.

4. Test cleanup on panicsrc-tauri/tests/autostart.rs:19-45

If the test panics between enable() (line 19) and disable() (line 45), the autostart entry is left on the machine. Since it points at a transient test binary, this is harmless in practice. A Drop guard or std::panic::catch_unwind wrapper could clean up if this test ever runs in shared CI.


What looks good

  • Independent autostart error handling (UploadSettingsDialog.tsx:115-124): The second commit cleanly separates autostart failures from upload config saves — autostart errors get their own toast and don't mask the successful config save. Good fix.
  • Plugin registration (lib.rs:434-437): MacosLauncher::LaunchAgent is the correct per-user choice. Follows the same unconditional pattern as tauri-plugin-updater in the builder chain, consistent with both being behind cfg(not(mobile)) in Cargo.toml.
  • build.rs workaround (lines 14-23): Well-scoped to test binaries only via rustc-link-arg-tests. Clear comment with upstream issue link. App build is completely unaffected.
  • Test (autostart.rs): Clean round-trip structure using Tauri's mock builder. The Windows-specific reg query assertion verifying the actual OS side-effect beyond is_enabled() is a nice touch.
  • UI toggle (UploadSettingsDialog.tsx:193-203): Reads actual OS state on sheet open (not stale React state), follows the same Field + Switch pattern as the existing toggles.
  • Capability & deps: autostart:default correctly added to desktop capability. Frontend/Rust dependency versions are consistent with the other @tauri-apps/plugin-* packages.

Verdict: Looks good to merge. All findings are low-severity — none are blockers.

@cohogan
cohogan merged commit f9c0b29 into main Jul 20, 2026
1 check passed
@cohogan
cohogan deleted the f/autostart branch July 20, 2026 18:34
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