hammerspoonlisted
Install: claude install-skill wilbeibi/wilbeibi-skills
# hammerspoon
One-off action = one `hs -q -c '<lua>'` call. Lasting behavior (hotkeys, watchers, menubar) = a module in `~/.hammerspoon/`. Recipes: [REFERENCE.md](REFERENCE.md).
## Readiness
`hs -q -c 'return "ok"'` must print `ok`. If not:
- exit 69 / "can't access message port" → Hammerspoon not running (`open -a Hammerspoon`) or `hs.ipc` not loaded → ensure `require("hs.ipc")` is in `~/.hammerspoon/init.lua`; the pathwatcher auto-reloads config, retry after ~2s.
- `hs` binary missing → tell the user to run `hs.ipc.cliInstall("/opt/homebrew")` in the Hammerspoon console.
- Window/app calls silently no-op → `hs -c 'return hs.accessibilityState()'` must be true; if false, user grants it in System Settings → Privacy & Security → Accessibility.
## One-off mode
```bash
hs -q -c 'hs.application.launchOrFocus("Obsidian") return "ok"'
hs -q -t 15 -c '<anything touching AppleScript or many windows>' # default IPC timeout is 4s; busy main loop can also cause one-off "receive timeout" — retry
```
- `return` the final value or you get no output; tables print as addresses — `return hs.json.encode(tbl)` (`hs.geometry` rects need `.table`; NaN values make encode silently return nil — `tostring()` is the safe fallback).
- Single-quote the shell argument, double quotes inside Lua. Multiline: heredoc `hs -q <<'EOF' ... EOF` or `hs -q /path/file.lua` (path must start with `~`, `./`, or `/`).
- Exit codes: 65 = Lua error (message on stderr), 69 = not running / ipc missing.
- One-shot