├── LICENSE ├── README.md ├── Sandbox.alfredworkflow ├── bin ├── boot-shutdown ├── sdx-start └── sdx-stop ├── docs ├── adding-environment-variables.md ├── alfred-workflow.md ├── create-api-client.md ├── fetch-sandbox-uuid.md ├── img │ ├── create-client-id.png │ ├── security-background-items.png │ └── security-login-items.png ├── install-launch-agents.md ├── install-sfcc-ci.md └── test-sfcc-ci.md ├── install └── launchd ├── com.opensfcc.sandbox.plist └── com.opensfcc.sleepwatcher.plist /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 OpenSFCC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | Sandbox Launchd 4 | === 5 | 6 | > Automatically Start & Stop your Sandbox when your macOS device Boots, Shuts Down, Wakes & Sleeps. 7 | 8 | Requirements 9 | --- 10 | 11 | - [X] [Homebrew](https://brew.sh) 12 | - [X] [Node.js LTS](https://nodejs.org/en) 13 | 14 | Getting Setup 15 | --- 16 | 17 | > Download the source code and follow these instructions to get setup: 18 | 19 | [![Download](https://img.shields.io/badge/Download-121212.svg?logo=github&style=for-the-badge)](https://github.com/opensfcc/sandbox-launchd/releases/latest) 20 | 21 | ### Installation Steps 22 | 23 | 1. [Install SFCC-CI](docs/install-sfcc-ci.md) 24 | 2. [Create API Client](docs/create-api-client.md) 25 | 3. [Adding Environment Variables](docs/adding-environment-variables.md) 26 | 4. [Test SFCC-CI](docs/test-sfcc-ci.md) 27 | 5. [Fetch Sandbox UUID](docs/fetch-sandbox-uuid.md) 28 | 6. [Install Launch Agents](docs/install-launch-agents.md) 29 | 30 | [![Get Started](https://img.shields.io/badge/First_Step-1aa0db.svg?logo=github&style=for-the-badge)](docs/install-sfcc-ci.md) 31 | 32 | ### Extra Goodies 33 | 34 | If you happen to use [Alfred](https://www.alfredapp.com) on your computer, we are also releasing a [Custom Workflow](https://github.com/opensfcc/sandbox-launchd/raw/main/Sandbox.alfredworkflow) that allows you to Start & Stop your Sandbox, and use your mobile device to trigger your workflow remotely. 35 | 36 | [![Alfred Workflow](https://img.shields.io/badge/Alfred_Workflow-5C1F87.svg?logo=alfred&logoColor=white&style=for-the-badge)](docs/alfred-workflow.md) 37 | 38 | Contributing 39 | --- 40 | 41 | > Are you interested in making this tool better? Fork this Repository, and we'll gladly accept Pull Requests. 42 | 43 | [![Contribution Guide](https://img.shields.io/badge/Contribution_Guide-EEEEEE.svg?logo=github&logoColor=black&style=for-the-badge)](https://github.com/opensfcc/sandbox-launchd/blob/develop/.github/CONTRIBUTING.md) 44 | 45 | Disclaimer 46 | --- 47 | 48 | > The trademarks and product names of Salesforce®, including the mark Salesforce®, are the property of Salesforce.com. OpenSFCC is not affiliated with Salesforce.com, nor does Salesforce.com sponsor or endorse the OpenSFCC products or website. The use of the Salesforce® trademark on this project does not indicate an endorsement, recommendation, or business relationship between Salesforce.com and OpenSFCC. 49 | -------------------------------------------------------------------------------- /Sandbox.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensfcc/sandbox-launchd/a5174d53b993f4e914bcbc8af15bc3600a63afd3/Sandbox.alfredworkflow -------------------------------------------------------------------------------- /bin/boot-shutdown: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | function shutdown() 4 | { 5 | # Send Shutdown Signal to Sandbox in Background 6 | ~/.opensfcc/sdx-stop 7 | exit 0 8 | } 9 | 10 | function startup() 11 | { 12 | # Send Startup Signal to Sandbox in Background 13 | ~/.opensfcc/sdx-start 14 | 15 | tail -f /dev/null & 16 | wait $! 17 | } 18 | 19 | trap shutdown SIGTERM 20 | trap shutdown SIGKILL 21 | 22 | startup; 23 | -------------------------------------------------------------------------------- /bin/sdx-start: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | # Load NVM if Installed 4 | if [ -d $HOME/.nvm ]; then 5 | . $HOME/.nvm/nvm.sh 6 | . $HOME/.zshrc 7 | nvm use default 8 | fi 9 | 10 | # Set Variables 11 | LOGFILE=$HOME/.opensfcc/sandbox.log 12 | MAX_LINES=100 13 | 14 | # Alias sandbox to sfcc-ci for custom handling 15 | sandbox() { 16 | # Check if SFCC_SANDBOX_ID is set 17 | if [ -z "$SFCC_SANDBOX_ID" ]; then 18 | echo -e "\n❌ MISSING SFCC_SANDBOX_ID\n\n\033[0;2mPlease make sure you've added your environmental variables:\n\n› \033[0;36mhttps://github.com/opensfcc/sandbox-launchd\n" 19 | exit 1 20 | 21 | # Check if sfcc-ci is installed 22 | elif hash sfcc-ci 2>/dev/null; then 23 | sfcc-ci "$@" 24 | 25 | # Exit if sfcc-ci is not installed 26 | else 27 | echo -e "\n❌ MISSING SFCC-CI\n\n\033[0;2mPlease install & configure sfcc-ci:\n\n› \033[0;36mhttps://github.com/opensfcc/sandbox-launchd\n" 28 | exit 1 29 | fi 30 | } 31 | 32 | # Do a quick check on log size 33 | LINES=$(cat $LOGFILE | wc -l | xargs) 34 | OVERFLOW=$(( $LINES - $MAX_LINES )) 35 | 36 | # If log is too big, remove MAX_LINES from the top 37 | if (( $LINES > $MAX_LINES )); then 38 | sed -i '' "1,${OVERFLOW}d" $LOGFILE 39 | fi 40 | 41 | # Log Timestamp 42 | echo -e "\n[$(date +%F\ %T)] START" >> $LOGFILE 43 | 44 | # Authenticate to Sandbox 45 | sandbox client:auth >> $LOGFILE 46 | 47 | # Start Sandbox and wait for it to have `started` status 48 | sandbox sandbox:start --sandbox $SFCC_SANDBOX_ID --sync >> $LOGFILE 49 | 50 | # Send Notification to Developer that Sandbox is ready 51 | osascript -e 'display notification "Your sandbox is running and ready to use." with title "Sandbox Started" sound name "Morse"' 52 | -------------------------------------------------------------------------------- /bin/sdx-stop: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | # Load NVM if Installed 4 | if [ -d $HOME/.nvm ]; then 5 | . $HOME/.nvm/nvm.sh 6 | . $HOME/.zshrc 7 | nvm use default 8 | fi 9 | 10 | # Set Variables 11 | LOGFILE=$HOME/.opensfcc/sandbox.log 12 | 13 | # Alias sandbox to sfcc-ci for custom handling 14 | sandbox() { 15 | # Check if SFCC_SANDBOX_ID is set 16 | if [ -z "$SFCC_SANDBOX_ID" ]; then 17 | echo -e "\n❌ MISSING SFCC_SANDBOX_ID\n\n\033[0;2mPlease make sure you've added your environmental variables:\n\n› \033[0;36mhttps://github.com/opensfcc/sandbox-launchd\n" 18 | exit 1 19 | 20 | # Check if sfcc-ci is installed 21 | elif hash sfcc-ci 2>/dev/null; then 22 | sfcc-ci "$@" 23 | 24 | # Exit if sfcc-ci is not installed 25 | else 26 | echo -e "\n❌ MISSING SFCC-CI\n\n\033[0;2mPlease install & configure sfcc-ci:\n\n› \033[0;36mhttps://github.com/opensfcc/sandbox-launchd\n" 27 | exit 1 28 | fi 29 | } 30 | 31 | # Log Timestamp 32 | echo -e "\n[$(date +%F\ %T)] STOP" >> $LOGFILE 33 | 34 | # Authenticate to Sandbox 35 | sandbox client:auth >> $LOGFILE 36 | 37 | # Stop Sandbox ( no need to wait, just send the shutdown command ) 38 | sandbox sandbox:stop --sandbox $SFCC_SANDBOX_ID >> $LOGFILE 39 | 40 | # No need to send notification, developer is long gone 41 | -------------------------------------------------------------------------------- /docs/adding-environment-variables.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Adding Environment Variables 6 | === 7 | 8 | > We'll need the following Environmental Variables to be set before things will work. 9 | 10 | Add the following under the existing exports listed in your `~/.zshrc` 11 | 12 | ```bash 13 | # SFCC-CI Variables 14 | export SFCC_OAUTH_CLIENT_ID="1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" 15 | export SFCC_OAUTH_CLIENT_SECRET="my^super*secret+password" 16 | export SFCC_SANDBOX_ID="" 17 | ``` 18 | 19 | ### What do these do? 20 | 21 | * `SFCC_OAUTH_CLIENT_ID` - This is your "API Client" that was generated earlier 22 | * `SFCC_OAUTH_CLIENT_SECRET` - This is the password you entered earlier 23 | * `SFCC_SANDBOX_ID` - We'll be getting this in a few steps 24 | 25 | Now we need to reload our profile: 26 | 27 | ```bash 28 | source ~/.zshrc 29 | ``` 30 | 31 | --- 32 | 33 | [![Previous Step](https://img.shields.io/badge/Previous-121212.svg?logo=github&style=for-the-badge)](./create-api-client.md)   [![Next Step](https://img.shields.io/badge/Next_Step-1aa0db.svg?logo=github&style=for-the-badge)](./test-sfcc-ci.md) 34 | -------------------------------------------------------------------------------- /docs/alfred-workflow.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Alfred Workflow 6 | === 7 | 8 | > [Alfred](https://www.alfredapp.com/) is an award-winning app for macOS which boosts your efficiency with hotkeys, keywords, text expansion and more. Search your Mac and the web, and be more productive with custom actions to control your Mac. 9 | 10 | Installation 11 | --- 12 | 13 | [![Download Workflow](https://img.shields.io/badge/Download_Workflow-5C1F87.svg?logo=alfred&logoColor=white&style=for-the-badge)](https://github.com/opensfcc/sandbox-launchd/raw/main/Sandbox.alfredworkflow) 14 | 15 | ### Usage 16 | 17 | 1. Trigger Alfred and type `sdx` 18 | 2. Select `Start Sandbox` to start your sandbox 19 | 3. Select `Stop Sandbox` to stop your sandbox 20 | 21 | ### Remote Setup: `*` 22 | 23 | 1. Open Alfred 24 | 2. Click Remote Icon in Left Column 25 | 3. Click the `[+]` button at the bottom of the list to add a New Remote 26 | 4. Select: `Workflows` > `Sandbox` > `Sandbox` 27 | 5. You can now manage your sandbox from your phone ;) 28 | 29 | `*` **NOTE:** You will need a Powerpack license for this. It's 100% worth it ;) 30 | 31 | --- 32 | 33 | [![README](https://img.shields.io/badge/README-121212.svg?logo=github&style=for-the-badge)](../README.md) 34 | -------------------------------------------------------------------------------- /docs/create-api-client.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Create API Client 6 | === 7 | 8 | > If you have not already created your API Client ID, you'll need to do that to use this tool. 9 | 10 | Sorry in advance for this one. It's a beast, but you only have to do it once ;) 11 | 12 | 1. Visit the [API Client](https://account.demandware.com/dw/account/APIAdmin) Tab on your SFCC [Account Manager](https://account.demandware.com/dw/account/Home) `*` 13 | 2. Click `Add API Client` button in the top right 14 | 3. For `Display Name`, enter something that identifies your Sandbox, e.g., `ods-jane-doe` 15 | 4. For `Description`, write something helpful, e.g., `ODS API User for Jane Doe` 16 | 5. Enter a secure password for `Password` ( this is your `SFCC_OAUTH_CLIENT_SECRET` ) 17 | 6. For `Access Control`, check the `Enabled` checkbox 18 | 7. Click the `Add` button on `Organizations` 19 | 8. Select the checkbox next to your Organization's name 20 | 9. Click the `Add` button to Assign the Organization 21 | 10. Click the `Add` button on `Roles` 22 | 11. Select the checkbox for `Sandbox API User` 23 | 12. Click the `Add` button to Assign the Role 24 | 13. Click the Filter Icon to the right of the `No role scope defined` 25 | 14. Select your Organization from the list 26 | 15. Choose your Sandbox from the select list 27 | 16. Click the `Add` button to add your Sandbox as a Sandbox API User 28 | 17. Set `Token Endpoint Auth Method` to `client_secret_post` 29 | 18. Set `Access Token Format` to `UUID - Deprecated. JWT recommended` 30 | 19. You can leave everything else with default settings 31 | 20. Press `Save` 32 | 33 | After Saving, you will be returned to the API Clients ID list. Find the one you just created and open it. At the top of the page, you will see your `API Client`. 34 | 35 | *Screenshot:* 36 | 37 | screenshot 38 | 39 | `*` **NOTE:** If you do not see the `API CLient` tab after logging into your Account Manager, contact your Administrator to get access. You will not be able to use this tool without these credentials. They may be able to set this up for you using the instructions above if they are unwilling to give you direct access. 40 | 41 | ### You will only need the following information to use this tool: 42 | 43 | * `SFCC_OAUTH_CLIENT_ID` ( API Client ID ) 44 | * `SFCC_OAUTH_CLIENT_SECRET` ( Password used when creating the Client ID ) 45 | * `SFCC_SANDBOX_ID` ( Sandbox UUID used by this tool ) 46 | 47 | --- 48 | 49 | [![Previous Step](https://img.shields.io/badge/Previous-121212.svg?logo=github&style=for-the-badge)](./install-sfcc-ci.md)   [![Next Step](https://img.shields.io/badge/Next_Step-1aa0db.svg?logo=github&style=for-the-badge)](./adding-environment-variables.md) 50 | -------------------------------------------------------------------------------- /docs/fetch-sandbox-uuid.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Fetch Sandbox UUID 6 | === 7 | 8 | > Now that we've verified everything is working with SFCC-CI, we can get our Sandbox UUID. 9 | 10 | Let's get a list of sandboxes our API Client ID has permission to access: 11 | 12 | ```bash 13 | sfcc-ci sandbox:list 14 | ``` 15 | 16 | Using the table generated in the command above, look for your sandbox number in the `instance` column. For example, if your sandbox starts with `abcd-001` your `instance` will be `001`. 17 | 18 | Copy the `id` from the `id` column for your sandbox. 19 | 20 | Now we can paste our Sandbox UUID as the value for `SFCC_SANDBOX_ID` in our `~./zshrc` file. 21 | 22 | ```bash 23 | export SFCC_SANDBOX_ID="9p8o7n6m-5l4k-3j2i-1h0g-9f8e7d6c5b4a" 24 | ``` 25 | 26 | Now let's reload our profile again with this update: 27 | 28 | ```bash 29 | source .zshrc 30 | ``` 31 | 32 | --- 33 | 34 | [![Previous Step](https://img.shields.io/badge/Previous-121212.svg?logo=github&style=for-the-badge)](./test-sfcc-ci.md)   [![Next Step](https://img.shields.io/badge/Next_Step-1aa0db.svg?logo=github&style=for-the-badge)](./install-launch-agents.md) 35 | -------------------------------------------------------------------------------- /docs/img/create-client-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensfcc/sandbox-launchd/a5174d53b993f4e914bcbc8af15bc3600a63afd3/docs/img/create-client-id.png -------------------------------------------------------------------------------- /docs/img/security-background-items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensfcc/sandbox-launchd/a5174d53b993f4e914bcbc8af15bc3600a63afd3/docs/img/security-background-items.png -------------------------------------------------------------------------------- /docs/img/security-login-items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensfcc/sandbox-launchd/a5174d53b993f4e914bcbc8af15bc3600a63afd3/docs/img/security-login-items.png -------------------------------------------------------------------------------- /docs/install-launch-agents.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Install Launch Agents 6 | === 7 | 8 | > All we have left to do now is install the Launch Agents to handle starting & stopping your sandbox. 9 | 10 | Make sure you are in the root of this project, and run the installer: 11 | 12 | ```bash 13 | ./install 14 | ``` 15 | 16 | Security Overview 17 | --- 18 | 19 | > Your IT Department might want to know a few things about what this tool is doing. 20 | 21 | ### Overview 22 | 23 | **NOTE:** This tool does not require a superuser or root-level access to install. 24 | 25 | Our [./install](../install) script does the following: 26 | 27 | 1. Uses [Homebrew](https://brew.sh) to install [sleepwatcher](https://formulae.brew.sh/formula/sleepwatcher) to add event listeners for Awake & Sleep states 28 | 2. Adds [sdx-start](../bin/sdx-start) bash script to start a Sandbox after the computer boots or wakes up 29 | 3. Adds [sdx-stop](../bin/sdx-stop) bash script to stop a Sandbox when the computer shuts down or goes to sleep 30 | 4. Adds [boot-shutdown](../bin/boot-shutdown) bash script to call above scripts on shutdown and boot 31 | 5. Adds [com.opensfcc.sleepwatcher.plist](../launchd/com.opensfcc.sleepwatcher.plist) Launch Agent for Sleepwatcher events 32 | 6. Adds [com.opensfcc.sandbox.plist](../launchd/com.opensfcc.sandbox.plist) Launch Agent for Boot and Shutdown events 33 | 34 | ### Installation Prompts 35 | 36 | After running the installer, you will see a notice for a new `Background Items Added` entry for [boot-shutdown](../bin/boot-shutdown). This was registered by the [com.opensfcc.sandbox.plist](../launchd/com.opensfcc.sandbox.plist) Launch Agent when we requested to be notified as the computer started or was about to shut down. 37 | 38 | Clicking this notice will open the Login Items, where our [boot-shutdown](../bin/boot-shutdown) script is listed. 39 | 40 | ![background-items](./img/security-background-items.png "background-items") 41 | 42 | Clicking this notice will open the Login Items, where you will see our [boot-shutdown](../bin/boot-shutdown) script listed. 43 | 44 | ![login-items](./img/security-login-items.png "login-items") 45 | 46 | --- 47 | 48 | [![Previous Step](https://img.shields.io/badge/Previous-121212.svg?logo=github&style=for-the-badge)](./fetch-sandbox-uuid.md)   [![Next Step](https://img.shields.io/badge/All_Done-1aa0db.svg?logo=github&style=for-the-badge)](../README.md) 49 | -------------------------------------------------------------------------------- /docs/install-sfcc-ci.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Install SFCC-CI 6 | === 7 | 8 | > We'll need to install Salesforce's SFCC-CI tool to connect to our sandbox. 9 | 10 | Install Salesforce Commerce Cloud CLI Globally 11 | 12 | ```bash 13 | npm install -g sfcc-ci 14 | ``` 15 | 16 | Now we can check that it was installed correctly and verify we get the help message: 17 | 18 | ```bash 19 | sfcc-ci --help 20 | ``` 21 | 22 | --- 23 | 24 | [![Previous Step](https://img.shields.io/badge/README-121212.svg?logo=github&style=for-the-badge)](../README.md)   [![Next Step](https://img.shields.io/badge/Next_Step-1aa0db.svg?logo=github&style=for-the-badge)](./create-api-client.md) 25 | -------------------------------------------------------------------------------- /docs/test-sfcc-ci.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://avatars.githubusercontent.com/u/151680118?s=200&v=4 "Logo") 2 | 3 | **[↤ Getting Started](../README.md)** 4 | 5 | Test SFCC-CI 6 | === 7 | 8 | > We should be ready to test that we have SFCC-CI installed correctly. 9 | 10 | Let's check that our API Client Authentication information was entered correctly: 11 | 12 | ```bash 13 | sfcc-ci client:auth 14 | ``` 15 | 16 | If you did not get a response of `Authentication succeeded`, head back through the first few steps and ensure you set up everything correctly. 17 | 18 | --- 19 | 20 | [![Previous Step](https://img.shields.io/badge/Previous-121212.svg?logo=github&style=for-the-badge)](./adding-environment-variables.md)   [![Next Step](https://img.shields.io/badge/Next_Step-1aa0db.svg?logo=github&style=for-the-badge)](./fetch-sandbox-uuid.md) 21 | -------------------------------------------------------------------------------- /install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e '\n\033[0;32mSANDBOX LAUNCHD\033[0m\n' 4 | 5 | # Install Sleepwatcher using Homebrew if not installed 6 | INSTALLED=$(brew list | grep sleepwatcher) 7 | if [ -z "$INSTALLED" ]; then 8 | echo '✔ Installing Sleepwatcher using Homebrew' 9 | brew install sleepwatcher 10 | fi 11 | 12 | # Create Launch Daemon 13 | echo '✔ Creating Launch Agents' 14 | mkdir -p $HOME/Library/LaunchAgents 15 | cp launchd/*.plist $HOME/Library/LaunchAgents/ 16 | 17 | # Copy Wake & Sleep files to home directory acording to instructions 18 | echo '✔ Copying Program Files' 19 | mkdir -p $HOME/.opensfcc 20 | cp bin/boot-shutdown $HOME/.opensfcc/boot-shutdown 21 | cp bin/sdx-stop $HOME/.opensfcc/sdx-stop 22 | cp bin/sdx-start $HOME/.opensfcc/sdx-start 23 | 24 | # Replace Relative Path with Absolute Path 25 | sed -i '' "s|~|$HOME|" $HOME/Library/LaunchAgents/com.opensfcc.*.plist 26 | sed -i '' "s|~|$HOME|" $HOME/.opensfcc/boot-shutdown 27 | 28 | # Unload Launch Daemon if Loaded 29 | LOADED=$(launchctl list | grep com.opensfcc) 30 | if [ -n "$LOADED" ]; then 31 | launchctl unload -w $HOME/Library/LaunchAgents/com.opensfcc.sleepwatcher.plist 32 | launchctl unload -w $HOME/Library/LaunchAgents/com.opensfcc.sandbox.plist 33 | fi 34 | 35 | # Load Launch Daemon 36 | echo '✔ Loading Launch Agents' 37 | launchctl load -w $HOME/Library/LaunchAgents/com.opensfcc.sleepwatcher.plist 38 | launchctl load -w $HOME/Library/LaunchAgents/com.opensfcc.sandbox.plist 39 | 40 | # Set Permissions on Program Files 41 | chmod u+x $HOME/.opensfcc/boot-shutdown 42 | chmod u+x $HOME/.opensfcc/sdx-* 43 | 44 | # Reset Log File 45 | cat /dev/null > $HOME/.opensfcc/sandbox.log 46 | 47 | # All Done :) 48 | echo -e '\n✅ Installation Complete!\n' 49 | -------------------------------------------------------------------------------- /launchd/com.opensfcc.sandbox.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | 7 | Label 8 | com.opensfcc.sandbox 9 | ProgramArguments 10 | 11 | ~/.opensfcc/boot-shutdown 12 | 13 | RunAtLoad 14 | 15 | KeepAlive 16 | 17 | LaunchOnlyOnce 18 | 19 | StandardOutPath 20 | ~/.opensfcc/sandbox.log 21 | StandardErrorPath 22 | ~/.opensfcc/sandbox.log 23 | ExitTimeOut 24 | 600 25 | 26 | 27 | -------------------------------------------------------------------------------- /launchd/com.opensfcc.sleepwatcher.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | 7 | Label 8 | com.opensfcc.sleepwatcher 9 | ProgramArguments 10 | 11 | /opt/homebrew/opt/sleepwatcher/sbin/sleepwatcher 12 | --verbose 13 | --sleep 14 | ~/.opensfcc/sdx-stop 15 | --wakeup 16 | ~/.opensfcc/sdx-start 17 | --displaysleep 18 | ~/.opensfcc/sdx-stop 19 | --displaywakeup 20 | ~/.opensfcc/sdx-start 21 | 22 | RunAtLoad 23 | 24 | KeepAlive 25 | 26 | StandardOutPath 27 | ~/.opensfcc/sandbox.log 28 | StandardErrorPath 29 | ~/.opensfcc/sandbox.log 30 | 31 | 32 | --------------------------------------------------------------------------------