Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    whilp

    hammerspoon

    whilp/hammerspoon
    Productivity
    9
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Configure and manage Hammerspoon automation, app launching, and window switching...

    SKILL.md

    Hammerspoon configuration skill

    Overview

    Manage Hammerspoon configuration for macOS automation including app launching, window switching, emoji/symbol pickers, and leader modal. Window management is handled by AeroSpace.

    Configuration locations

    • Config directory: ~/.config/hammerspoon/
    • Symlink: ~/.hammerspoon → ~/.config/hammerspoon/
    • CLI tool: hs (installed via hs.ipc.cliInstall() in init.lua)

    Current modules

    Core infrastructure

    hyper-key.lua - Inline hyper key implementation

    • No spoon dependencies
    • Provides HyperKey.new(mods) constructor
    • Binding methods: bind(key):toFunction(name, fn) and bind(key):toApplication(app)
    • Tracks bindings in self.bindings table

    init.lua - Main entry point

    • Calls hs.ipc.cliInstall() to enable CLI access
    • Defines hyper modifier: {cmd, ctrl, alt, shift}
    • Loads window-switcher and sets up cmd+space and cmd+tab bindings
    • Loads notch-clock with 4-minute offset
    • Loads leader modal with emoji and symbol pickers

    Leader modal system

    leader-modal.lua - Modal keybinding system

    • Timeout-based modal (default 3000ms)
    • Shows on-screen hints for available bindings
    • Supports nested leader keys
    • Sticky mode for repeated actions

    leader-dsl.lua - DSL for defining leader bindings

    • Leader(key, description, bindings) - Define leader menu
    • Bind(key, description, action, options) - Define action
    • Actions can be functions, shell commands, or mode transitions
    • Automatically registers clues from ~/.config/hammerspoon/clues/ directory

    clues/*.lua - Leader binding definitions

    • windows.lua - Window management (moved to AeroSpace)
    • hammerspoon.lua - Reload config, console, update apps, switcher
    • apps.lua - App launching
    • system.lua - System operations
    • cleanshot.lua - CleanShot integration
    • emoji.lua - Emoji picker
    • superwhisper.lua - SuperWhisper integration

    Pickers

    emoji-picker.lua - Emoji chooser

    • Fuzzy-searchable emoji picker
    • Categories and descriptions
    • Inserts selected emoji via keystroke

    symbol-picker.lua - Symbol chooser

    • Special characters and symbols
    • Categories: arrows, math, punctuation, currency, etc.
    • Inserts selected symbol via keystroke

    chooser-style.lua - Shared chooser styling

    • Dark theme
    • Consistent width and row count
    • Applied to all choosers

    Window switcher

    window-switcher.lua - Unified launcher/dispatcher modal

    • Uses hs.chooser API with fuzzy matching
    • Shows windows, apps, and commands
    • Keybindings: cmd+space and cmd+tab
    • Dark theme with 15 visible rows

    fuzzy.lua - Dynamic programming fuzzy matching

    • Subsequence matching with scoring bonuses
    • Type priority: window (3), app (2), command (1)

    notch-clock.lua - Clock in notch area

    • Shows time in MacBook notch
    • 4-minute offset configuration

    Common operations

    Using the hs CLI

    The hs command-line tool provides direct interaction with Hammerspoon. It requires hs.ipc.cliInstall() to be called in init.lua (already configured).

    Check for errors and module status:

    echo "
    local status = {modules_loaded = {}, errors = {}}
    local modules = {'hyper-key', 'config-watch', 'window-hotkeys', 'quick-switch', 'window-switcher'}
    for _, mod in ipairs(modules) do
      local ok, result = pcall(require, mod)
      if ok then
        table.insert(status.modules_loaded, mod)
      else
        table.insert(status.errors, mod .. ': ' .. tostring(result))
      end
    end
    return hs.json.encode(status, true)
    " | hs -c ''
    

    View live console output:

    hs -C
    

    Execute Hammerspoon commands:

    echo "hs.alert.show('test')" | hs -c ''
    echo 'hs.reload()' | hs -c ''
    

    Interactive Lua REPL:

    hs
    

    Mirror prints to console:

    hs -P
    

    Run a script:

    hs /path/to/script.lua
    

    Common flags:

    • -A - Auto-launch Hammerspoon if not running
    • -C - Clone console prints to this terminal (best for checking errors)
    • -P - Mirror prints to Hammerspoon console
    • -c - Execute command and return result
    • -i - Force interactive mode
    • -n - Disable colorized output
    • -N - Force colorized output
    • -q - Quiet mode (errors and results only)

    Other operations

    Reload Hammerspoon:

    echo 'hs.reload()' | hs -c ''
    # or via URL:
    open -g hammerspoon://reload
    

    Check if running:

    ps aux | rg -i hammerspoon
    

    Open console window:

    open "hammerspoon://consoleWindow"
    

    Test configuration: Edit any .lua file in ~/.config/hammerspoon/ to trigger auto-reload

    Development patterns

    Adding new leader bindings

    Create a file in ~/.config/hammerspoon/clues/:

    return Leader("key", "Description", {
      Bind("a", "Action 1", { fn = function() ... end }),
      Bind("b", "Action 2", { shell = "/path/to/script" }),
      Bind("c", "Action 3", { mode = "mode_name" }),
    })
    

    Creating new modules

    1. Create ~/.config/hammerspoon/module-name.lua
    2. Return module table or functionality
    3. Require in init.lua: local module = require("module-name")

    App replacement status

    Current Hammerspoon setup replaces:

    • AltTab: Window switching via window-switcher.lua (cmd+space, cmd+tab)

    Other macOS automation tools:

    • Karabiner-Elements: Key remapping (caps lock to ctrl, etc.)
    • AeroSpace: Window management (tiling, workspaces, monitor assignment)
    • CleanShot: Screenshots (integrated via leader modal)

    Troubleshooting

    Check for errors

    Use the hs CLI to check for module loading errors:

    echo "
    local status = {modules_loaded = {}, errors = {}}
    local modules = {'hyper-key', 'config-watch', 'window-hotkeys', 'quick-switch', 'window-switcher'}
    for _, mod in ipairs(modules) do
      local ok, result = pcall(require, mod)
      if ok then
        table.insert(status.modules_loaded, mod)
      else
        table.insert(status.errors, mod .. ': ' .. tostring(result))
      end
    end
    return hs.json.encode(status, true)
    " | hs -c ''
    

    Or view live console output: hs -C

    Config not loading

    • Check symlink: ls -la ~/.hammerspoon
    • Verify Hammerspoon is running: ps aux | rg Hammerspoon
    • Reload manually: echo 'hs.reload()' | hs -c ''
    • Check for errors: hs -C or open "hammerspoon://consoleWindow"

    Keybindings not working

    • Check for conflicts with app shortcuts
    • Verify modifier keys are correct
    • Test with: echo "hs.alert.show('test')" | hs -c ''

    Auto-reload not triggering

    • Verify config-watch.lua is loaded in init.lua
    • Check file extension is .lua
    • Restart Hammerspoon app

    CLI not working

    If hs command not found, ensure hs.ipc.cliInstall() is called in init.lua

    Philosophy

    Zero spoons approach

    • Inline functionality instead of external dependencies
    • Only use spoons if absolutely necessary
    • Keep implementation simple and maintainable

    Decision criteria for using spoons:

    • Must provide significant value that's hard to inline
    • Must be actively maintained
    • Must be worth the workflow complexity

    Future spoon management (not yet implemented): If spoons are needed, they will be managed via GitHub workflow:

    1. Add spoon commit hash to .github/workflows/versions.lua
    2. Create .github/workflows/hammerspoon.yml build workflow
    3. Workflow clones spoons at specified revisions, bundles into tarball
    4. Release as hammerspoon-YYYY.MM.DD-darwin-arm64.tar.gz
    5. Only add spoons to config after workflow builds successfully

    This ensures pinned, reproducible spoon dependencies similar to other tools in the repo.

    File organization

    • One module per file
    • Clear, descriptive names
    • Require modules in init.lua
    • Use XDG-style config directory

    Resources

    • Hammerspoon API: https://www.hammerspoon.org/docs/
    • Plan document: ~/.claude/plans/hammerspoon-consolidation.md
    • dbalatero dotfiles: https://github.com/dbalatero/dotfiles/tree/main/hammerspoon (reference only)
    Recommended Servers
    Kernel
    Kernel
    Repository
    whilp/world
    Files