From 65df8980cd868f6eed4c949877062e76d87c7d23 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 26 Oct 2026 19:06:08 +0000 Subject: [PATCH 1/4] Export an iPhone and iPad profile that turns Apple Intelligence off The Mac tool can write a configuration profile for iOS and iPadOS with the restriction keys Apple documents for those systems. Model deletion stays on the Mac. Co-authored-by: MrTiptop --- Sources/removemacai/Mobile.swift | 115 ++++++++++++++++++++++++ Sources/removemacai/SelfTest.swift | 34 +++++++ Sources/removemacai/TweakCommands.swift | 40 ++++++++- Sources/removemacai/main.swift | 13 ++- 4 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 Sources/removemacai/Mobile.swift diff --git a/Sources/removemacai/Mobile.swift b/Sources/removemacai/Mobile.swift new file mode 100644 index 0000000..88b0cf1 --- /dev/null +++ b/Sources/removemacai/Mobile.swift @@ -0,0 +1,115 @@ +// MrTiptop +import Foundation + +/// A configuration profile that turns Apple Intelligence off on an iPhone or +/// iPad. It uses the same restriction keys as the Mac profile where Apple +/// documents them for iOS and iPadOS. Forced preferences and model deletion +/// stay on the Mac: iOS and iPadOS do not let a profile delete the models. +enum Mobile { + enum Device: String { + case iPhone + case iPad + + /// `ios` is the iPhone profile. `ipados` is the iPad profile. + init?(argument: String) { + switch argument.lowercased() { + case "iphone", "ios": self = .iPhone + case "ipad", "ipados": self = .iPad + default: return nil + } + } + + var profileIdentifier: String { "io.github.omlahore.removemacai.\(rawValue.lowercased())" } + var systemName: String { self == .iPhone ? "iOS" : "iPadOS" } + } + + /// One Apple Intelligence feature a profile can switch off. + /// `supervised` is Apple's rule: the device has to be supervised or the + /// switch is ignored. Siri and the ChatGPT extension do not need that. + struct Feature { + let id: String + let title: String + let restrictions: [String] + let supervised: Bool + /// Visual Intelligence is an iPhone camera feature. iPadOS has no switch. + let iPhoneOnly: Bool + } + + static let features: [Feature] = [ + Feature( + id: "siri", title: "Siri and Siri AI", + restrictions: ["allowAssistant", "allowSiriAI"], supervised: false, iPhoneOnly: false), + Feature( + id: "chatgpt", title: "ChatGPT and other AI extensions", + restrictions: [ + "allowExternalIntelligenceIntegrations", "allowExternalIntelligenceIntegrationsSignIn", + ], supervised: false, iPhoneOnly: false), + Feature( + id: "writing-tools", title: "Writing Tools", + restrictions: ["allowWritingTools"], supervised: true, iPhoneOnly: false), + Feature( + id: "genmoji", title: "Genmoji", + restrictions: ["allowGenmoji"], supervised: true, iPhoneOnly: false), + Feature( + id: "image-playground", title: "Image Playground", + restrictions: ["allowImagePlayground"], supervised: true, iPhoneOnly: false), + Feature( + id: "image-wand", title: "Image Wand", + restrictions: ["allowImageWand"], supervised: true, iPhoneOnly: false), + Feature( + id: "mail", title: "Mail summaries and smart replies", + restrictions: ["allowMailSummary", "allowMailSmartReplies"], supervised: true, iPhoneOnly: false), + Feature( + id: "safari-summaries", title: "Safari summaries", + restrictions: ["allowSafariSummary"], supervised: true, iPhoneOnly: false), + Feature( + id: "notes-summaries", title: "Notes transcription summaries", + restrictions: ["allowNotesTranscriptionSummary"], supervised: true, iPhoneOnly: false), + Feature( + id: "visual-intelligence", title: "Visual Intelligence", + restrictions: ["allowVisualIntelligenceSummary"], supervised: true, iPhoneOnly: true), + ] + + static func feature(_ id: String) -> Feature? { features.first { $0.id == id } } + + static func features(for device: Device) -> [Feature] { + features.filter { !$0.iPhoneOnly || device == .iPhone } + } + + /// The profile for `device`, with every feature off except `kept`. + static func data(keeping kept: Set, device: Device) throws -> Data { + var restrictions = payload(device: device) + for feature in features(for: device) where !kept.contains(feature.id) { + for key in feature.restrictions { restrictions[key] = false } + } + let supervised = features(for: device).filter(\.supervised).map(\.title).joined(separator: ", ") + let description = """ + Turns off Apple Intelligence on this \(device.rawValue). Remove the profile and the switches come back. \ + \(device.systemName) does not let a profile delete the model files. \ + Siri and ChatGPT extensions apply on any device. \(supervised) apply on a supervised device. Shared iPad ignores them. + """ + let profile: [String: Any] = [ + "PayloadType": "Configuration", + "PayloadVersion": 1, + "PayloadIdentifier": device.profileIdentifier, + "PayloadUUID": Profile.uuid(device.profileIdentifier), + "PayloadDisplayName": "RemoveMacAI", + "PayloadDescription": description, + "PayloadOrganization": "RemoveMacAI", + "PayloadRemovalDisallowed": false, + "PayloadContent": [restrictions], + ] + return try PropertyListSerialization.data(fromPropertyList: profile, format: .xml, options: 0) + } + + private static func payload(device: Device) -> [String: Any] { + let id = device.profileIdentifier + ".restrictions" + return [ + "PayloadType": "com.apple.applicationaccess", + "PayloadVersion": 1, + "PayloadIdentifier": id, + "PayloadUUID": Profile.uuid(id), + "PayloadDisplayName": "Apple Intelligence", + ] + } +} diff --git a/Sources/removemacai/SelfTest.swift b/Sources/removemacai/SelfTest.swift index 3d3073d..de01a39 100644 --- a/Sources/removemacai/SelfTest.swift +++ b/Sources/removemacai/SelfTest.swift @@ -224,6 +224,40 @@ func selfTest() -> Bool { } catch { check(false, "the profile builds: \(error)") } + + do { + check(Mobile.Device(argument: "ios") == .iPhone && Mobile.Device(argument: "ipados") == .iPad + && Mobile.Device(argument: "phone") == nil, + "iphone and ipad profile targets accept the OS names") + check(Set(Mobile.features.map(\.id)).count == Mobile.features.count, "iPhone and iPad feature names are unique") + let phone = try PropertyListSerialization.propertyList(from: Mobile.data(keeping: [], device: .iPhone), format: nil) as! [String: Any] + let pad = try PropertyListSerialization.propertyList(from: Mobile.data(keeping: ["writing-tools"], device: .iPad), format: nil) as! [String: Any] + check(phone["PayloadScope"] == nil && pad["PayloadScope"] == nil + && phone["PayloadRemovalDisallowed"] as? Bool == false, + "an iPhone or iPad profile is removable and is not a Mac system profile") + let phonePayloads = phone["PayloadContent"] as! [[String: Any]] + let padPayloads = pad["PayloadContent"] as! [[String: Any]] + let phoneRestrictions = phonePayloads[0] + let padRestrictions = padPayloads[0] + check(phonePayloads.count == 1 && phonePayloads[0]["PayloadType"] as? String == "com.apple.applicationaccess" + && padPayloads.count == 1, + "an iPhone profile carries restrictions only, with no Mac preference payloads") + check(phoneRestrictions["allowWritingTools"] as? Bool == false + && phoneRestrictions["allowAssistant"] as? Bool == false + && phoneRestrictions["allowSiriAI"] as? Bool == false + && phoneRestrictions["allowImageWand"] as? Bool == false + && phoneRestrictions["allowVisualIntelligenceSummary"] as? Bool == false + && phoneRestrictions["allowDiagnosticSubmission"] == nil, + "an iPhone profile turns Writing Tools, Siri, Image Wand, and Visual Intelligence off") + check(padRestrictions["allowWritingTools"] == nil + && padRestrictions["allowGenmoji"] as? Bool == false + && padRestrictions["allowImageWand"] as? Bool == false + && padRestrictions["allowExternalIntelligenceIntegrations"] as? Bool == false + && padRestrictions["allowVisualIntelligenceSummary"] == nil, + "a kept iPad feature is left alone and iPad has no Visual Intelligence switch") + } catch { + check(false, "the iPhone and iPad profiles build: \(error)") + } // The debloater catalog. check(Set(Tweaks.all.map(\.id)).count == Tweaks.all.count, "tweak names are unique") let changeKeys = Tweaks.all.flatMap { $0.changes.map(\.key) } diff --git a/Sources/removemacai/TweakCommands.swift b/Sources/removemacai/TweakCommands.swift index ca592bf..92748c1 100644 --- a/Sources/removemacai/TweakCommands.swift +++ b/Sources/removemacai/TweakCommands.swift @@ -236,7 +236,12 @@ enum TweakCommands { // MARK: export /// Writes the profile for a preset or named tweaks, for deploying with an MDM. - static func export(path: String, ids: [String], preset: Preset?, keepAI: Set, noAI: Bool) { + /// `device` writes an iPhone or iPad profile that only turns Apple Intelligence off. + static func export(path: String, ids: [String], preset: Preset?, keepAI: Set, noAI: Bool, device: Mobile.Device? = nil) { + if let device { + exportMobile(path: path, device: device, ids: ids, preset: preset, keepAI: keepAI, noAI: noAI) + return + } var tweaks = Set() for id in ids { guard let t = Tweaks.tweak(id) else { Term.fail("there is no tweak called \"\(id)\"") } @@ -253,4 +258,37 @@ enum TweakCommands { print(Term.dim(" Tweaks: \(tweaks.isEmpty ? "none" : tweaks.sorted().joined(separator: ", "))")) print(Term.dim(" Per-user tweaks (Finder, Dock, typing) aren't in profiles; run removemacai on each Mac for those.")) } + + /// An iPhone or iPad profile. Tweaks and model deletion are Mac-only. + private static func exportMobile(path: String, device: Mobile.Device, ids: [String], preset: Preset?, keepAI: Set, noAI: Bool) { + if !ids.isEmpty || preset != nil { + Term.fail("an \(device.rawValue) profile only turns Apple Intelligence off. Leave out tweak names and --preset") + } + if noAI { Term.fail("--no-ai leaves Apple Intelligence alone, so an \(device.rawValue) profile would be empty") } + let names = Mobile.features(for: device).map(\.id).joined(separator: ", ") + for id in keepAI.sorted() { + guard let feature = Mobile.feature(id) else { + Term.fail("there is no \(device.rawValue) feature called \"\(id)\". Names: \(names)") + } + if feature.iPhoneOnly && device != .iPhone { + Term.fail("\(feature.title) is an iPhone feature. Leave it out of --keep on an iPad") + } + } + let off = Mobile.features(for: device).filter { !keepAI.contains($0.id) } + guard !off.isEmpty else { Term.fail("nothing would be turned off. Leave a feature out of --keep") } + do { + try Mobile.data(keeping: keepAI, device: device).write(to: URL(fileURLWithPath: path)) + } catch { Term.fail("could not write \(path): \(error)") } + print(Term.green("✓") + " Wrote \(path) for \(device.rawValue) (\(device.systemName))") + print(Term.dim(" Off: \(off.map(\.title).joined(separator: ", "))")) + if !keepAI.isEmpty { print(Term.dim(" Kept on: \(keepAI.sorted().joined(separator: ", "))")) } + let supervised = off.filter(\.supervised).map(\.title) + if !supervised.isEmpty { + print(Term.dim(" A supervised \(device.rawValue) honors: \(supervised.joined(separator: ", ")). An unsupervised one ignores those.")) + } + print(Term.dim(" Siri and ChatGPT extensions apply without supervision.")) + print(Term.dim(" \(device.systemName) keeps the model files. Removing the profile turns the switches back on.")) + print(Term.dim(" Shared iPad ignores the supervised switches.")) + print(Term.dim(" Install it from Settings > General > VPN & Device Management.")) + } } diff --git a/Sources/removemacai/main.swift b/Sources/removemacai/main.swift index 6c44bd3..44e572a 100644 --- a/Sources/removemacai/main.swift +++ b/Sources/removemacai/main.swift @@ -26,6 +26,8 @@ let usage = """ removemacai clean [] show space to get back, move some to the Trash removemacai export [--preset p] [] [--keep a,b] [--no-ai] write the profile for an MDM + --for iphone|ipad write an iPhone (ios) or iPad (ipados) profile instead. + It turns Apple Intelligence off. Models stay on the device. removemacai revert undo everything RemoveMacAI changed removemacai app open the RemoveMacAI app @@ -80,6 +82,14 @@ func unknownCommandMessage(_ name: String) -> String { if let hint = suggestCommand(for: name) { message += ". Did you mean \"\(hint)\"?" } return message } +func mobileDeviceOption() -> Mobile.Device? { + guard let name = option("--for") else { return nil } + guard let device = Mobile.Device(argument: name) else { + Term.fail("unknown device \"\(name)\". Use iphone, ios, ipad, or ipados") + } + return device +} + func presetOption() -> Preset? { guard let name = option("--preset") else { return nil } guard let preset = Preset(rawValue: name) else { @@ -159,9 +169,10 @@ case "export": let preset = presetOption() let keep = Set((option("--keep") ?? "").split(separator: ",").map { String($0).trimmed }.filter { !$0.isEmpty }) let noAI = flag("--no-ai") + let device = mobileDeviceOption() if let bad = unknownOption(in: args) { Term.fail("unknown option \(bad)") } guard let path = args.first else { Term.fail("name the file to write, for example: removemacai export RemoveMacAI.mobileconfig") } - TweakCommands.export(path: path, ids: Array(args.dropFirst()), preset: preset, keepAI: keep, noAI: noAI) + TweakCommands.export(path: path, ids: Array(args.dropFirst()), preset: preset, keepAI: keep, noAI: noAI, device: device) case "selftest": exit(selfTest() ? 0 : 1) case "--version", "-v", "version": From 1fd664d49caae6b0e3dd7ab1790382fa8369a876 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 26 Oct 2026 21:26:26 +0000 Subject: [PATCH 2/4] Drop the name comment and document the iPhone and iPad export An unsupervised phone only honors the Siri and ChatGPT switches. The profile export is described next to the Mac profile commands. Co-authored-by: MrTiptop --- README.md | 12 ++++++++++++ Sources/removemacai/Mobile.swift | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 442c2fb..765c74a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Two presets get you started. **Recommended** turns Apple Intelligence, analytics | `removemacai background` | List other apps' background items; `off` or `on` with their labels | | `removemacai clean` | Show the space you can get back; name items to move them to the Trash | | `removemacai export ` | Write the configuration profile for an MDM | +| `removemacai export --for iphone\|ipad` | Write an iPhone or iPad profile | | `removemacai revert` | Undo everything RemoveMacAI changed | | `removemacai app` | Open the app | @@ -123,6 +124,17 @@ removemacai export Privacy.mobileconfig --no-ai analytics personalized-ads spotl It holds the Apple Intelligence restrictions, the download block for removed models and the locked tweaks. Per-user tweaks such as Finder and Dock settings aren't in the profile; `removemacai apply` sets those on each Mac. `removemacai tweaks --json` reports the state of every tweak for compliance scripts. +## iPhone and iPad + +`export --for iphone` or `export --for ipad` writes a profile for that device: + +```sh +removemacai export Phone.mobileconfig --for iphone +removemacai export Pad.mobileconfig --for ipad +``` + +An unsupervised phone only honors the Siri and ChatGPT switches. + ## How it works - **Locked settings** (Apple Intelligence and the tweaks marked with a lock) go in one configuration profile that you approve in System Settings, because macOS requires that. Removing the profile undoes all of them. diff --git a/Sources/removemacai/Mobile.swift b/Sources/removemacai/Mobile.swift index 88b0cf1..fb23b3b 100644 --- a/Sources/removemacai/Mobile.swift +++ b/Sources/removemacai/Mobile.swift @@ -1,4 +1,3 @@ -// MrTiptop import Foundation /// A configuration profile that turns Apple Intelligence off on an iPhone or From ae0060b38a9234181b16ceb9984326a37cec2b9f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 26 Oct 2026 21:38:21 +0000 Subject: [PATCH 3/4] Name the iPhone and iPad limits the profile can actually set Visual Intelligence summaries apply on iPad as well as iPhone, because Apple documents that restriction for iOS. The Mail switch only turns off summaries a person starts. Mail can still write them on its own. Co-authored-by: MrTiptop --- Sources/removemacai/Mobile.swift | 34 ++++++++++++------------- Sources/removemacai/SelfTest.swift | 10 +++++--- Sources/removemacai/TweakCommands.swift | 8 +++--- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/Sources/removemacai/Mobile.swift b/Sources/removemacai/Mobile.swift index fb23b3b..9ae8cbc 100644 --- a/Sources/removemacai/Mobile.swift +++ b/Sources/removemacai/Mobile.swift @@ -30,50 +30,47 @@ enum Mobile { let title: String let restrictions: [String] let supervised: Bool - /// Visual Intelligence is an iPhone camera feature. iPadOS has no switch. - let iPhoneOnly: Bool } static let features: [Feature] = [ Feature( id: "siri", title: "Siri and Siri AI", - restrictions: ["allowAssistant", "allowSiriAI"], supervised: false, iPhoneOnly: false), + restrictions: ["allowAssistant", "allowSiriAI"], supervised: false), Feature( id: "chatgpt", title: "ChatGPT and other AI extensions", restrictions: [ "allowExternalIntelligenceIntegrations", "allowExternalIntelligenceIntegrationsSignIn", - ], supervised: false, iPhoneOnly: false), + ], supervised: false), Feature( id: "writing-tools", title: "Writing Tools", - restrictions: ["allowWritingTools"], supervised: true, iPhoneOnly: false), + restrictions: ["allowWritingTools"], supervised: true), Feature( id: "genmoji", title: "Genmoji", - restrictions: ["allowGenmoji"], supervised: true, iPhoneOnly: false), + restrictions: ["allowGenmoji"], supervised: true), Feature( id: "image-playground", title: "Image Playground", - restrictions: ["allowImagePlayground"], supervised: true, iPhoneOnly: false), + restrictions: ["allowImagePlayground"], supervised: true), Feature( id: "image-wand", title: "Image Wand", - restrictions: ["allowImageWand"], supervised: true, iPhoneOnly: false), + restrictions: ["allowImageWand"], supervised: true), Feature( id: "mail", title: "Mail summaries and smart replies", - restrictions: ["allowMailSummary", "allowMailSmartReplies"], supervised: true, iPhoneOnly: false), + restrictions: ["allowMailSummary", "allowMailSmartReplies"], supervised: true), Feature( id: "safari-summaries", title: "Safari summaries", - restrictions: ["allowSafariSummary"], supervised: true, iPhoneOnly: false), + restrictions: ["allowSafariSummary"], supervised: true), Feature( id: "notes-summaries", title: "Notes transcription summaries", - restrictions: ["allowNotesTranscriptionSummary"], supervised: true, iPhoneOnly: false), + restrictions: ["allowNotesTranscriptionSummary"], supervised: true), Feature( - id: "visual-intelligence", title: "Visual Intelligence", - restrictions: ["allowVisualIntelligenceSummary"], supervised: true, iPhoneOnly: true), + id: "visual-intelligence", title: "Visual Intelligence summaries", + restrictions: ["allowVisualIntelligenceSummary"], supervised: true), ] static func feature(_ id: String) -> Feature? { features.first { $0.id == id } } - static func features(for device: Device) -> [Feature] { - features.filter { !$0.iPhoneOnly || device == .iPhone } - } + /// iPhone and iPad use the same restriction keys. Apple's schema lists them under iOS. + static func features(for _: Device) -> [Feature] { features } /// The profile for `device`, with every feature off except `kept`. static func data(keeping kept: Set, device: Device) throws -> Data { @@ -82,10 +79,13 @@ enum Mobile { for key in feature.restrictions { restrictions[key] = false } } let supervised = features(for: device).filter(\.supervised).map(\.title).joined(separator: ", ") + let mailNote = kept.contains("mail") + ? "" + : " Mail summaries turn off the ones you start yourself. Mail can still write them on its own." let description = """ Turns off Apple Intelligence on this \(device.rawValue). Remove the profile and the switches come back. \ \(device.systemName) does not let a profile delete the model files. \ - Siri and ChatGPT extensions apply on any device. \(supervised) apply on a supervised device. Shared iPad ignores them. + Siri and ChatGPT extensions apply on any device. \(supervised) apply on a supervised device. Shared iPad ignores them.\(mailNote) """ let profile: [String: Any] = [ "PayloadType": "Configuration", diff --git a/Sources/removemacai/SelfTest.swift b/Sources/removemacai/SelfTest.swift index a66f815..feaf167 100644 --- a/Sources/removemacai/SelfTest.swift +++ b/Sources/removemacai/SelfTest.swift @@ -254,13 +254,17 @@ func selfTest() -> Bool { && phoneRestrictions["allowImageWand"] as? Bool == false && phoneRestrictions["allowVisualIntelligenceSummary"] as? Bool == false && phoneRestrictions["allowDiagnosticSubmission"] == nil, - "an iPhone profile turns Writing Tools, Siri, Image Wand, and Visual Intelligence off") + "an iPhone profile turns Writing Tools, Siri, Image Wand, and Visual Intelligence summaries off") check(padRestrictions["allowWritingTools"] == nil && padRestrictions["allowGenmoji"] as? Bool == false && padRestrictions["allowImageWand"] as? Bool == false && padRestrictions["allowExternalIntelligenceIntegrations"] as? Bool == false - && padRestrictions["allowVisualIntelligenceSummary"] == nil, - "a kept iPad feature is left alone and iPad has no Visual Intelligence switch") + && padRestrictions["allowVisualIntelligenceSummary"] as? Bool == false, + "a kept iPad feature is left alone and iPad turns Visual Intelligence summaries off") + let phoneDescription = phone["PayloadDescription"] as? String ?? "" + check(phoneDescription.contains("Mail can still write them on its own") + && phoneDescription.contains("Visual Intelligence summaries"), + "the profile says Mail summaries are manual and names Visual Intelligence summaries") } catch { check(false, "the iPhone and iPad profiles build: \(error)") } diff --git a/Sources/removemacai/TweakCommands.swift b/Sources/removemacai/TweakCommands.swift index 00a51d6..41adca8 100644 --- a/Sources/removemacai/TweakCommands.swift +++ b/Sources/removemacai/TweakCommands.swift @@ -270,12 +270,9 @@ enum TweakCommands { if noAI { Term.fail("--no-ai leaves Apple Intelligence alone, so an \(device.rawValue) profile would be empty") } let names = Mobile.features(for: device).map(\.id).joined(separator: ", ") for id in keepAI.sorted() { - guard let feature = Mobile.feature(id) else { + guard Mobile.feature(id) != nil else { Term.fail("there is no \(device.rawValue) feature called \"\(id)\". Names: \(names)") } - if feature.iPhoneOnly && device != .iPhone { - Term.fail("\(feature.title) is an iPhone feature. Leave it out of --keep on an iPad") - } } let off = Mobile.features(for: device).filter { !keepAI.contains($0.id) } guard !off.isEmpty else { Term.fail("nothing would be turned off. Leave a feature out of --keep") } @@ -290,6 +287,9 @@ enum TweakCommands { print(Term.dim(" A supervised \(device.rawValue) honors: \(supervised.joined(separator: ", ")). An unsupervised one ignores those.")) } print(Term.dim(" Siri and ChatGPT extensions apply without supervision.")) + if off.contains(where: { $0.id == "mail" }) { + print(Term.dim(" Mail summaries turn off the ones you start yourself. Mail can still write them on its own.")) + } print(Term.dim(" \(device.systemName) keeps the model files. Removing the profile turns the switches back on.")) print(Term.dim(" Shared iPad ignores the supervised switches.")) print(Term.dim(" Install it from Settings > General > VPN & Device Management.")) From a4612d0135252a9d0d83632b23f79c2e1246678f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 26 Oct 2026 22:06:06 +0000 Subject: [PATCH 4/4] Stop promising Siri AI and ChatGPT on Shared iPad Apple forbids allowSiriAI and the ChatGPT extension keys on Shared iPad. Siri itself still applies without supervision. Co-authored-by: MrTiptop --- Sources/removemacai/Mobile.swift | 2 +- Sources/removemacai/SelfTest.swift | 6 ++++-- Sources/removemacai/TweakCommands.swift | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/removemacai/Mobile.swift b/Sources/removemacai/Mobile.swift index 9ae8cbc..238494f 100644 --- a/Sources/removemacai/Mobile.swift +++ b/Sources/removemacai/Mobile.swift @@ -85,7 +85,7 @@ enum Mobile { let description = """ Turns off Apple Intelligence on this \(device.rawValue). Remove the profile and the switches come back. \ \(device.systemName) does not let a profile delete the model files. \ - Siri and ChatGPT extensions apply on any device. \(supervised) apply on a supervised device. Shared iPad ignores them.\(mailNote) + Siri applies without supervision. Siri AI and ChatGPT extensions apply without supervision, and Shared iPad ignores them. \(supervised) apply on a supervised device. Shared iPad ignores those too.\(mailNote) """ let profile: [String: Any] = [ "PayloadType": "Configuration", diff --git a/Sources/removemacai/SelfTest.swift b/Sources/removemacai/SelfTest.swift index feaf167..aca0d16 100644 --- a/Sources/removemacai/SelfTest.swift +++ b/Sources/removemacai/SelfTest.swift @@ -263,8 +263,10 @@ func selfTest() -> Bool { "a kept iPad feature is left alone and iPad turns Visual Intelligence summaries off") let phoneDescription = phone["PayloadDescription"] as? String ?? "" check(phoneDescription.contains("Mail can still write them on its own") - && phoneDescription.contains("Visual Intelligence summaries"), - "the profile says Mail summaries are manual and names Visual Intelligence summaries") + && phoneDescription.contains("Visual Intelligence summaries") + && phoneDescription.contains("Shared iPad ignores them") + && !phoneDescription.contains("any device"), + "the profile names its Mail and Visual Intelligence limits and does not promise Siri AI on Shared iPad") } catch { check(false, "the iPhone and iPad profiles build: \(error)") } diff --git a/Sources/removemacai/TweakCommands.swift b/Sources/removemacai/TweakCommands.swift index 41adca8..642a439 100644 --- a/Sources/removemacai/TweakCommands.swift +++ b/Sources/removemacai/TweakCommands.swift @@ -286,7 +286,7 @@ enum TweakCommands { if !supervised.isEmpty { print(Term.dim(" A supervised \(device.rawValue) honors: \(supervised.joined(separator: ", ")). An unsupervised one ignores those.")) } - print(Term.dim(" Siri and ChatGPT extensions apply without supervision.")) + print(Term.dim(" Siri applies without supervision. Siri AI and ChatGPT extensions do too, except Shared iPad ignores them.")) if off.contains(where: { $0.id == "mail" }) { print(Term.dim(" Mail summaries turn off the ones you start yourself. Mail can still write them on its own.")) }