Match profiles list output liberally when sweeping profiles
macOS 26 lists profiles as attribute lines (profileIdentifier:) rather
than the key-value layout the parser assumed, so profile:remove found
nothing. Scan for the identifier anywhere in the output instead; the
real format is pinned as a test.

Assisted-by: GLM 5.2 via pi
change orxovqlprpspxlqvsmwpkrpqnsuovtnt
commit 610e6235d3a915076edb0908f07f4f259d66a939
author Alpha Chen <alpha@kejadlen.dev>
date
parent owvktulw
diff --git a/lib/pro_tacts/profile.rb b/lib/pro_tacts/profile.rb
index 3ca188e..0c5664b 100644
--- a/lib/pro_tacts/profile.rb
+++ b/lib/pro_tacts/profile.rb
@@ -33,10 +33,11 @@ module ProTacts
 
     # Picks our profile identifiers out of `profiles list` output so
     # profile:remove can sweep every pro-tacts profile, not just the latest.
+    # Scans for the prefix anywhere in the output rather than assuming a
+    # key-value layout, since the listing format has changed across macOS
+    # versions (key-value today, table under later releases).
     def self.installed_identifiers(list_output)
-      list_output.scan(/^\s*identifier:\s*(\S+)/).flatten
-        .select { |identifier| identifier.start_with?(IDENTIFIER_PREFIX) }
-        .uniq
+      list_output.scan(/(?<![\w.-])#{Regexp.escape(IDENTIFIER_PREFIX)}-[\w.-]+/).uniq
     end
 
     def self.template
diff --git a/test/pro_tacts/test_profile.rb b/test/pro_tacts/test_profile.rb
index 0fd96e2..49ed2c1 100644
--- a/test/pro_tacts/test_profile.rb
+++ b/test/pro_tacts/test_profile.rb
@@ -66,6 +66,35 @@ class ProfileTest < Minitest::Test
     ], ProTacts::Profile.installed_identifiers(list_output)
   end
 
+  def test_installed_identifiers_reads_attribute_format_output
+    list_output = <<~OUTPUT
+      alpha[1] attribute: profileIdentifier: #{ProTacts::Profile::IDENTIFIER_PREFIX}-20260818155835720a9db
+      There are 1 user configuration profiles installed for 'alpha'
+    OUTPUT
+
+    assert_equal ["#{ProTacts::Profile::IDENTIFIER_PREFIX}-20260818155835720a9db"],
+      ProTacts::Profile.installed_identifiers(list_output)
+  end
+
+  def test_installed_identifiers_reads_table_format_output
+    list_output = <<~OUTPUT
+      Profiles:
+          identifier                             display name
+          ------------------------------------   --------------
+          #{ProTacts::Profile::IDENTIFIER_PREFIX}-20260818ab12   pro-tacts CardDAV
+          com.example.unrelated                  Work
+      OUTPUT
+
+    assert_equal ["#{ProTacts::Profile::IDENTIFIER_PREFIX}-20260818ab12"],
+      ProTacts::Profile.installed_identifiers(list_output)
+  end
+
+  def test_installed_identifiers_ignores_longer_identifiers_containing_the_prefix
+    list_output = "com.example.#{ProTacts::Profile::IDENTIFIER_PREFIX}-fake\n"
+
+    assert_empty ProTacts::Profile.installed_identifiers(list_output)
+  end
+
   def test_installed_identifiers_is_empty_without_ours
     list_output = "  identifier: com.example.unrelated\n"