Feature Guide

A comprehensive walkthrough of everything LaunchPad does -- from automatic agent discovery to Touch ID security.

Agent Discovery P0

On first launch and on-demand, LaunchPad scans your system for every existing LaunchAgent plist file. It parses each plist, extracts the full configuration, and cross-references with launchctl list to determine live status.

Scan coverage

  • ~/Library/LaunchAgents/ -- your user-level agents (full read/write access for managed jobs)
  • /Library/LaunchAgents/ -- system-wide user agents (read-only in the dashboard)

What gets extracted from each plist

FieldPlist Key
LabelLabel
Command & argumentsProgramArguments or Program
ScheduleStartInterval, StartCalendarInterval
Event triggersWatchPaths, QueueDirectories, StartOnMount
Keep-alive configKeepAlive (boolean or conditional)
EnvironmentEnvironmentVariables, WorkingDirectory
Log pathsStandardOutPath, StandardErrorPath
AdvancedRunAtLoad, ThrottleInterval, Nice, ProcessType

Status detection

For each discovered agent, LaunchPad queries launchctl list to determine:

  • Loaded vs. Unloaded -- whether the agent is registered with launchd
  • Running vs. Idle -- whether the agent has an active process (PID)
  • Last exit code -- success (0) or failure (non-zero)

Jobs not created by LaunchPad are marked as "External" with a read-only badge. You can inspect their configuration but cannot modify or delete them. LaunchPad identifies its own jobs by the presence of a <key>LaunchPadManaged</key><true/> key in the plist.

Malformed plist files are handled gracefully -- displayed with an error indicator, never crashing the scan. The full scan of 100+ plists completes in under 3 seconds.

Job Builder P0

The Job Builder is a visual form that replaces manual plist XML authoring. It collects all the configuration a LaunchAgent needs, validates inputs in real time, generates valid plist XML, and registers the job with launchctl -- all in one flow.

Form fields

FieldDescription
LabelReverse-DNS identifier (auto-suggested from executable name, e.g., com.launchpad.backup)
NameHuman-readable display name
CommandExecutable path with file picker or manual input
ArgumentsAdditional command-line arguments
Working DirectoryCWD for execution
Environment VariablesKey-value editor for env vars
ScheduleTriple input: visual, cron, or natural language (see Schedule Engine)
Event TriggersWatchPaths, QueueDirectories, StartOnMount (see Event System)
Log PathsAuto-defaulted to ~/Library/Logs/LaunchPad/<label>.log/.err
KeepAliveBoolean or conditional (NetworkState, SuccessfulExit, PathState, Crashed)
RunAtLoadExecute immediately when loaded
NiceProcess priority (-20 to 20)
ProcessTypeStandard, Background, or Adaptive

Built-in safeguards

  • Label uniqueness is validated against both the database and launchctl list
  • Generated plist XML is validated with plutil -lint before writing
  • A plist preview pane shows the exact XML before saving
  • A "Test Run" button executes the command once and displays output in a modal
  • Conflicting schedule types (StartInterval + StartCalendarInterval) are prevented at the form level

On save

  1. Plist XML is generated and validated
  2. File is written to ~/Library/LaunchAgents/
  3. Job is registered: launchctl bootstrap gui/<uid> <path>
  4. Job record is created in SQLite with full configuration

Schedule Engine P0

Three interchangeable schedule input methods, all bidirectionally synced. Change one and the others update automatically.

The default input. Provides dropdowns and toggles for:

  • Day-of-week multi-select: Mon-Sun presets ("Every day", "Weekdays", "Weekends")
  • Hour picker: 0-23 (or 12h AM/PM toggle)
  • Minute picker: 0-59 or common intervals (00, 15, 30, 45)
  • Interval mode: every N seconds/minutes/hours for frequency-based schedules

A 7-day timeline strip below the form shows exactly when the job will fire next.

Standard 5-field cron expression: minute hour day-of-month month day-of-week. Below the input, LaunchPad shows:

  • Human-readable description (e.g., "At 09:00, Monday through Friday")
  • Next 5 scheduled run times

Invalid cron expressions are rejected with a clear error message before you can save.

Type plain English and LaunchPad parses it with chrono-node. Supported patterns include:

  • every 30 minutes
  • daily at 9am
  • every weekday at 9am
  • every Monday at noon
  • twice daily
  • first Monday of the month at noon

The parsed interpretation is shown for confirmation before applying.

Schedule mapping

All three inputs map to launchd's native schedule keys:

  • Calendar-based schedules map to StartCalendarInterval (single dict or array of dicts)
  • Frequency-based schedules map to StartInterval (integer seconds)
Schedule conflict warning

LaunchPad warns when a schedule would fire more than 100 times per day (potential misconfiguration) and prevents using StartCalendarInterval and StartInterval simultaneously, as launchd behavior is undefined in that case.

Event System P0

Beyond time-based schedules, launchd supports event-driven triggers. LaunchPad exposes all of them through the UI.

TriggerPlist KeyDescription
WatchPathsWatchPathsTrigger when a file or directory changes. Supports multiple paths with file/folder picker.
QueueDirectoriesQueueDirectoriesTrigger when items appear in a directory. Job processes and removes them.
StartOnMountStartOnMountTrigger when a volume (USB drive, network share) is mounted.
RunAtLoadRunAtLoadExecute immediately when the agent is loaded (at login).
KeepAliveKeepAliveRestart the job based on conditions: always, on crash, on network change, on path state, or on successful exit.

