This is just something I asked Gemini out of curiosity for now. I haven't tried any of this yet.
1
Turning a script into a .app bundle is a great way to give your custom tools a native feel, complete with an icon and the ability to pin them to your Dock.
The most robust way to do this on macOS is using Automator. It handles the underlying folder structure (the "wrapper") for you.
Step 1: Create the Wrapper with Automator
- Open Automator (found in your Applications folder).
- Select New Document and choose Application as the type.
- In the search bar on the left, type "run shell script."
- Drag and drop the "Run Shell Script" action into the main workflow area on the right.
- Paste your script code directly into the box.
- Tip: Ensure the shell is set correctly (usually
/bin/zshor/bin/bash).
- Tip: Ensure the shell is set correctly (usually
- Go to File > Save, name your app, and save it to your Applications folder.
Step 2: Make it Look Professional (Optional)
A generic robot icon is boring. You can easily swap it for something custom:
- Find an image you like (PNG or ICNS) and open it in Preview.
- Press Cmd + A (Select All) then Cmd + C (Copy).
- Find your new
.appin Finder, right-click it, and select Get Info. - Click the small icon at the very top-left of the Info window so it has a blue highlight.
- Press Cmd + V (Paste).
The "Manual" Way (Advanced)
If you prefer the command line, macOS apps are actually just specially structured directories. You can build one manually like this:
Create the structure:
mkdir -p MyApp.app/Contents/MacOS
Move your script: Move your script into that MacOS folder and rename it to match the app name (e.g., MyApp).
Make it executable:
chmod +x MyApp.app/Contents/MacOS/MyApp
Note: Manual bundles often need a Info.plist file inside the Contents folder to tell macOS which file to execute first. Using Automator (Step 1) is generally much smoother because it generates this metadata for you.
Since you're interested in the "Manual" route, we're going to dive into the Info.plist. Think of this file as the app's "identity card"—it tells macOS exactly what to do when you double-click the icon.
1. Creating the Info.plist
Inside your MyApp.app/Contents/ folder (next to the MacOS folder), create a file named Info.plist. Copy and paste this XML structure into it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>MyApp</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
<key>CFBundleIdentifier</key>
<string>com.yourname.myapp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
</dict>
</plist>
Key Details:
CFBundleExecutable: This must match the name of the script you put inContents/MacOS/exactly.CFBundleIdentifier: A unique string (usually reverse DNS style) to help macOS keep track of preferences.
2. Adding a "Success" Notification
To make your app feel alive, you can have it send a native macOS notification when the script finishes. Add this line to the very end of your shell script:
osascript -e 'display notification "Task completed successfully!" with title "MyApp"'
3. The Final Directory Structure
Your final "Manual" app should look exactly like this hierarchy:
MyApp.app/
Contents/
Info.plist
MacOS/
MyApp (Your executable script)
Resources/
icon.icns (Optional icon file)
Troubleshooting Tip: Permissions:
- If the app doesn't launch, it’s usually because the script isn't "executable." Open your terminal and run:
chmod +x /Path/To/Your/MyApp.app/Contents/MacOS/MyApp