{"id":32146952,"url":"https://github.com/emorydunn/launchagent","last_synced_at":"2026-02-21T01:03:43.053Z","repository":{"id":31633905,"uuid":"122115826","full_name":"emorydunn/LaunchAgent","owner":"emorydunn","description":"Programmatically create and maintain launchd agents and daemons without manually building Property Lists. ","archived":false,"fork":false,"pushed_at":"2022-04-06T22:09:03.000Z","size":325,"stargazers_count":63,"open_issues_count":2,"forks_count":14,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-10-16T22:46:20.711Z","etag":null,"topics":["launchagent","launchd","macos","swift","swift-package-manager"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emorydunn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-19T20:20:28.000Z","updated_at":"2025-10-03T22:22:39.000Z","dependencies_parsed_at":"2022-08-30T17:41:47.510Z","dependency_job_id":null,"html_url":"https://github.com/emorydunn/LaunchAgent","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/emorydunn/LaunchAgent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorydunn%2FLaunchAgent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorydunn%2FLaunchAgent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorydunn%2FLaunchAgent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorydunn%2FLaunchAgent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emorydunn","download_url":"https://codeload.github.com/emorydunn/LaunchAgent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emorydunn%2FLaunchAgent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279439910,"owners_count":26170699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-17T02:00:07.504Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["launchagent","launchd","macos","swift","swift-package-manager"],"created_at":"2025-10-21T08:35:02.566Z","updated_at":"2025-10-21T08:35:03.585Z","avatar_url":"https://github.com/emorydunn.png","language":"Swift","readme":"# LaunchAgent\n\n![SwiftPM] ![Swift5.2] ![license] ![build] ![coverage]\n\n[SwiftPM]: https://img.shields.io/badge/SwiftPM-compatible-success.svg\n[swift]: https://developer.apple.com/swift/\n[Swift5.2]: https://img.shields.io/badge/swift-5.2-orange.svg?style=flat\n[spm]: https://swift.org/package-manager/\n[license]: https://img.shields.io/github/license/emorydunn/LaunchAgent.svg?style=flat\n[build]: https://github.com/emorydunn/LaunchAgent/workflows/Swift/badge.svg\n[docs]: https://emorydunn.github.io/LaunchAgent/\n[coverage]: https://emorydunn.github.io/LaunchAgent/badge.svg\n\nLaunchAgent provides an easy way to pragmatically create and maintain [`launchd`][launchd] agents and daemons without needing to manually build Property Lists.\n\nTake a look at the full [documentation][docs].\n\n[launchd]: http://www.launchd.info\n\n## LaunchAgent\n\nA LaunchAgent can be created with either an array of program arguments:\n```swift\nLaunchAgent(label: \"local.PythonServer\", program: [\"python\", \"-m\", \"SimpleHTTPServer\", \"8000\"])\n```\n\nor with variadic parameters:\n```swift\nLaunchAgent(label: \"local.PythonServer\", program: \"python\", \"-m\", \"SimpleHTTPServer\", \"8000\")\n```\n\nThe agent can also be created with only a label, but will be invalid if loaded:\n```swift\nLaunchAgent(label: \"local.PythonServer\")\n```\n\nWhen creating a new agent it needs to be written to disk:\n\n```swift\nlet agent = LaunchAgent(label: \"local.PythonServer\", program: \"python\", \"-m\", \"SimpleHTTPServer\", \"8000\")\n\ndo {\n    try LaunchControl.shared.write(agent)\n    try agent.load()\n    agent.start()\n} catch {\n    print(\"Unexpected error:\" error)\n}\n```\n\n### Using LaunchControl to read and write LaunchAgents\n\nThe `LaunchControl` class can read agents from and write agents to `~/Library/LaunchAgents`.\nWhen using either method the `url` of the loaded agent will be set.\n\n### Controlling LaunchAgents\n\nLaunchAgent has `load()`, `unload()`, `start()`, `stop()`, and `status()` methods which do what they say on the tin.\n\nLoad \u0026 unload require the agent's URL parameter to be set, or `launchctl` won't be able to locate them.\nStart, stop, and status are called based on the label.\n\n\n## Supported Keys\n\nLaunchAgent does not currently support all keys, and there are some caveats to some keys it does support.\n\nMost parameters in the `LaunchAgent` class are optional, and setting `nil` will remove the key from the encoded plist.\nSome keys use their own type to encapsulate a complex dictionary value.\n\n## Basic Config\n| Key Name         | Key type | Supported | Notes |\n|------------------|----------|-----------|-------|\n| Label            | String   | true      | |\n| Disabled         | String   | true      | |\n| Program          | String   | true      | |\n| ProgramArguments | [String] | true      | |\n| EnableGlobbing   | Bool     | true      | deprecated in macOS |\n\n### Program\n| Key Name             | Key type         | Supported | Notes |\n|----------------------|------------------|-----------|-------|\n| workingDirectory     | String           | true      | |\n| standardInPath       | String           | true      | |\n| standardOutPath      | String           | true      | |\n| standardErrorPath    | String           | true      | |\n| environmentVariables | [String: String] | true      | |\n\n### Run Conditions\n| Key Name              | Key type              | Supported | Notes |\n|-----------------------|-----------------------|-----------|-------|\n| runAtLoad             | Bool                  | true     | |\n| startInterval         | Int                   | true     | |\n| startCalendarInterval | StartCalendarInterval | true     | |\n| startOnMount          | Bool                  | true     | |\n| onDemand              | Bool                  | true     | |\n| keepAlive             | Bool                  | true     | |\n| watchPaths            | [String]              | true     | |\n| queueDirectories      | [String]              | true     | |\n\n### Security\n| Key Name      | Key type | Supported | Notes |\n|---------------|----------|-----------|-------|\n| umask         | Int      | true      | Use `FilePermissions.umaskDecimal` to get a valid value |\n| sessionCreate | Bool     | true      | |\n| groupName     | String   | true      | |\n| userName      | String   | true      | |\n| initGroups    | Bool     | true      | |\n| rootDirectory | String   | true      | |\n\n### Run Constraints\n| Key Name               | Key type | Supported | Notes |\n|------------------------|----------|-----------|-------|\n| launchOnlyOnce         | Bool     | true      | |\n| limitLoadToSessionType | [String] | true      | Always encodes as an array |\n| limitLoadToHosts       | [String] | true      | |\n| limitLoadFromHosts     | [String] | true      | |\n\n\n### Control\n| Key Name            | Key type           | Supported | Notes |\n|---------------------|--------------------|-----------|-------|\n| AbandonProcessGroup | Bool               | true      |       |\n| EnablePressuredExit | Bool               | true      |       |\n| EnableTransactions  | Bool               | true      |       |\n| ExitTimeOut         | Int                | true      |       |\n| inetdCompatibility  | inetdCompatibility | true      |       |\n| HardResourceLimits  | ResourceLimits     | true      |       |\n| SoftResourceLimits  | ResourceLimits     | true      |       |\n| TimeOut             | Int                | true      |       |\n| ThrottleInterval    | Int                | true      |       |\n\n### IPC\n| Key Name     | Key type               | Supported | Notes |\n|--------------|------------------------|-----------|-------|\n| MachServices | [String: MachService]  | true      |       |\n| Sockets      |                        | false     |       |\n\n\n### Debug\n| Key Name        | Key type | Supported | Notes |\n|-----------------|----------|-----------|-------|\n| Debug           | Bool     | true      | Deprecated |\n| WaitForDebugger | Bool     | true      |            |\n\n### Performance\n| Key Name                | Key type         | Supported | Notes |\n|-------------------------|------------------|-----------|-------|\n| LegacyTimers            | Bool             | true      | |\n| LowPriorityIO           | Bool             | true      | |\n| LowPriorityBackgroundIO | Bool             | true      | |\n| Nice                    | Int              | true      | |\n| ProcessType             | ProcessType enum | true      | |\n\n\n## Custom Key Classes\n\n### StartCalendarInterval\n\nThe `StartCalendarInterval` encapsulates the dictionary for setting calendar-based job intervals.\nBy default all values are set to `nil`, meaning the job will run on any occurrence of that value.\n\nThe Month and Weekday keys are represented by enums for each month and week, respectively.\nDay, Hour, and Minute values are simply integers. They are checked for validity in their\nrespective time ranges, and will be set to the minimum or maximum value depending on which way they were out of bounds.\n\n## inetdCompatibility\n\nEncapsulates the `inetdCompatibility` `wait` key.\n\n## ResourceLimits\n\nEncapsulates the SoftResourceLimits and HardResourceLimits keys:\n\n- cpu\n- core\n- data\n- fileSize\n- memoryLock\n- numberOfFiles\n- numberOfProcesses\n- residentSetSize\n- stack\n\n## FilePermissions\n\nIndividual permission Unix bits for read, write, and execute.\n\n## Unix Permissions\n- Read: 4\n- Write: 2\n- Execute: 1\n\nIn addition you can get the [umask](https://ss64.com/osx/umask.html) value.\n\nWhen setting permissions for a LaunchAgent use `.umaskDecimal` to get the value.\nIf you're reading a LaunchAgent `FilePermissions(umask:)` will read in the decimal so the permissions can be updated.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femorydunn%2Flaunchagent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femorydunn%2Flaunchagent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femorydunn%2Flaunchagent/lists"}