A flexible command line tool for instantly deploying user interfaces for simple commands and scripts.
Suitcase is a command line tool that can be "programmed" to display a SwiftUI interface that can trigger commands and scripts.
It's similar to Shortcuts, but for macOS and driven by the command line.
Because of its SwiftUI underpinnings Suitcase is a first class Mac citizen. With out of the box support for, Dark Mode, Menubars and Drag and Drop.
Its power and flexibility come form the tried and trusted UNIX command line. Anything you can do in Terminal you can do in Suitcase, but with a UI and export the command as a .command
file, to check in with a project or share with the world.
- @SuitcaseCLI — Regular posts about updates and examples
- The Bazaar — Examples and documentation
- Impedimenta — Blog posts, links and related projects
- @ImpedimentaCode — Infrequent posts about other projects and tools
- @rjstelling — Frequent, irrelevant mostly technology and politics, open DMs
OVERVIEW: A flexible command line tool for instantly deploying user interfaces
for simple commands and scripts.
USAGE: Suitcase <subcommand>
OPTIONS:
--version Show the version.
-h, --help Show help information.
SUBCOMMANDS:
basic Launch a basic Suitcase process, that has a main menu
and an icon in the Dock when running.
utility Launch a utility Suitcase process, without a Dock
icon or main menu.
A basic
Suitcase process has a main menu and an icon in the Dock when running.
See the full documentation.
A utility
Suitcase process does not have a Dock icon or main menu. It consists of just a main window.
See the full documentation.
These examples are very basic but should give you a good idea of how you can use Suitcase. More details examples can be found at the Bazaar. If you have any questions please create an issue. If you create a command and you'd like to share it, open a PR at the Bazaar.
A simple example consisting of one button that when clicked calls the say
command. Watch the video of this example in action, there is a detailed say
example at the Suitcase Bazaar.
📝 Code
$ Suitcase --name="Demo App" --window-title="Hello World" \
--window-width="200" --window-height="200" \
--control-type="label" --control-title="Give a face to every voice…" \
--control-type="button" \
--control-title="🗣 Say hello" \
--control-action="/usr/bin/say Hello World"
A more advanced example using buttons and passing parameters to the say
command. A detailed explanation of War Games can be found at the Suitcase Bazaar.
📝 Code
$ Suitcase --name="War Games" \
--control-title="Shall we play a game?" \
--control-type="text-field" \
--control-identifier="say.textfield" \
--control-title="Daniel" \
--control-type="button" \
--control-group-identifier="g.btns" \
--control-action="/usr/bin/say" \
--control-action-parameter="-v,Daniel,say.textfield" \
--control-title="Samantha" \
--control-type="button" \
--control-group-identifier="g.btns" \
--control-action="/usr/bin/say" \
--control-action-parameter="-v,Samantha,say.textfield" \
--control-title="Veena" \
--control-type="button" \
--control-group-identifier="g.btns" \
--control-action="/usr/bin/say" \
--control-action-parameter="-v,Veena,say.textfield"
This example shows how to create menus and sub-menus. Actions can be attached to any menu item the same way as button
s. Watch the video of this example in action.
Menu items can also be assigned a keyboard shortcut. See the full documentation for more details.
📝 Code
$ Suitcase --name="Demo App" --window-title="Menus" \
--control-title="UUID" \
--control-type="label" --control-identifier="com.label.uuid" \
--menu-title="Action>Generate>UUID" \
--menu-action="/usr/bin/uuidgen" \
--menu-action-destination="com.label.uuid" \
--menu-title="Action>Copy UUID" \
--menu-shortcut="k" \
--menu-action="/usr/bin/printenv com.label.uuid | /usr/bin/pbcopy"
Hidden Files & Folders
This is a more involved example that uses defaults
to read the macOS user defaults system and use sed
to set a state label
. Watch the video of this example in action.
📝 Code
$ Suitcase --name="Hidden Finder Settings" \
--control-title="Hidden Files & Folders:" \
--control-group-identifier="com.finder.hidden" \
--control-type="label" \
--control-title="unknown" \
--control-group-identifier="com.finder.hidden" \
--control-type="label" \
--control-identifier="com.label.hidden.state" \
--control-title="Refresh" \
--control-group-identifier="com.finder.hidden" \
--control-type="button" \
--control-action="/usr/bin/defaults read com.apple.finder AppleShowAllFiles | /usr/bin/sed s/1/Visible/g;s/0/Hidden/g" \
--control-action-destination="com.label.hidden.state" \
--control-title="Enable" \
--control-type="button" \
--control-group-identifier="com.finder.hidden.buttons" \
--control-action="/usr/bin/defaults write com.apple.finder AppleShowAllFiles -bool TRUE & /usr/bin/killall Finder" \
--control-title="Disable" \
--control-type="button" \
--control-group-identifier="com.finder.hidden.buttons" \
--control-action="/usr/bin/defaults write com.apple.finder AppleShowAllFiles -bool FALSE & /usr/bin/killall Finder"
This is how the command would be run in Terminal.
$ defaults read com.apple.finder AppleShowAllFiles | sed 's/1/Visible/g;s/0/Hidden/g'
The button uses &
to run two commands, one to write to the user defaults and the second to relaunch the Finder:
$ defaults write com.apple.finder AppleShowAllFiles -bool TRUE
Kill the Finder and relaunch:
$ killall Finder
Any Suitcase command can be exported as a self running .command
file. You can double click this file to launch the Suitcase or share the file (it's just plain text).
Please create an issue.
Releases and News (@SuitcaseCLI) Richard Stelling (@rjstelling)