Use when creating a new project folder, starter pack, app scaffold, or agent-ready workspace — AGENTS.md, README, TASKS, DECISIONS, PROMPTS, an idempotent bootstrap script, and starter-pack modes.
日本語の概要は準備中です。原文の説明を表示しています。
Use when adding, reviewing, or debugging Launch at Login in a macOS app — SMAppService registration, the requiresApproval state, a Settings toggle that reflects reality, and migration off deprecated login-item APIs.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Add Launch at Login with SMAppService (macOS 13+), expose it as an honest Settings toggle, and handle every status the system can return — including the one where the user said no.
Use this skill when the user says:
SMAppServiceSMLoginItemSetEnabled (migration)Do not use this skill for launch daemons or privileged helpers (SMAppService.daemon + launchd plists are a different, root-level topic), or for iOS.
Launch at Login is opt-in, visible in Settings, honest about its
current state, and trivial to turn off. The app never registers
itself without the user asking.
One import, one service, three calls:
import ServiceManagement
// Register (adds the app to System Settings > General > Login Items)
try SMAppService.mainApp.register()
// Unregister
try SMAppService.mainApp.unregister()
// Current truth — always read this, never cache your own flag
SMAppService.mainApp.status
register() takes effect immediately and persists across reboots. No helper bundle, no Library/LaunchAgents plist, no deprecated API.
SMAppService.Status is the part most implementations get wrong. Handle all four:
| Status | Meaning | What your UI shows |
|---|---|---|
.enabled | Registered and allowed | Toggle on |
.notRegistered | Not a login item | Toggle off |
.requiresApproval | Registered, but the user disabled it in System Settings | Toggle off + a "Needs approval in System Settings" hint with a button |
.notFound | System can't find the registration (rare; moved/renamed app) | Toggle off; re-register on next enable |
The killer detail: the user can flip your login item in System Settings > General > Login Items at any time, behind your back. A cached boolean in UserDefaults will lie. Read status every time the Settings view appears and every time the app becomes active.
For .requiresApproval, send the user to the right pane:
SMAppService.openSystemSettingsLoginItems()
import SwiftUI
import ServiceManagement
@MainActor
@Observable
final class LaunchAtLogin {
private(set) var status: SMAppService.Status = .notRegistered
var isEnabled: Bool { status == .enabled }
var needsApproval: Bool { status == .requiresApproval }
init() { refresh() }
func refresh() {
status = SMAppService.mainApp.status
}
func setEnabled(_ enabled: Bool) {
do {
if enabled {
try SMAppService.mainApp.register()
} else {
try SMAppService.mainApp.unregister()
}
} catch {
// Registration can fail (e.g. translocated app run from a DMG).
// Fall through to refresh() so the toggle snaps back to the truth.
}
refresh()
}
}
struct LaunchAtLoginToggle: View {
@State private var model = LaunchAtLogin()
var body: some View {
VStack(alignment: .leading, spacing: 4) {
Toggle("Launch at Login", isOn: Binding(
get: { model.isEnabled },
set: { model.setEnabled($0) }
))
if model.needsApproval {
HStack(spacing: 6) {
Text("Waiting for approval in System Settings.")
.font(.caption)
.foregroundStyle(.secondary)
Button("Open Login Items…") {
SMAppService.openSystemSettingsLoginItems()
}
.buttonStyle(.link)
.font(.caption)
}
}
}
// The user can change this in System Settings while we're not looking.
.onReceive(NotificationCenter.default.publisher(
for: NSApplication.didBecomeActiveNotification)) { _ in
model.refresh()
}
}
}
Notes that keep this correct:
status. If registration failed or needs approval, the toggle reflects that instead of lying.didBecomeActiveNotification so a trip to System Settings and back updates the UI.register() on a translocated build (running straight from a DMG) is expected; the fix is "move the app to /Applications", not a crash.If the app launches at login, it should not shove a window in the user's face at boot.
LSUIElement = YES and don't open a window on launch — nothing else needed. This is the common case (see macos-menubar-swiftui).If the codebase still uses any of these, replace them with SMAppService.mainApp:
SMLoginItemSetEnabled + a separate login-item helper bundle in Contents/Library/LoginItems — delete the helper target entirely.LSSharedFileList (ancient, removed).~/Library/LaunchAgents/*.plist for a GUI app — user-visible, fragile, and now shown with a scary "background item added" notification. Login items belong to SMAppService.There is no data to migrate: on first run of the new version, read SMAppService.mainApp.status and treat it as the truth. Don't try to auto-re-register based on the old preference — that's registering without the user asking.
General
[ ] Launch at Login
Waiting for approval in System Settings. Open Login Items… (only when required)
[ ] Start hidden (windowed apps only)
.requiresApproval state.[ ] Uses SMAppService.mainApp — no helper bundle, no SMLoginItemSetEnabled
[ ] Toggle reads status from the system, not from a cached UserDefaults flag
[ ] All four statuses handled, including .requiresApproval with a
"Open Login Items…" path
[ ] Status refreshes when the app becomes active
[ ] register()/unregister() errors leave the toggle showing the real state
[ ] App never registers itself without an explicit user action
[ ] Launch-at-login start is quiet (no window thrown at the user at boot)
[ ] Turning it off works and survives a relaunch
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when creating a new project folder, starter pack, app scaffold, or agent-ready workspace — AGENTS.md, README, TASKS, DECISIONS, PROMPTS, an idempotent bootstrap script, and starter-pack modes.
日本語の概要は準備中です。原文の説明を表示しています。
Use when designing or implementing states for AI agent tasks, background jobs, local model runs, queues, and notifications — one shared set of states, only legal transitions, and a recovery path out of every failure.
日本語の概要は準備中です。原文の説明を表示しています。
Use when exposing app features to App Intents, Shortcuts, Siri, Spotlight, widgets, controls, or system actions — small safe AppIntents, AppShortcutsProvider, AppEnum/AppEntity, parameters, and open-vs-background behavior.
日本語の概要は準備中です。原文の説明を表示しています。
Use when designing, reviewing, or implementing a command-palette / ⌘K layer for an Apple-platform app — keyboard-first global search, ranked and grouped results, native floating panel, and protected destructive commands.
日本語の概要は準備中です。原文の説明を表示しています。
Use when designing or implementing empty, first-run, no-result, offline, error, or waiting states in Apple-platform apps — every empty state explains what is missing, why it matters, and what to do next.
日本語の概要は準備中です。原文の説明を表示しています。
Use when designing or implementing feedback, status, progress, alerts, errors, success states, and live activity indicators in Apple-platform apps — inline status, banners, alerts, notifications, and loading states.
日本語の概要は準備中です。原文の説明を表示しています。