Drop an executable into ~/.config/scuttlarr/scripts/ and its trigger word joins the launcher grammar — no restart, no store, no manifest file. Any language. The bundled scripts (json, ip) are reference implementations and yours to edit.
<script> manifest — print a JSON manifest to stdout, exit 0
{
"trigger": "uuid",
"name": "UUID",
"description": "Generate a v4 UUID"
}<script> query <args> — called on every keystroke (debounced)
{
"items": [
{
"title": "Copy 3f9c1e2a-7b4d-4c8e-9a1f-2d6b8e4c0a55",
"subtitle": "v4 · fresh every keystroke",
"action": { "type": "copy", "value": "3f9c1e2a-7b4d-4c8e-9a1f-2d6b8e4c0a55" }
}
]
}copy puts text on the clipboard, open opens a URL, file or app, none is informational. altAction runs on ⌥⏎.clip is built-in and can’t be claimed.sys.path[0] — a script named json.py shadows the stdlib. Bundled scripts del sys.path[0] first; do the same.Network is your business for scripts: fetch what you like, and mind the timeouts above.
Everything lives in ~/.config/scuttlarr/config.json — watched and hot-applied, in sync with the settings window both ways. Themes are token overlays; unknown names fall back safely so a hand-edit can’t blank the UI.
{
"theme": "scuttlarr",
"themes": { "my-theme": { "accent": "#ff176c" } },
"bar": {
"enabled": true,
"layout": {
"left": [{ "id": "workspaces" }, { "id": "agents" }, { "id": "frontApp" }],
"center": [{ "id": "clock" }],
"right": [{ "id": "wifi" }, { "id": "battery" }]
}
},
"agents": { "askMode": false, "askProvider": "claude" },
"desktop": {
"tiling": { "enabled": true, "managed": true, "modifier": "alt", "gaps": 8,
"workspaces": 6, "float": ["com.raycast.macos"] },
"borders": { "enabled": false, "width": 5, "style": "round" },
"cornerRadius": null
}
}Bar modules live in explicit left / center / right zones and render in the order you list them. The clock is an ordinary module — put it wherever you like. Displays with a notch have no usable center, so they take an optional bar.notchedLayout of the same shape; without one, the main layout applies with the center folded into the head of the right zone.
desktop is the tiling layer: scuttlarr renders ~/.config/aerospace/aerospace.toml from these few knobs and reloads AeroSpace live. Set tiling.managed to false and the file is yours — scuttlarr never writes it again. Borders (JankyBorders) are opt-in from Settings → Desktop and take their colours from the theme; cornerRadius sets macOS’s hidden window-corner default (1–26, apps relaunch to pick it up).
Some trigger words open a full keyboard-driven TUI panel inside the launcher window instead of returning rows. They fuzzy-match like apps, so you don’t have to type them exactly. Esc walks back; focus returns exactly where it was — including over a full-screen app.
usage ⏎ and agents ⏎ are gated on the agent settings — both are off until you turn them on.
No installer, no daemons left behind. Four paths and it’s gone:
$ rm -rf /Applications/scuttlarr.app \
~/.config/scuttlarr \
~/Library/Application\ Support/com.mitchmalone.scuttlarr \
~/Library/LaunchAgents/scuttlarr.plistInstalled with Homebrew? brew uninstall handles the app; the three dotfile paths are still yours to remove. AeroSpace (installed alongside as a cask dependency) and JankyBorders (if you opted in) stay until you brew uninstall them too — ~/.config/aerospace is only scuttlarr’s if its first line says so.