spatie/scotty
Scotty is a beautiful SSH task runner for running scripted tasks on remote servers. Define tasks and macros in a simple Scotty.sh (bash + annotations), then run them with clear output. Fully compatible with Laravel Envoy as a drop-in replacement.
scotty run deploy
scotty run cloneRepository
Scotty shows each task as it runs, with a step counter, elapsed time, and the command that's currently executing:

If a task fails, Scotty shows the output and stops. You'll immediately see what went wrong:

Want to see what would happen without actually running anything? Use --pretend:
scotty run deploy --pretend
This shows the SSH commands Scotty would execute, without connecting to any server.
By default, Scotty stops at the first failed task. If you want it to keep going regardless:
scotty run deploy --continue
If you don't need to see all the output and just want to know whether things passed:
scotty run deploy --summary
This hides task output and only shows results. Failed tasks always show their output, even in summary mode.
Declare every option you want to accept at the top of your Scotty.sh file with # [@option](https://github.com/option). There are three forms:
# [@option](https://github.com/option) staging # boolean flag: $STAGING='1' when --staging is passed, unset otherwise
# [@option](https://github.com/option) branch=main # optional value with a default: $BRANCH='main' unless overridden
# [@option](https://github.com/option) tag= # required value: scotty errors if --tag=... isn't passed
scotty run deploy --branch=develop --tag=v1.2 --staging
An option named branch is exposed to your tasks as $BRANCH. The same rule applies to the CLI flag, the environment variable Scotty looks up, and the assignment written into the script preamble: each option has exactly one canonical bash name.
The transformation is:
release-name → release_name)release_name → RELEASE_NAME)So # [@option](https://github.com/option) release-name=latest declares a CLI flag --release-name=..., an env var $RELEASE_NAME, and a script variable $RELEASE_NAME — all one and the same. Flags that aren't declared are rejected with The "--foo" option does not exist.
For value options, Scotty resolves each variable in this order:
--branch=develop or --release-name=v42)BRANCH=develop scotty run deploy, RELEASE_NAME=v42 scotty run deploy)# [@option](https://github.com/option) branch=main)Boolean flags only read from the CLI — $STAGING is unset unless --staging was passed on this invocation.
Note:
[@option](https://github.com/option)declarations are currently supported in the Scotty.sh (bash) format. Blade-format files ignore[@option](https://github.com/option)and continue to forward any passed CLI flag as a Blade variable.
Sometimes you want to take a quick look at the server halfway through a deploy, or you just want to slow things down and watch each step more carefully. Press p at any point during execution. Scotty finishes the current task and then waits.

Press Enter to continue with the next task, or Ctrl+C if you want to stop entirely.
You can press Ctrl+C at any time to cancel. Scotty restores the terminal and exits cleanly. Everything that was already output stays in your scrollback, so you can scroll up to see what happened.
To see all available tasks and macros in your file:
scotty tasks

You can quickly SSH into any server defined in your Scotty file:
scotty ssh
scotty ssh remote
If only one server is defined, Scotty connects to it directly. With multiple servers, you'll get a selection prompt.
scotty init
This prompts you to choose a format (bash or Blade) and a server host, then creates the file for you.
How can I help you explore Laravel packages today?