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": false, "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, off by default. Turn on tiling.enabled (or pick tiling in setup) and 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.