Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Sources/removemacai/App/Pages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,16 @@ struct BackgroundView: View {
Text(item.label).font(.caption.monospaced()).foregroundStyle(.secondary)
Text(item.program).font(.caption2.monospaced()).foregroundStyle(.tertiary)
.lineLimit(1).truncationMode(.middle)
if let warning = item.warning {
Label(warning, systemImage: "exclamationmark.triangle").font(.caption).foregroundStyle(.orange)
}
}
}
.toggleStyle(.switch)
.disabled(model.backgroundBusy)
}
} header: {
Text("Updaters, helpers and agents other apps installed. They run whether or not their app is open. Switching one off takes effect at once.")
Text("Updaters, helpers and agents other apps installed. They run whether or not their app is open. Switching one off takes effect at once. Updaters are safe to switch off; a helper can be what makes its app work, such as a VPN or Docker.")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
.font(.body).foregroundStyle(.secondary).textCase(nil)
} footer: {
Footer("Items marked All users ask for your password. Apple's own background services are protected by System Integrity Protection, so RemoveMacAI leaves them alone.")
Expand Down
12 changes: 12 additions & 0 deletions Sources/removemacai/BackgroundItems.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ struct BackgroundItem: Identifiable, Hashable {

static let interpreters: Set<String> = ["sh", "bash", "zsh", "python3", "python", "node", "osascript", "perl", "ruby"]

/// Whether it only keeps its app up to date, judged by its label and the
/// name of what it runs. Anything else (a VPN, Docker's socket, a sync or
/// licensing helper) can be what makes its app work, so it gets a warning.
var isUpdater: Bool {
[label, (program as NSString).lastPathComponent].contains { $0.lowercased().contains("update") }
}

/// What switching it off can break, or nil for an updater.
var warning: String? {
isUpdater ? nil : "Not an updater. Turning it off can stop \(owner) working."
}

/// The app or program it runs, as people know it.
var owner: String {
if let app = program.split(separator: "/").first(where: { $0.hasSuffix(".app") }) {
Expand Down
9 changes: 9 additions & 0 deletions Sources/removemacai/SelfTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ func selfTest() -> Bool {
program: "/Library/PrivilegedHelperTools/dev.orbstack.OrbStack.privhelper", system: true)
check(script.owner == "sync.sh" && helper.owner == "OrbStack", "background items are named after what they run")

let updater = BackgroundItem(label: "com.google.GoogleUpdater.wake", plist: "",
program: "/Users/x/Library/Application Support/Google/GoogleUpdater/Current/GoogleUpdater.app/Contents/MacOS/GoogleUpdater",
system: false)
check(updater.isUpdater && updater.warning == nil && !helper.isUpdater && helper.warning != nil,
"helpers that aren't updaters carry a warning")
let vpn = BackgroundItem(label: "com.example.vpn", plist: "", program: "/Library/Example Updates/vpnd",
arguments: ["/Library/Example Updates/vpnd", "--check-updates"], system: true)
check(!vpn.isUpdater && vpn.warning != nil, "an unrelated mention of updates keeps the warning")

print(failed == 0 ? Term.green("all checks passed") : Term.red("\(failed) failed"))
return failed == 0
}
11 changes: 9 additions & 2 deletions Sources/removemacai/TweakCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ enum TweakCommands {
}
print(Term.bold("Background items from other apps"))
for item in items {
let state = BackgroundItems.isDisabled(item, labels) ? Term.dim("off") : Term.green("on")
print(" " + Term.pad(item.label, 48) + Term.pad(item.owner, 22) + state + (item.system ? Term.dim(" (all users)") : ""))
let off = BackgroundItems.isDisabled(item, labels)
let state = off ? Term.dim(Term.pad("off", 5)) : Term.green(Term.pad("on", 5))
let kind = item.isUpdater ? Term.dim("updater") : Term.yellow("helper")
print(" " + Term.pad(item.label, 48) + Term.pad(item.owner, 22) + state + kind
+ (item.system ? Term.dim(" (all users)") : ""))
}
print()
print(Term.dim("Turning off a helper can stop its app working, for example a VPN or Docker."))
print(Term.dim("Turn one off with: removemacai background off <label>"))
return true
}
Expand All @@ -155,6 +159,9 @@ enum TweakCommands {
Term.fail("there is no background item called \"\(name)\"")
}
guard !chosen.isEmpty else { Term.fail("name the items, as listed by: removemacai background") }
if action == "off" {
for item in chosen { if let warning = item.warning { print(Term.yellow("!") + " \(item.label): " + warning) } }
}
if !yes {
guard isatty(STDIN_FILENO) == 1 else { Term.fail("run it in a terminal, or add --yes") }
let verb = action == "off" ? "Turn off" : "Turn on"
Expand Down