-
Notifications
You must be signed in to change notification settings - Fork 3
Command Line Reference
Three binaries are installed to /usr/local/bin/tpp/. All require root (sudo) except where noted.
The core patching engine. Each subcommand runs one phase of the patching workflow.
sudo /usr/local/bin/tpp/patcher <subcommand> [options]
Discovers installed third-party applications and writes per-app metadata to Discovered/.
sudo /usr/local/bin/tpp/patcher scan [--user-initiated]Reads all label files (Installomator + Managed Labels), evaluates each label to detect installed apps, and records the installed version and app paths. Runs a full scan unconditionally regardless of the configured ScanIntervalDays interval.
| Flag | Description |
|---|---|
--user-initiated |
Show a swiftDialog progress window during the scan. Used when triggered from PatcherMenu; not needed when running manually. |
Checks all previously discovered apps for available updates.
sudo /usr/local/bin/tpp/patcher check [--user-initiated]Re-evaluates each entry in Discovered/ against its label's version logic. Marks apps as needing an update when the available version differs from the installed version. Does not re-run a full label scan; only examines already-discovered apps.
| Flag | Description |
|---|---|
--user-initiated |
Show a swiftDialog progress window during the check. Used when triggered from PatcherMenu. |
Checks uninstalled labels for apps that may have been installed by other means, without re-running label scripts or hitting the network for non-installed labels.
sudo /usr/local/bin/tpp/patcher lightScan [--label <label>]Reads the Scanned/ folder (populated during a full scan) and checks whether any unmanaged label now has an app present. Faster than a full scan. Also used internally by the Applications folder watcher when a new .app bundle is detected in /Applications.
| Option | Description |
|---|---|
--label <label> |
Scan only a single label. Used by the Applications folder watcher for targeted detection. |
Downloads and validates installers for apps that need updating.
sudo /usr/local/bin/tpp/patcher stage [--label <label>] [--user-initiated]Downloads to the patcher cache, verifies the Team ID signature, and holds the installer ready for apply. Skips apps already staged at the current version. When --label is specified, the configured bandwidth limit is bypassed.
| Option / Flag | Description |
|---|---|
--label <label> |
Stage only this specific label. Bypasses any configured bandwidth limit. |
--user-initiated |
Show a swiftDialog progress window during the download. Used when triggered from PatcherMenu. |
Downloads and stages pending updates immediately, bypassing any configured bandwidth limit.
sudo /usr/local/bin/tpp/patcher stageOnDemandLike stage, but always bypasses DownloadBandwidthLimit. Useful for testing or recovering from a corrupted download when you need the full download speed.
Installs all staged updates (or a single label).
sudo /usr/local/bin/tpp/patcher apply [--label <label>] [--days-pending <N>] [--user-initiated]Runs the installer for each app with a staged update. Prompts the user via swiftDialog if blocking processes are running (when SwiftDialogEnabled is true). Respects deferral state and deadlines.
| Option / Flag | Description |
|---|---|
--label <label> |
Apply only the staged update for this label. |
--days-pending <N> |
Number of days the oldest pending update has been staged. Used by the scheduler for deadline enforcement and to cap deferral options on the final patch day. |
--user-initiated |
Skip the deferral prompt and proceed directly to the patching window. Used when triggered from PatcherMenu. |
Silently installs staged updates where no blocking process is running.
sudo /usr/local/bin/tpp/patcher applyQuiet [--label <label>]Installs each staged update only if the label's blocking process is not currently running. Apps whose blocking process is active are silently skipped — they are not counted as deferrals and will appear in the next interactive apply pass. Enabled in the scheduler via the QuietApplyEnabled preference.
| Option | Description |
|---|---|
--label <label> |
Apply quietly only for this label. |
Ensures a specific label is scanned, staged, and applied. Runs all three phases end-to-end for a single label.
sudo /usr/local/bin/tpp/patcher ensure <label>Runs scan, stage, and apply in sequence for the named label. Bypasses the bandwidth limit and the IgnoreAppsInHomeFolder preference so the install always proceeds to /Applications. Intended for bootstrapping required tools (e.g. swiftDialog) and for self-service installs triggered from Available Software.
| Argument | Description |
|---|---|
<label> |
Installomator label name to ensure is installed and current. Required. |
Deletes patch history for all labels, or a single label.
# Reset all labels
sudo /usr/local/bin/tpp/patcher resetHistory
# Reset a single label
sudo /usr/local/bin/tpp/patcher resetHistory <label>Removes history.json from the label's cache folder. After a reset, the next apply cycle treats the label as if it has never been patched — deferral counts and deadline tracking start fresh.
Use case: After manually installing a new version of an app, run
resetHistory <label>so the scheduler doesn't attempt to re-apply an older staged installer.
| Argument | Description |
|---|---|
<label> |
Label whose history should be reset. Omit to reset all labels. |
Clears broken/failed state for all labels, or a single label.
# Clear all broken state
sudo /usr/local/bin/tpp/patcher resetBroken
# Clear a single label
sudo /usr/local/bin/tpp/patcher resetBroken <label>Removes the label from the broken-scan, broken-stage, failed-stage, failed-apply, and broken-apply-version tracking in config.json. After a reset, the scheduler will retry staging and applying the label on the next cycle.
Use case: After a transient download failure or a package that previously failed Team ID verification has been corrected upstream, use
resetBroken <label>to allow the label to be re-staged without waiting for the failure threshold to clear naturally.
| Argument | Description |
|---|---|
<label> |
Label whose broken state should be cleared. Omit to clear all labels. |
Fully resets a single label: removes its staged cache and moves it from Discovered back to Scanned.
sudo /usr/local/bin/tpp/patcher resetLabel <label>Performs three operations in sequence:
-
Removes
Cache/<label>/— deletes the staged installer,metadata.json, andhistory.jsonfor the label. -
Demotes the discovered plist — reads
Discovered/<label>.plist, strips the install-specific keys (installedVersion,updateStatus,foundInstalls), and writes the result toScanned/<label>.plist. -
Removes
Discovered/<label>.plist— the label is no longer tracked as an installed app.
After the reset, the label is in the same state as a freshly scanned but not-yet-installed app. It will be re-evaluated on the next full scan: if the app is found installed at a standard path, it will be re-discovered normally; if not found, it stays in Scanned.
Use case: An app was discovered on a removable external drive that will never be reconnected. The staged update and install-path records need to be cleared so the label stops appearing as pending and is no longer tied to the missing volume.
| Argument | Description |
|---|---|
<label> |
Label to reset. Required. |
Resets ownership and permissions on all patcher data folders.
sudo /usr/local/bin/tpp/patcher repairPermissionsSets root:wheel ownership and 755 (directories) / 644 (files) permissions on the patcher Application Support tree. Run this if a permission error is preventing the scheduler from reading or writing its data folders.
Deletes log files in /Library/Logs/Patcher/ older than a specified number of days.
sudo /usr/local/bin/tpp/patcher cleanLogs [--days <N>]Removes log files whose modification date is older than the retention window. Run automatically by the scheduler; can also be run manually.
| Option | Description |
|---|---|
--days <N> |
Delete logs older than N days. Defaults to the LogRetentionDays preference (default: 90). Pass 0 to skip cleanup. |
Sends the accumulated webhook report and clears the report log.
sudo /usr/local/bin/tpp/patcher sendReportReads the accumulated apply results and stage failures from webhook_report.json, applies the WebhookStageFailureThreshold filter, and sends the report to the configured webhook URLs (Teams and/or Slack). Clears the report log after a successful send. Has no effect if no webhook URLs are configured or if nothing has accumulated since the last send.
See Reporting for webhook configuration details.
Sends a test webhook notification to validate connectivity and message format.
sudo /usr/local/bin/tpp/patcher testWebhookSends a fabricated report containing three fake successful installs and one fake failure to the configured webhook URLs. Useful for verifying that the webhook URL, network path, and message formatting are all working before putting the system into production.
Downloads and syncs the Installomator metadata repository to local storage.
sudo /usr/local/bin/tpp/patcher metadataFetches the latest commit of the configured metadata repository and extracts icons, descriptions, publisher names, and keywords to the local metadata cache. Used by the Available Software catalog to display app details and icons. Run automatically by the scheduler when MetadataSyncEnabled is true.
The daemon entry point. In normal operation it is launched and kept alive by the LaunchDaemon — administrators do not need to invoke it directly. On each wake (every 10 minutes), it evaluates all phase intervals and runs any that are due.
# The scheduler is managed by launchd; use kickstart to trigger an immediate cycle
sudo launchctl kickstart system/com.gilburns.patcher.schedulerThe scheduler also exposes a named Mach XPC service (com.gilburns.patcher.xpc) so PatcherMenu and Available Software can trigger on-demand phase runs without waiting for the next scheduled wake.
Prints the current patching schedule — last run time, configured interval, and next scheduled run for each phase — without modifying any state.
# Human-readable table (default)
/usr/local/bin/tpp/patcherscheduler status
# JSON output
/usr/local/bin/tpp/patcherscheduler status --json
# Plist (XML) output
/usr/local/bin/tpp/patcherscheduler status --plistThe table output shows each phase with its configured interval, the last time it ran, and when it is next due. It also reports any pending label update that would trigger an early scan, and the initial deployment delay status if configured.
The --json and --plist formats are suitable for ingestion by monitoring tools or MDM extension attributes.
statusdoes not requiresudo— it only reads scheduler state and preferences.
| Flag | Description |
|---|---|
--json |
Output as a JSON object. |
--plist |
Output as an XML property list. |
Generates human-readable patch status reports from the data written by the daemon. Does not require root.
/usr/local/bin/tpp/patcherreport <subcommand> [options]
See Reporting for full details on each subcommand's output format.
| Option | Description |
|---|---|
--json |
Output as JSON. |
--csv |
Output as CSV. |
--output <path> |
Write to a file instead of stdout. Parent directories are created automatically. |
| Subcommand | Description |
|---|---|
summary |
Overall patching statistics — apps managed, updates applied, pending count, broken labels. |
pending |
Labels staged and ready to install but not yet applied. |
recent [--days N] |
Labels with activity in the last N days (default: 30). |
broken |
Labels that have reached the scan-broken or stage-broken threshold. |
never-updated |
Apps discovered but never successfully patched. |
label <name> |
Full chronological event history for a single label. |
deferrals [--days N] |
Dialog interaction history: deferrals, blocking-process outcomes, and auto-actions. |
See Reporting for full output examples.