MCPcopy Index your code
hub / github.com/DeprecatedLuar/akeyshually

github.com/DeprecatedLuar/akeyshually @v0.5.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.3 ↗ · + Follow
272 symbols 802 edges 35 files 135 documented · 50%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

akeyshually banner

"Any button, any input from any peripheral, triggers anything on your system"

InstallCommandsConfigurationBehaviorsKey Names


Errm... Akeyshually, this is NOT a keyboard remapper but an evdev-based userspace daemon configured in TOML that intercepts raw input events from any evdev hardware, performs stateful modifier tracking, and executes arbitrary shell commands through a fire-and-forget subprocess model regardless of session type or graphical environment manager. And it also does remapping.

akeyshually demo


Installation

Linux Go

Universal

curl -sSL https://raw.githubusercontent.com/DeprecatedLuar/the-satellite/main/satellite.sh | bash -s -- install DeprecatedLuar/akeyshually

Go

go install github.com/DeprecatedLuar/akeyshually/cmd/akeyshually@latest

Make sure $GOPATH/bin (usually ~/go/bin) is in your PATH.

Other Install Methods

Manual Install 1. Download binary for your OS from releases 2. Make executable: chmod +x akeyshually 3. Move to PATH: mv akeyshually ~/.local/bin/


From Source (for try-harders)

git clone https://github.com/DeprecatedLuar/akeyshually.git
cd akeyshually
go build -ldflags="-s -w" -o akeyshually ./cmd/akeyshually
mv akeyshually ~/.local/bin/

[!NOTE] User must be in input group: sudo usermod -aG input $USER (logout required)

[!NOTE] First run auto-generates config files in ~/.config/akeyshually/. Just run akeyshually and you're good.


The ludicrous features you've never seen before

Hardware bowing to akeyshually

I'd check out the Overlay System and Behaviors. That's where it gets fun.

  • I designed it to have zero conflicts with any other remapper or shortcut tool. (keyd, kanata, kmonad, xremap...)
  • Dead-simple TOML config. Modular overlays that are portable and shareable by design for absolute no conflicts.
  • Declarative config only consumes what you explicitly asked for
  • Actually lightweight takes about ~3MB binary, <3MB RAM, 0% CPU when idle (as expected)
  • You can write literal drivers on steroids on a 10 line file. If its a peripheral akeyshually basically pwns it.
  • Advanced triggers and behaviors customization (see table)
  • Its borderline black-market software

Quick Start

Prerequisites:

# Add yourself to the input group (first time only)
sudo usermod -aG input $USER
# then logout and back in

Run akeyshually — config auto-generates at ~/.config/akeyshually/:

akeyshually

Nerd cat

Open config and add this shortcut:

[shortcuts]
'super+shift+a' = "notify-send 'Errm... whassup doc?'"

Press the combo, notification pops.

Now here's how to make an auto-clicker:

"f9.repeat" = ">lclick"

Tap F9 to trigger, tap again to stop.


Configuration

Config lives at ~/.config/akeyshually/: - config.toml - All-in-one config (settings, shortcuts, command aliases) - akeyshually.service - Systemd service file (with install instructions)

[!TIP] If you wanna see a working example vheck out my personal config at the bottom of this section.

Shortcut Syntax

Key combinations: - Single key: "print", "super", "f1" - With modifiers: "super+t", "ctrl+alt+delete", "shift+print" - Modifiers: super, ctrl, alt, shift (lowercase) - Use + to combine modifiers and keys

Dot notation: - Triggers define when the command fires: .onpress, .hold, .doubletap, .pressrelease, etc. - Modifiers change how the command executes: .switch, .repeat, .passthrough - Chain triggers and modifiers: "key.hold.repeat", "key.doubletap(200)" - Triggers can take parameters: .hold(500), .doubletap(200), .taphold(200, 500)

Alias syntax: - Share command across multiple keys: "f1/f2/f3.switch" = ["cmd1", "cmd2"] - Dot modifiers from the last key apply to all: "a/b.hold" = "a.hold" + "b.hold"

Axis syntax: - Axis direction: "rx+", "abs_y-" (axis name + direction suffix) - Remap to scroll: "rx+" = ">scrollup", "abs_y-" = ">scrolldown" - Works with drawing tablets, gamepads, trackballs, any ABS device

Commands: - Direct: "super+t" = "kitty" - Command variable: "super+t" = "$TERMINAL" or "super+t" = "terminal" (references [command_variables]) - Arrays for specific behaviors: ".pressrelease" = ["press_cmd", "release_cmd"]

