<p align="center">
<img src="branding/hero-16x9-1600x900.jpg" alt="Summon — deterministic app switching for macOS" width="800">
</p>
<h1 align="center">Summon</h1>
<p align="center">
<strong>Open, focus, and cycle macOS apps from your keyboard.</strong>
</p>
<p align="center">
<a href="#installation">Install</a> · <a href="#quick-start">Quick Start</a> · <a href="#usage">Usage</a> · <a href="#configuration">Configuration</a>
</p>
---
Summon is a tiny macOS command-line tool for keyboard-driven app switching.
Define your applications in `~/.config/summon/summon.toml`, wire them to your preferred hotkey tool, and use one command to launch, focus, or cycle through app windows.
```sh
summon terminal
summon browser
summon editor
```
Summon is designed to be fast, boring, and easy to keep in your dotfiles.
## Installation
```sh
cargo install summon-switcher
brew install liamwh/summon-switcher/summon-switcher
# from source, install to ~/bin and start the warm daemon path
just install
```
## Quick Start
Create `~/.config/summon/summon.toml`:
```toml
[settings]
cycle_when_focused = true
launch_if_not_running = true
[bindings.terminal]
app = "com.mitchellh.ghostty"
[bindings.browser]
app = "com.brave.Browser"
[bindings.editor]
app = "dev.zed.Zed"
```
Wire to your hotkey tool (e.g. [skhd](https://github.com/koekeishiya/skhd)):
```
cmd + alt + ctrl + shift - return : summon terminal
cmd + alt + ctrl + shift - b : summon browser
cmd + alt + ctrl + shift - z : summon editor
```
## Usage
```sh
summon <binding> # Launch, focus, or cycle the configured app
summon app <app> # Summon an app directly by name or bundle ID
summon list # List all configured bindings
summon config path # Print the active config file path
summon config check # Validate the config file
summon doctor # Check macOS permissions
summon daemon status # Inspect the optional warm daemon
summon inspect windows dev.zed.Zed --pretty
```
By default, `summon` will try the daemon first and fall back to direct mode if
the socket is unavailable. Set `SUMMON_DAEMON=off` to force direct mode, or
`SUMMON_DAEMON=required` to require the daemon.
## Configuration
Summon reads from `$XDG_CONFIG_HOME/summon/summon.toml` (defaults to `~/.config/summon/summon.toml`).
Each binding maps a name to an application target:
```toml
[bindings.terminal]
app = "com.mitchellh.ghostty"
cycle_when_focused = true
launch_if_not_running = true
```
Applications can be resolved by bundle identifier, name, or path:
```toml
[bindings.terminal]
app = "com.mitchellh.ghostty" # Bundle ID (preferred)
[bindings.preview]
app = "Preview" # App name
[bindings.custom]
app = "/Applications/My App.app" # Path
```
## How it works
1. Resolve the configured target application
2. If not running — launch it
3. If running but not focused — focus its most recent window
4. If already focused and `cycle_when_focused` is enabled — cycle to the next window
This makes repeated keypresses useful rather than redundant.
For the snappiest hot path, `just install` restarts a background daemon that
caches config and handles repeated invocations over a Unix socket. That keeps
keypresses off the cold CLI startup path while still preserving a direct-mode
fallback.
The daemon logs to `~/Library/Logs/summon/summond.log`. Use
`summon inspect windows <app> --pretty` to capture the live AX window state
that Summon will use for cycling.
## Integrations
Summon works with any tool that can execute a command. Example configs are in the [`examples/`](examples/) directory.
### skhd
Add to `~/.skhdrc`:
```
hyper - return : summon terminal
hyper - b : summon browser
hyper - z : summon editor
hyper - f : summon finder
```
See [`examples/skhdrc`](examples/skhdrc) for a complete example.
### Raycast
Copy the script commands from [`examples/raycast/`](examples/raycast/) to your Raycast scripts directory:
```sh
cp examples/raycast/summon-*.sh ~/.config/raycast/scripts/
```
### Shell aliases
Add to `~/.zshrc` or `~/.bashrc`:
```sh
alias st='summon terminal'
alias sb='summon browser'
alias se='summon editor'
```
See [`examples/shell-aliases.sh`](examples/shell-aliases.sh) for more.
### Other tools
Summon also works with [Karabiner-Elements](https://karabiner-elements.pqrs.org/), [Hammerspoon](https://www.hammerspoon.org/), [Alfred](https://www.alfredapp.com/), and [AeroSpace](https://github.com/nikitabobko/AeroSpace). Any tool that can run a shell command can invoke `summon <binding>`.
## License
Apache-2.0