Overview
Global shortcuts work even when other apps are focused. They use the bindingregistry service which receives keyboard events from keylogger and dispatches to registered callbacks.
Steps
1. Choose Your Service Location
Decide where the shortcut handler will live:
- •Existing service (Go/Python) - Add to that service's startup
- •Electron frontend - Add to
frontend/electron/main.ts - •New service - Create new service with NATS connection
2. Register the Shortcut
On service startup, send a NATS request to bindingregistry.register:
json
{
"id": "myservice.myAction",
"callback_subject": "myservice.shortcuts",
"shortcut": {
"code": "KeyK",
"modifiers": {
"shift": false,
"control": false,
"option": false,
"command": true
}
},
"trigger": {
"type": "press"
}
}
Key code reference: Use DOM KeyboardEvent.code values:
- •Letters:
KeyA,KeyB, ...,KeyZ - •Numbers:
Digit0,Digit1, ... - •Punctuation:
Semicolon,Quote,Comma,Period,Slash,Backslash - •Special:
Space,Enter,Escape,Backspace,Tab - •Arrows:
ArrowUp,ArrowDown,ArrowLeft,ArrowRight
3. Subscribe to Callback
Subscribe to your callback_subject. When the shortcut triggers, you receive:
json
{
"specversion": "1.0",
"type": "com.accelerator.bindingregistry.shortcutTriggered",
"source": "bindingregistry",
"id": "uuid",
"time": "2025-01-24T12:00:00Z",
"data": {
"shortcut_id": "myservice.myAction",
"trigger": { "type": "press" },
"shortcut": { "code": "KeyK", "modifiers": {...} }
}
}
4. Update Documentation
Add the new shortcut to SHORTCUTS.md and update the registration location in AGENTS.md.
Examples
Go (audiorecorder pattern):
- •Define binding in
bindings.gousing generated AsyncAPI types - •Register on startup in
main.go - •See:
audiorecorder/bindings.go,audiorecorder/main.go
Python (brain pattern):
- •Direct NATS request/response
- •See:
brain/main.pyregister_shortcut()function
TypeScript/Electron:
- •Register when NATS connects in
connectToNats() - •Subscribe to callback subject for events
- •See:
frontend/electron/main.ts
Trigger Types
| Type | Description | Extra Fields |
|---|---|---|
press | Fire on key down | None |
release | Fire on key up | None |
hold | Fire after holding key | duration_ms |
multi_tap | Fire after N presses | count, window_ms |
Common Issues
- •Shortcut not firing: Check modifiers match exactly (all four must be specified)
- •Duplicate registration: Use unique
idper binding; same ID = error - •Conflict with other shortcuts: Check SHORTCUTS.md for existing bindings