Deep Dive on triggers and modifiers:

Triggers — define when the command fires:

Trigger Syntax Description
(default) / .onpress "key" Executes on key press
.doubletap / .doubletap(ms) "key.doubletap(200)" Executes on confirmed double-tap
.hold / .hold(ms) "key.hold(500)" Fire once after hold threshold
.pressrelease "key.pressrelease" = ["cmd", "release_cmd"] Execute on press and release (either can be "")
.taphold / .taphold(tap_ms, hold_ms) "key.taphold(200, 500)" Tap once, then tap-and-hold on next press
.longpress / .longpress(ms) "key.longpress(500)" Fire once after threshold (one-shot)
.holdrelease / .holdrelease(ms) "key.holdrelease(500)" = ["hold_cmd", "release_cmd"] Execute at hold threshold and on release
.taplongpress / .taplongpress(tap_ms, long_ms) "key.taplongpress" = ["tap_cmd", "long_cmd"] Tap once, or tap-then-longpress
.tappressrelease / .tappressrelease(tap_ms) "key.tappressrelease(200)" = ["press_cmd", "release_cmd"] Tap then press fires first, release fires second
.tapholdrelease / .tapholdrelease(tap_ms, hold_ms) "key.tapholdrelease" = ["hold_cmd", "release_cmd"] Tap then hold fires first, release fires second

Modifiers — change how the command executes:

Modifier Syntax Description
.switch "key.switch" = ["cmd1", "cmd2"] Cycles through a command array
.repeat "key.hold.repeat" Loops command while held
.passthrough "key.passthrough" Ignores modifiers when matching

Normal (default):

"super+t" = "kitty"  # Executes on key press

Hold (fire once after threshold):

"super+m.hold" = "mute"                 # Fire once after default threshold
"super+m.hold(500)" = "mute"            # Fire once after 500ms (no process management)

Repeat while held:

"f9.hold.repeat" = "xdotool click 1"     # Repeat every default_interval while held
"f9.onpress.repeat" = "xdotool click 1"  # Toggle: start/stop on each press

Switch (cycle through commands):

"super+tab.switch" = ["cmd1", "cmd2", "cmd3"]  # Cycles on each press

Double-tap (execute on quick double-tap):

"super.doubletap(200)" = "$LAUNCHER"      # Double-tap within 200ms
"print.doubletap(300)" = "screen-record"  # Works on any single key

Press/Release (dual commands):

"super.pressrelease" = ["", "rofi"]            # Release only (modifier tap)
"super+m.pressrelease" = ["mic-on", "mic-off"] # Both press and release

Tap-then-hold:

"super+t.taphold" = "hold-cmd"             # Tap once, then tap-and-hold (default timings)
"super+t.taphold(200, 500)" = "hold-cmd"   # Custom tap window (200ms) + hold threshold (500ms)

Long press:

"super+h.longpress(1000)" = "shutdown"  # Fire once after 1000ms (one-shot)

Hold and release:

"mute.holdrelease" = ["enable-mic", "disable-mic"]        # Push-to-talk: hold to enable, release to disable
"mute.holdrelease(500)" = ["enable-mic", "disable-mic"]   # Custom hold threshold (500ms)

Tap or long press:

"super+space.taplongpress" = ["quick-cmd", "long-cmd"]       # Tap fires first, longpress fires second
"super+space.taplongpress(200, 1000)" = ["tap", "longhold"]  # Custom tap (200ms) + long (1000ms) windows

Settings Reference

Configure daemon behavior in the [settings] section:

Setting Type Default Description
default_interval number 150 Default interval for .repeat behaviors in milliseconds (values < 10 treated as seconds)
disable_media_keys boolean false When true, forwards media keys to system instead of intercepting them
shell string $SHELL Shell to use for executing commands (fallback: sh)
env_file string - File to source before executing commands (e.g., "~/.profile")
notify_on_overlay_change boolean false Show desktop notifications when overlays are enabled/disabled
devices array [] Device name substrings to explicitly grab (case-insensitive), e.g. ["Huion", "Xbox", "PlayStation", "DualShock"]

Example:

[settings]
default_interval = 150
disable_media_keys = false
shell = "/bin/bash"
env_file = "~/.profile"
notify_on_overlay_change = true
devices = ["Huion Tablet", "Xbox Controller"]

Available Key Names

