diff --git a/cmd/list-installed-launchjob-ids.rb b/cmd/list-installed-launchjob-ids.rb
new file mode 100755
index 0000000000000..7089dc521cc5b
--- /dev/null
+++ b/cmd/list-installed-launchjob-ids.rb
@@ -0,0 +1,63 @@
+# typed: strict
+# frozen_string_literal: true
+
+require "abstract_command"
+require "open3"
+
+module Homebrew
+ module Cmd
+ class ListInstalledLaunchjobIdsCmd < AbstractCommand
+ cmd_args do
+ description <<~EOS
+ List all installed launchjob IDs, which may be useful
+ in a Cask uninstall stanza, e.g.:
+
+ uninstall launchctl: "job.id.goes.here"
+
+ Launchctl jobs attributed to Apple will be omitted.
+
+ If a launchctl job is currently loaded, and visible to the current
+ user, it will be followed by a plus symbol '(+)' in the output.
+ This can be verified via the command:
+
+ /bin/launchctl list 'job.id.goes.here'
+
+ See CONTRIBUTING.md and 'man launchctl' for more information.
+ EOS
+
+ named_args :none
+
+ hide_from_man_page!
+ end
+
+ sig { override.returns(T.nilable(String)) }
+ def run
+ loaded = list_loaded_launchjob_ids
+ pattern = "{#{Dir.home},}/Library/Launch{Agents,Daemons}/**.plist"
+ puts Pathname
+ .glob(pattern)
+ .filter(&:readable?)
+ .filter_map { method(:read_label).call(it) }
+ .reject { it.start_with? "com.apple." }
+ .uniq.sort
+ .map { loaded.include?(it) ? "#{it} (+)" : it }
+ end
+
+ sig { params(plist: Pathname).returns(T.nilable(String)) }
+ def read_label(plist)
+ xml = plist.read
+ if xml.start_with? "bplist"
+ xml, _, status = Open3.capture3("/usr/bin/plutil -convert xml1 -o - '#{plist}'")
+ return unless status.success?
+ end
+ Plist.parse_xml(xml, marshal: false)["Label"]
+ end
+
+ sig { returns(T::Array[T.nilable(String)]) }
+ def list_loaded_launchjob_ids
+ loaded, = Open3.capture3("/bin/launchctl list")
+ loaded.lines.map { it.split(/\s+/).last }
+ end
+ end
+ end
+end
diff --git a/developer/bin/list_installed_launchjob_ids b/developer/bin/list_installed_launchjob_ids
deleted file mode 100755
index 333e40a39d4e4..0000000000000
--- a/developer/bin/list_installed_launchjob_ids
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/bash
-#
-# list_installed_launchjob_ids
-#
-
-###
-### settings
-###
-
-set -e # exit on any uncaught error
-set +o histexpand # don't expand history expressions
-shopt -s nocasematch # case-insensitive regular expressions
-
-###
-### global variables
-###
-
-# prefer GNU xargs
-xargs="$(/usr/bin/which gxargs || printf '/usr/bin/xargs')"
-
-###
-### functions
-###
-
-launchjob_id_source_1 () {
- /usr/bin/find ~/Library/LaunchAgents/ \
- ~/Library/LaunchDaemons/ \
- /Library/LaunchAgents/ \
- /Library/LaunchDaemons/ \
- -type f -print0 2>/dev/null | \
- "$xargs" -0 /usr/bin/perl -0777 -ne \
- 'while (m{\s*Label\s*\s*([^<]+?)}sg) { print "$1\n" }'
-}
-
-merge_sources () {
- /usr/bin/sort | /usr/bin/uniq
-}
-
-clean_sources () {
- /usr/bin/grep -E -v '^com\.apple\.'
-}
-
-mark_up_sources () {
- /usr/bin/perl -pe 's{\n}{\000}sg' | \
- "$xargs" -0 -I{} -n1 /bin/bash -c \
- 'printf "{}"; /bin/launchctl list "{}" >/dev/null 2>&1 && printf " (+)"; printf "\n"'
-}
-
-###
-### main
-###
-
-_list_installed_launchjob_ids () {
-
- {
- launchjob_id_source_1;
- } | \
- merge_sources | \
- clean_sources | \
- mark_up_sources
-
-}
-
-# process args
-if [[ $1 =~ ^-+h(elp)?$ ]]; then
- printf "list_installed_launchjob_ids
-
-List all installed launchjob IDs, which may be useful
-in a Cask uninstall stanza, e.g.:
-
- uninstall launchctl: 'job.id.goes.here'
-
-Launchctl jobs attributed to Apple will be omitted.
-
-If a launchctl job is currently loaded, and visible to the current
-user, it will be followed by a plus symbol '(+)' in the output.
-This can be verified via the command:
-
- /bin/launchctl list 'job.id.goes.here'
-
-See CONTRIBUTING.md and 'man launchctl' for more information.
-
-"
- exit
-fi
-
-# dispatch main
-_list_installed_launchjob_ids "${@}"
-
-#