Event triggers are configured in a separate section from the schedule, but they can be combined. A job can have both a recurring schedule and a file watch trigger. The UI clearly indicates when multiple trigger types are active.

Path-based triggers (WatchPaths, QueueDirectories) validate that paths exist, showing a warning (not blocking) if the path is missing.

Log Viewer P0

For every managed job, LaunchPad captures and stores complete execution history: start time, end time, duration, exit code, and full stdout/stderr output.

Execution timeline

The job detail view shows a chronological timeline of every run with color-coded status badges:

  • Success -- exit code 0
  • Failed -- non-zero exit code
  • Running -- active PID
  • Signal -- terminated by signal

Each entry shows the timestamp, duration, and a one-line stderr excerpt if the exit code was non-zero. Click to expand and see full stdout and stderr in a terminal-style log viewer.

Log viewer features

  • Monospace font on dark background
  • ANSI color code rendering
  • Text search (Cmd+F)
  • Copy-to-clipboard for full log content
  • Auto-scroll toggle for live tailing
  • Logs exceeding 1 MB are truncated with a "Download Full Log" option

Live tail mode

For currently running jobs, the log viewer streams output in real time by polling the log file and appending new content. Toggle auto-scroll on or off depending on your needs.

Per-job statistics

MetricDescription
Total runsLifetime execution count
Success ratePercentage of runs with exit code 0
Average durationMean execution time in ms
Last runTimestamp of most recent execution
Last failureTimestamp of most recent non-zero exit

Organization P1

Two complementary systems for managing jobs at scale: Folders for hierarchical grouping and Tags for cross-cutting labels.

Folders

  • Each job belongs to exactly one folder
  • Supports nested folders up to 3 levels deep
  • Default folders: "Uncategorized" (all new jobs) and "System" (external/read-only agents) -- cannot be deleted
  • Folder sidebar shows a tree view with job count badges
  • Drag-and-drop jobs into folders

Tags

  • Each job can have multiple tags
  • Tags are color-coded and user-defined
  • Click a tag to filter; Shift+Click for multi-tag filtering (AND/OR toggle)

Search and filtering

  • Full-text search across job label, command path, folder name, and tag names
  • Status filter: running, idle, failed (last run), disabled/unloaded
  • Sort options: name, last run, next run, status (failures first), date created
  • Active filters are shown as removable chips above the job list

Bulk operations

Select multiple jobs via checkboxes, then apply batch actions: move to folder, add/remove tag, enable, disable, or delete. Bulk operations require a single Touch ID confirmation.

Security P1

LaunchPad uses macOS Touch ID via the Web Authentication API (WebAuthn) to protect destructive operations. This is defense-in-depth for a localhost tool -- preventing accidental modifications, not protecting against a compromised machine.

Protected operations

  • Deleting a job
  • Modifying a job's command or schedule
  • Enabling/disabling a job (load/unload)
  • Bulk operations (single confirmation for the batch)

How it works

  1. Server generates a WebAuthn challenge
  2. Browser calls navigator.credentials.get()
  3. macOS prompts Touch ID (or password fallback)
  4. Signed assertion is sent back to the server
  5. Server verifies and proceeds with the operation

A 5-minute session cooldown (configurable) prevents repeated prompts during active management sessions. Touch ID can be globally toggled off in Settings.

System job protection

Jobs in /Library/LaunchAgents/ and user-level agents not created by LaunchPad are always read-only. All API write endpoints enforce is_managed = true before proceeding. LaunchPad-created plists include a LaunchPadManaged key for identification.

Import & Export P1

Backup and share your LaunchPad-managed jobs.

  • Export: Download a bundle of all managed job plists as a ZIP archive, or export individual job configurations as JSON
  • Import: Load plist files or LaunchPad JSON exports to recreate jobs on another machine
  • Migration: The export bundle includes all metadata (folder assignments, tags, notification preferences) alongside the plist files

Preferences P1

Global settings accessible from the dashboard sidebar.

SettingDescriptionDefault
Server portPort the dashboard binds to24680
Polling intervalFrequency of status checks and log capture30 seconds
Log retentionHow long execution logs are kept before pruning90 days
NotificationsGlobal toggle for macOS native failure notificationsEnabled
Touch IDRequire biometric confirmation for destructive opsEnabled
Touch ID cooldownSession duration before re-prompting5 minutes
ThemeDark mode (default) or light modeDark
Auto-startStart LaunchPad server on loginEnabled

Notifications P1

When a managed job exits with a non-zero exit code, LaunchPad sends a macOS native notification via Notification Center within 60 seconds of the failure.

Notification content

  • Title: "LaunchPad: Job Failed"
  • Body: Job label, exit code, and the first 100 characters of stderr
  • Action: Clicking the notification opens the dashboard to the failed job's detail view

In-app notification center

A bell icon in the dashboard header shows a chronological list of all failure events with read/unread indicators. Includes "Mark all read" and "Clear all" actions.

Per-job notification settings

  • Every failure (default) -- notify on each non-zero exit
  • After N consecutive failures -- suppress noise for flaky jobs
  • Disabled -- no notifications for this job

LaunchPad installs itself as a LaunchAgent that starts on login. The menubar icon provides at-a-glance status:

  • Green -- all jobs healthy
  • Yellow -- warnings detected
  • Red -- failures in the last 24 hours

Clicking the menubar icon shows a dropdown with: job status summary, "Open Dashboard" link, recently failed jobs, and a Quit option. The menubar polls /api/status every 60 seconds.