Modifiers: super, ctrl, alt, shift (can have standalone shortcuts; left/right separation planned for future release)

Letters: a-z

Numbers: 0-9

Special keys: return/enter, space, tab, esc/escape, backspace, delete, insert, home, end, pageup, pagedown, semicolon/;

Arrows: left, right, up, down

Function keys: f1-f24

Print screen: print/printscreen

Numpad: kp0-kp9, kpplus, kpminus, kpasterisk, kpslash, kpenter, kpdot

Media keys: volumeup, volumedown, mute, brightnessup, brightnessdown, playpause/play, nextsong/next, previoussong/previous, calc/calculator

CD controls (legacy): playcd, pausecd, stopcd, ejectcd, closecd, ejectclosecd

Gamepad (canonical names): btn_south, btn_north, btn_east, btn_west, btn_tl, btn_tr, btn_tl2, btn_tr2, btn_start, btn_select, btn_mode, btn_thumbl, btn_thumbr

Gamepad (Xbox aliases): gp_a, gp_b, gp_x, gp_y, gp_lb, gp_rb, gp_lt, gp_rt, gp_ls, gp_rs, gp_start, gp_select, gp_guide

Gamepad (PlayStation aliases): gp_cross, gp_circle, gp_square, gp_triangle, gp_l1, gp_r1, gp_l2, gp_r2, gp_l3, gp_r3

Note: Xbox and PlayStation names map to the same buttons. Use whichever matches your controller (e.g., gp_a = gp_cross = btn_south).

Tablet/generic: btn_0-btn_9, btn_tool_pen, btn_touch, btn_stylus, btn_stylus2

Mouse buttons (remap output): - Left: btn_left, lclick, leftclick, lbutton, leftbutton, mouse1 - Right: btn_right, rclick, rightclick, rbutton, rightbutton, mouse2 - Middle: btn_middle, mclick, middleclick, mbutton, middlebutton, mouse3 - Forward: btn_forward, forward, mouse4 - Back: btn_back, back, mouse5 - Extra: btn_side, btn_extra - Use with remap prefix: ">lclick", ">rclick", ">middleclick", etc.

Axis (absolute): x, y, z, rx, ry, rz, abs_x, abs_y, abs_z, abs_rx, abs_ry, abs_rz - Use with direction suffix: "rx+", "abs_y-" - Remap to scroll: ">scrollup", ">scrolldown", ">scrollleft", ">scrollright" (or ">wheelup", ">wheeldown", ">wheelleft", ">wheelright")

Other: 102nd, ro

Here is my personal config:

```toml [settings] default_interval = 150 disable_media_keys = false # Set to true to let system handle media keys (GNOME/KDE/etc.) env_file = "~/.profile"

[shortcuts] "super+k" = "edit_config" "ctrl+shift+k" = "kill_switch"

-[LAUNCHERS]--------------------------------

"super.pressrelease" = ["", "hotline"] "super.doubletap(270)" = "$LAUNCHER"

"super+enter" = "$TERMINAL" "super+b" = "$BROWSER" "super+shift+b" = "brave" "super+e" = "thunderbird" "super+w" = "whatsapp" "super+f" = "$FILEMANAGER" "super+v" = "copyq toggle" "shift+super+n" = "notetaker"

-[WINDOW MANAGER]---------------------------

"super+x" = "kill_window"

-[UTILS]------------------------------------

"print" = "grimblast -f -n copysave area ~/Media/Pictures/screenshots/latest.png" "print.doubletap" = "last_screenshot" "super+shift+p" = "last_screenshot" "super+ctrl+p" = "grimblast -f -n copysave area" "shift+print" = "grimblast -f -n -o save area" "super+p" = "grimblast copy area"

"super+y" = "yap toggle & sleep 3 && tcpeek reconnect"

-[MEDIA KEYS]--------------

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 209
Method 38
Struct 18
TypeAlias 5
FuncType 2

Languages

Go100%

Modules by API surface

internal/timers/race.go24 symbols
internal/config/config_test.go24 symbols
internal/config/validate.go23 symbols
internal/matcher/matcher.go22 symbols
internal/config/config.go22 symbols
internal/listener/listener.go21 symbols
internal/ladder/ladder_test.go18 symbols
internal/ladder/ladder.go14 symbols
internal/config/validate_test.go12 symbols
internal/executor/lifecycle.go10 symbols
internal/handlers/abs_handler.go9 symbols
internal/common/debug.go9 symbols

For agents

$ claude mcp add akeyshually \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page