@quickcall/all-configs 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/bin/all-configs.js +44 -0
- package/package.json +20 -4
- package/runtime/allconfigs/__init__.py +1 -0
- package/runtime/allconfigs/__main__.py +42 -0
- package/runtime/allconfigs/__pycache__/__init__.cpython-312.pyc +0 -0
- package/runtime/allconfigs/__pycache__/__main__.cpython-312.pyc +0 -0
- package/runtime/allconfigs/__pycache__/modules.cpython-312.pyc +0 -0
- package/runtime/allconfigs/__pycache__/probe.cpython-312.pyc +0 -0
- package/runtime/allconfigs/__pycache__/runner.cpython-312.pyc +0 -0
- package/runtime/allconfigs/modules.py +221 -0
- package/runtime/allconfigs/probe.py +60 -0
- package/runtime/install.sh +74 -0
- package/runtime/lib/common.sh +147 -0
- package/runtime/lib/uninstall.sh +35 -0
- package/runtime/modules/aldente/install.sh +23 -0
- package/runtime/modules/aldente/module.toml +11 -0
- package/runtime/modules/aliases/aliases.sh +31 -0
- package/runtime/modules/aliases/install.sh +36 -0
- package/runtime/modules/aliases/module.toml +7 -0
- package/runtime/modules/aqua-voice/install.sh +23 -0
- package/runtime/modules/aqua-voice/module.toml +11 -0
- package/runtime/modules/betterdisplay/install.sh +23 -0
- package/runtime/modules/betterdisplay/module.toml +11 -0
- package/runtime/modules/bitwarden/install.sh +19 -0
- package/runtime/modules/bitwarden/module.toml +11 -0
- package/runtime/modules/browsers/install.sh +33 -0
- package/runtime/modules/browsers/module.toml +11 -0
- package/runtime/modules/bun/install.sh +72 -0
- package/runtime/modules/bun/module.toml +7 -0
- package/runtime/modules/caveman/install.sh +79 -0
- package/runtime/modules/caveman/module.toml +7 -0
- package/runtime/modules/claude/install.sh +22 -0
- package/runtime/modules/claude/module.toml +7 -0
- package/runtime/modules/codex/install.sh +20 -0
- package/runtime/modules/codex/module.toml +7 -0
- package/runtime/modules/docker/install.sh +19 -0
- package/runtime/modules/docker/module.toml +11 -0
- package/runtime/modules/external-skills/install.sh +30 -0
- package/runtime/modules/external-skills/module.toml +4 -0
- package/runtime/modules/ffmpeg/install.sh +13 -0
- package/runtime/modules/ffmpeg/module.toml +11 -0
- package/runtime/modules/fonts/install.sh +62 -0
- package/runtime/modules/fonts/module.toml +8 -0
- package/runtime/modules/ghostty/config +44 -0
- package/runtime/modules/ghostty/install.sh +64 -0
- package/runtime/modules/ghostty/module.toml +9 -0
- package/runtime/modules/ghostty/themes/ayu-dark +22 -0
- package/runtime/modules/ghostty/themes/catppuccin-frappe +23 -0
- package/runtime/modules/ghostty/themes/catppuccin-latte +23 -0
- package/runtime/modules/ghostty/themes/catppuccin-latte.conf +23 -0
- package/runtime/modules/ghostty/themes/catppuccin-macchiato +23 -0
- package/runtime/modules/ghostty/themes/catppuccin-mocha +23 -0
- package/runtime/modules/ghostty/themes/visual-studio-light +27 -0
- package/runtime/modules/ghostty/themes/vscode-light +24 -0
- package/runtime/modules/ghostty/themes/vscode-light-soft +24 -0
- package/runtime/modules/ghostty/xterm-ghostty.terminfo +81 -0
- package/runtime/modules/github/install.sh +101 -0
- package/runtime/modules/github/module.toml +8 -0
- package/runtime/modules/hf/install.sh +98 -0
- package/runtime/modules/hf/module.toml +7 -0
- package/runtime/modules/karabiner/README.md +146 -0
- package/runtime/modules/karabiner/agents.md +39 -0
- package/runtime/modules/karabiner/app_launchers.json +236 -0
- package/runtime/modules/karabiner/custom_delete_mapping.json +13 -0
- package/runtime/modules/karabiner/fn_to_control.json +9 -0
- package/runtime/modules/karabiner/install.sh +60 -0
- package/runtime/modules/karabiner/karabiner.json +866 -0
- package/runtime/modules/karabiner/keychron-modifier-swap.sh +80 -0
- package/runtime/modules/karabiner/module.toml +8 -0
- package/runtime/modules/karabiner/remap_caps_lock_shift_super.json +23 -0
- package/runtime/modules/karabiner/remap_escape_to_control.json +49 -0
- package/runtime/modules/karabiner/rename_caps_lock_to_super.json +23 -0
- package/runtime/modules/karabiner/right_shift_mouse_click.json +44 -0
- package/runtime/modules/karabiner/swap_esc_delete.json +10 -0
- package/runtime/modules/karabiner/troubleshooting.md +242 -0
- package/runtime/modules/karabiner/vim_arrow_keys.json +477 -0
- package/runtime/modules/keepingyouawake/install.sh +23 -0
- package/runtime/modules/keepingyouawake/module.toml +11 -0
- package/runtime/modules/keycastr/install.sh +23 -0
- package/runtime/modules/keycastr/module.toml +11 -0
- package/runtime/modules/multi-github/install.sh +179 -0
- package/runtime/modules/multi-github/module.toml +4 -0
- package/runtime/modules/ncdu/install.sh +13 -0
- package/runtime/modules/ncdu/module.toml +11 -0
- package/runtime/modules/node/install.sh +73 -0
- package/runtime/modules/node/module.toml +11 -0
- package/runtime/modules/nvim/.neoconf.json +15 -0
- package/runtime/modules/nvim/init.lua +2 -0
- package/runtime/modules/nvim/install.sh +142 -0
- package/runtime/modules/nvim/lazy-lock.json +35 -0
- package/runtime/modules/nvim/lazyvim.json +10 -0
- package/runtime/modules/nvim/lua/config/autocmds.lua +18 -0
- package/runtime/modules/nvim/lua/config/keymaps.lua +10 -0
- package/runtime/modules/nvim/lua/config/lazy.lua +53 -0
- package/runtime/modules/nvim/lua/config/options.lua +3 -0
- package/runtime/modules/nvim/lua/plugins/image.lua +9 -0
- package/runtime/modules/nvim/lua/plugins/markdown.lua +56 -0
- package/runtime/modules/nvim/lua/plugins/noice.lua +17 -0
- package/runtime/modules/nvim/lua/plugins/rose-pine.lua +16 -0
- package/runtime/modules/nvim/lua/plugins/snacks.lua +20 -0
- package/runtime/modules/nvim/module.toml +8 -0
- package/runtime/modules/nvim/stylua.toml +3 -0
- package/runtime/modules/p10k/install.sh +46 -0
- package/runtime/modules/p10k/module.toml +8 -0
- package/runtime/modules/p10k/p10k.zsh +1711 -0
- package/runtime/modules/pi/install.sh +77 -0
- package/runtime/modules/pi/module.toml +8 -0
- package/runtime/modules/pi/packages +5 -0
- package/runtime/modules/pi/settings.json +21 -0
- package/runtime/modules/presentify/install.sh +25 -0
- package/runtime/modules/presentify/module.toml +7 -0
- package/runtime/modules/rectangle/RectangleConfig.json +353 -0
- package/runtime/modules/rectangle/install.sh +64 -0
- package/runtime/modules/rectangle/module.toml +11 -0
- package/runtime/modules/shortcat/install.sh +19 -0
- package/runtime/modules/shortcat/module.toml +11 -0
- package/runtime/modules/skills/install.sh +25 -0
- package/runtime/modules/skills/module.toml +4 -0
- package/runtime/modules/skills/skills-lock.json +35 -0
- package/runtime/modules/slack/install.sh +23 -0
- package/runtime/modules/slack/module.toml +11 -0
- package/runtime/modules/spotify/install.sh +23 -0
- package/runtime/modules/spotify/module.toml +11 -0
- package/runtime/modules/ssh-keygen/install.sh +130 -0
- package/runtime/modules/ssh-keygen/module.toml +4 -0
- package/runtime/modules/statusline/install.sh +69 -0
- package/runtime/modules/statusline/module.toml +7 -0
- package/runtime/modules/statusline/statusline.sh +168 -0
- package/runtime/modules/statusline/turn-counter.sh +11 -0
- package/runtime/modules/superfile/cheatsheet.md +127 -0
- package/runtime/modules/superfile/config.toml +181 -0
- package/runtime/modules/superfile/hotkeys.toml +96 -0
- package/runtime/modules/superfile/install.sh +73 -0
- package/runtime/modules/superfile/module.toml +7 -0
- package/runtime/modules/tailscale/install.sh +29 -0
- package/runtime/modules/tailscale/module.toml +11 -0
- package/runtime/modules/tinycast/install.sh +68 -0
- package/runtime/modules/tinycast/module.toml +7 -0
- package/runtime/modules/tinycast/settings.json +226 -0
- package/runtime/modules/tmux/.tmux.conf.local +168 -0
- package/runtime/modules/tmux/README.md +50 -0
- package/runtime/modules/tmux/install.sh +57 -0
- package/runtime/modules/tmux/installer.mjs +191 -0
- package/runtime/modules/tmux/module.toml +8 -0
- package/runtime/modules/tmux/shell-helpers.sh +20 -0
- package/runtime/modules/tmux/uninstall.sh +134 -0
- package/runtime/modules/uv/install.sh +72 -0
- package/runtime/modules/uv/module.toml +7 -0
- package/runtime/modules/vlc/install.sh +23 -0
- package/runtime/modules/vlc/module.toml +11 -0
- package/runtime/modules/vscode/install.sh +33 -0
- package/runtime/modules/vscode/keybindings.json +74 -0
- package/runtime/modules/vscode/module.toml +8 -0
- package/runtime/modules/vscode/settings.json +426 -0
- package/runtime/modules/vscode/tasks.json +1 -0
- package/runtime/modules/yt-dlp/install.sh +13 -0
- package/runtime/modules/yt-dlp/module.toml +11 -0
- package/runtime/modules/zed/install.sh +43 -0
- package/runtime/modules/zed/module.toml +8 -0
- package/runtime/modules/zed/settings.json +208 -0
- package/runtime/modules/zoxide/install.sh +41 -0
- package/runtime/modules/zoxide/module.toml +11 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
printf 'usage: %s on|off|status [config]\n' "$(basename "$0")" >&2
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if [[ $# -lt 1 || $# -gt 2 ]]; then
|
|
9
|
+
usage
|
|
10
|
+
exit 2
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
mode="$1"
|
|
14
|
+
config="${2:-$HOME/.config/karabiner/karabiner.json}"
|
|
15
|
+
|
|
16
|
+
case "$mode" in
|
|
17
|
+
on|off|status) ;;
|
|
18
|
+
*)
|
|
19
|
+
usage
|
|
20
|
+
exit 2
|
|
21
|
+
;;
|
|
22
|
+
esac
|
|
23
|
+
|
|
24
|
+
if [[ ! -f "$config" ]]; then
|
|
25
|
+
printf 'missing config: %s\n' "$config" >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
filter_status='
|
|
30
|
+
.profiles[0].devices[]
|
|
31
|
+
| select(.identifiers.vendor_id == 13364 and .identifiers.product_id == 560)
|
|
32
|
+
| if (.simple_modifications // [] | length) > 0 then "on" else "off" end
|
|
33
|
+
'
|
|
34
|
+
|
|
35
|
+
if [[ "$mode" == "status" ]]; then
|
|
36
|
+
jq -r "$filter_status" "$config"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
tmp="$(mktemp)"
|
|
41
|
+
trap 'rm -f "$tmp"' EXIT
|
|
42
|
+
|
|
43
|
+
if [[ "$mode" == "on" ]]; then
|
|
44
|
+
jq '
|
|
45
|
+
.profiles |= map(
|
|
46
|
+
.complex_modifications.rules = (.complex_modifications.rules // [] | map(select(.description != "Swap left and right Option/Command on Keychron")))
|
|
47
|
+
| .devices = (.devices // [] | map(
|
|
48
|
+
if (.identifiers.vendor_id == 13364 and .identifiers.product_id == 560) then
|
|
49
|
+
.simple_modifications = [
|
|
50
|
+
{"from":{"key_code":"left_option"},"to":[{"key_code":"left_command"}]},
|
|
51
|
+
{"from":{"key_code":"left_command"},"to":[{"key_code":"left_option"}]},
|
|
52
|
+
{"from":{"key_code":"right_option"},"to":[{"key_code":"right_command"}]},
|
|
53
|
+
{"from":{"key_code":"right_command"},"to":[{"key_code":"right_option"}]}
|
|
54
|
+
]
|
|
55
|
+
else
|
|
56
|
+
.
|
|
57
|
+
end
|
|
58
|
+
))
|
|
59
|
+
)
|
|
60
|
+
' "$config" > "$tmp"
|
|
61
|
+
else
|
|
62
|
+
jq '
|
|
63
|
+
.profiles |= map(
|
|
64
|
+
.complex_modifications.rules = (.complex_modifications.rules // [] | map(select(.description != "Swap left and right Option/Command on Keychron")))
|
|
65
|
+
| .devices = (.devices // [] | map(
|
|
66
|
+
if (.identifiers.vendor_id == 13364 and .identifiers.product_id == 560) then
|
|
67
|
+
del(.simple_modifications)
|
|
68
|
+
else
|
|
69
|
+
.
|
|
70
|
+
end
|
|
71
|
+
))
|
|
72
|
+
)
|
|
73
|
+
' "$config" > "$tmp"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
jq empty "$tmp"
|
|
77
|
+
mv "$tmp" "$config"
|
|
78
|
+
trap - EXIT
|
|
79
|
+
|
|
80
|
+
printf 'Keychron modifier swap: %s\n' "$mode"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Remap caps_lock to super and shift+command+caps_lock to escape",
|
|
3
|
+
"manipulators": [
|
|
4
|
+
{
|
|
5
|
+
"from": { "key_code": "caps_lock" },
|
|
6
|
+
"to": [
|
|
7
|
+
{
|
|
8
|
+
"key_code": "left_control",
|
|
9
|
+
"modifiers": ["left_shift", "left_option", "left_command"]
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"type": "basic"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"from": {
|
|
16
|
+
"key_code": "spacebar",
|
|
17
|
+
"modifiers": { "mandatory": ["control"] }
|
|
18
|
+
},
|
|
19
|
+
"to": [{ "key_code": "escape" }],
|
|
20
|
+
"type": "basic"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Control to Escape when pressed alone, Control when used with other keys",
|
|
3
|
+
"manipulators": [
|
|
4
|
+
{
|
|
5
|
+
"from": {
|
|
6
|
+
"key_code": "left_control",
|
|
7
|
+
"modifiers": {
|
|
8
|
+
"optional": [
|
|
9
|
+
"any"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"to": [
|
|
14
|
+
{
|
|
15
|
+
"key_code": "left_control",
|
|
16
|
+
"lazy": true
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"to_if_alone": [
|
|
20
|
+
{
|
|
21
|
+
"key_code": "escape"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"type": "basic"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"from": {
|
|
28
|
+
"key_code": "right_control",
|
|
29
|
+
"modifiers": {
|
|
30
|
+
"optional": [
|
|
31
|
+
"any"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"to": [
|
|
36
|
+
{
|
|
37
|
+
"key_code": "right_control",
|
|
38
|
+
"lazy": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"to_if_alone": [
|
|
42
|
+
{
|
|
43
|
+
"key_code": "escape"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"type": "basic"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Remap caps_lock to super",
|
|
3
|
+
"manipulators": [
|
|
4
|
+
{
|
|
5
|
+
"from": { "key_code": "caps_lock" },
|
|
6
|
+
"to": [
|
|
7
|
+
{
|
|
8
|
+
"key_code": "left_control",
|
|
9
|
+
"modifiers": ["left_shift", "left_option", "left_command"]
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"type": "basic"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"from": {
|
|
16
|
+
"key_code": "spacebar",
|
|
17
|
+
"modifiers": { "mandatory": ["control"] }
|
|
18
|
+
},
|
|
19
|
+
"to": [{ "key_code": "escape" }],
|
|
20
|
+
"type": "basic"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Right Shift to Right Mouse Click when pressed alone, Shift when used with other keys",
|
|
3
|
+
"manipulators": [
|
|
4
|
+
{
|
|
5
|
+
"from": {
|
|
6
|
+
"key_code": "left_shift",
|
|
7
|
+
"modifiers": {
|
|
8
|
+
"optional": [
|
|
9
|
+
"any"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"to": [
|
|
14
|
+
{
|
|
15
|
+
"key_code": "left_shift",
|
|
16
|
+
"lazy": true
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"type": "basic"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"from": {
|
|
23
|
+
"key_code": "right_shift",
|
|
24
|
+
"modifiers": {
|
|
25
|
+
"optional": [
|
|
26
|
+
"any"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"to": [
|
|
31
|
+
{
|
|
32
|
+
"key_code": "right_shift",
|
|
33
|
+
"lazy": true
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"to_if_alone": [
|
|
37
|
+
{
|
|
38
|
+
"pointing_button": "button2"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"type": "basic"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Troubleshooting: Keychron K3 Pro modifier weirdness
|
|
2
|
+
|
|
3
|
+
Complete incident history reconstructed from `debug-chat.md` (~3,600 lines of debugging, 2026-06-12 → 2026-10-15). Newest first for incidents, but read the **Gold State** first.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## GOLD STATE (verified live 2026-10-27 — this is what works)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
jq '[.profiles[].complex_modifications.rules[] | select(.description=="Correct swapped modifiers on Keychron Bluetooth Keyboard")] | length' ~/.config/karabiner/karabiner.json
|
|
11
|
+
# live: 1, but DISABLED ("enabled": false — Karabiner UI toggle writes this)
|
|
12
|
+
# repo + karabiner_scripts copies: 0 (rule fully deleted)
|
|
13
|
+
|
|
14
|
+
jq '[.profiles[].devices[] | select(.identifiers.vendor_id==13364) | {identifiers, swap: (.simple_modifications != null and (.simple_modifications|length > 0))}]' ~/.config/karabiner/karabiner.json
|
|
15
|
+
# → 3 entries, all swap: false
|
|
16
|
+
|
|
17
|
+
hidutil property --get UserKeyMapping
|
|
18
|
+
# → (null)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Gold state = **exactly this**:
|
|
22
|
+
|
|
23
|
+
1. **No Option/Command swap anywhere in Karabiner.** Not a complex rule (or only as a disabled shell in the live config), not device `simple_modifications`.
|
|
24
|
+
2. **Three Keychron device entries registered, none carrying modifier mappings:**
|
|
25
|
+
- `vendor_id: 13364, product_id: 640, is_keyboard: true, is_pointing_device: true` — Bluetooth `Keychron Bluetooth Keyboard`, combined keyboard+pointing interface
|
|
26
|
+
- `vendor_id: 13364, product_id: 640, is_keyboard: true, is_pointing_device: false` — same identity, keyboard-only interface shape (fallback)
|
|
27
|
+
- `vendor_id: 13364, product_id: 560, is_keyboard: true, is_pointing_device: true` — USB `Keychron K3 Pro`
|
|
28
|
+
3. **macOS native remaps: none** (`hidutil` null, `com.apple.keyboard.modifiermapping` empty, per-device `HIDKeyboardModifierMappingPairs` empty).
|
|
29
|
+
4. **Keychron Launcher:** Layer 0 (Mac) bottom row `Ctrl LOpt LCmd space RCmd`. Known quirk: **Layer 2 (Windows) can get stuck active** regardless of the physical Mac/Win switch. Workaround: remap Layer 2's three bottom-row positions to `Alt`/`Win`/`Win`. Escalation: factory reset (`Fn + J + Z`, ~4s) + re-pair (`Fn + 1/2/3` held ~4s), firmware reflash last (exact K3 Pro model/layout firmware).
|
|
30
|
+
|
|
31
|
+
### The "device code" memory — both are right
|
|
32
|
+
|
|
33
|
+
| Date | What worked | Status today |
|
|
34
|
+
|------|-------------|--------------|
|
|
35
|
+
| 2026-10-01 | `product_id: 640` device entry **with `is_pointing_device: true`** | **Gold.** This is what makes Karabiner match the BT identity at all; without it Caps-as-super and all device rules silently stop applying. |
|
|
36
|
+
| 2026-10-01 | Device-scoped `simple_modifications` swap correction on 640 | ⚠️ Worked ~2 weeks, became the breaker on 2026-10-15. Removed. |
|
|
37
|
+
| 2026-10-15 | **Removing the swap correction entirely** (user toggled the complex rule off in Karabiner UI) | **Gold.** No correction = nothing to double-swap. |
|
|
38
|
+
|
|
39
|
+
**Rule #1: never re-add a Keychron Option/Command swap to Karabiner.** Every swap added across this saga eventually caused a double-swap episode.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Incident 2026-10-15 (final): the Karabiner "fix" was the breaker
|
|
44
|
+
|
|
45
|
+
Full-day session. Everything tried, in order:
|
|
46
|
+
|
|
47
|
+
### Morning — diagnosis with corrections still in place
|
|
48
|
+
|
|
49
|
+
1. **Karabiner service check.** Live state: only BT `0x3434:0x280` connected, Karabiner running, `Default profile` active, BT correction loaded, macOS remaps null — still swapped. Sandboxed `karabiner_cli --list-connected-devices` had hung with `asio.system:1` and `--show-current-profile-name` also hung → briefly concluded the service was dead (logs last advanced Oct 14 13:37, launchctl print showed services absent). Restarted Karabiner via `open -a 'Karabiner-Elements'`.
|
|
50
|
+
2. **Correction of the false conclusion.** Re-ran the CLI outside the sandbox: service was healthy all along, saw exactly one Keychron (BT 640, keyboard+pointing), correction loaded. Lesson: sandboxed CLI failure ≠ dead service.
|
|
51
|
+
3. **Physical Mac/Win switch theory** — user: "no its not switching at all". Rejected.
|
|
52
|
+
4. **Config-rewriter theory** — searched `launchctl list`, all LaunchAgents/LaunchDaemons plists, crontab, running processes for anything touching karabiner/keychron/modifier/swap/watch. Nothing. Ruled out permanently.
|
|
53
|
+
5. **Caps Lock latched theory** — earlier failing trace had mouse clicks carrying `flags caps`; asked user to press Caps once and re-click. New Caps trace: correct super chord, mouse clicks with no `flags caps`. Ruled out. (Also matches the June 12 incident where latched Caps was the whole cause.)
|
|
54
|
+
6. **Interface-matching hypothesis.** Found via Karabiner docs: device identifiers are ANDed. Correction was on the 640 entry with `is_pointing_device: true`; if the keyboard reconnects as keyboard-only, the entry stops matching and the swap silently drops out. **Added a second, mutually exclusive 640 entry with `is_pointing_device: false` carrying the same correction** to all 3 config copies. Forced reload via `karabiner_cli --select-profile 'Default profile'` (reload confirmed 11:36:16 and 11:36:53). Announced a commit.
|
|
55
|
+
7. **User: "nope not working why are you committing without consulting me."** Commit stopped, nothing committed. Fallback hypothesis falsified.
|
|
56
|
+
8. **macOS per-device modifier prefs** — checked `.GlobalPreferences` ByHost plists and `com.apple.HIToolbox.plist` for modifier mappings tied to the Keychron. Empty.
|
|
57
|
+
9. **History re-read** — found the June 12 incident note (same symptom, VIA connection restored layer state). Pivoted investigation toward QMK/VIA layer state.
|
|
58
|
+
|
|
59
|
+
### Midday — the probe war
|
|
60
|
+
|
|
61
|
+
Established three-key probe: physical left Option, left Command, right Command (this board has no right Option key), down/up each, in EventViewer.
|
|
62
|
+
|
|
63
|
+
10. **Trace 1 (11:42):** physical LOpt → `left_command`, LCmd → `left_option`, RCmd → `right_option`. Swapped.
|
|
64
|
+
11. **Device-entry order hypothesis.** Config had a generic `{is_keyboard: true}` entry **before** the Keychron-specific entries; concluded the generic entry was being selected first so the Keychron swap never ran. **Reordered all 3 configs: 640 entries moved before the generic entry.** Reloaded.
|
|
65
|
+
12. **Trace 2 (11:45): unchanged.** Order hypothesis falsified. (Noted: Karabiner normalized the fallback entry's explicit `is_pointing_device: false` away on reload — harmless.)
|
|
66
|
+
13. **Mechanism switch.** Concluded device-level `simple_modifications` was not being applied at all. Replaced it with a **device-scoped complex rule** "Correct swapped modifiers on Keychron Bluetooth Keyboard": 4 manipulators (`left_command→left_option`, `left_option→left_command`, `right_option→right_command`, `right_command→right_option`), each with `device_if` on `vendor_id 13364, product_id 640` and `modifiers: optional any`. Same mechanism as the proven-working Caps rule. Removed all device `simple_modifications` so no double-swap was possible. Reloaded.
|
|
67
|
+
14. **Trace 3 (11:48): unchanged.** "This rules out both of my mapping fixes. Stopping configuration edits."
|
|
68
|
+
15. **Read-only verification.** `karabiner_cli --list-connected-devices` + rule jq + log tails: live identity and rule exact match, yet zero effect. Concluded the keyboard itself was emitting Windows-order codes and the repair point was the saved VIA keymap.
|
|
69
|
+
|
|
70
|
+
### Afternoon — Keychron Launcher investigation
|
|
71
|
+
|
|
72
|
+
16. Guided user to `launcher.keychron.com` (USB cable mode). Keychron docs: layers 0/1 = Mac, 2/3 = Windows.
|
|
73
|
+
17. **Discovery 1:** user had been editing **Layer 2 (Windows)**. Layer 0 (Mac) bottom row was already correct: `Ctrl LOpt LCmd space RCmd`.
|
|
74
|
+
18. Guided Layer 0 edits anyway: LOpt→`Alt`, LCmd→`Win`, RCmd→`Win` (Keychron calls macOS Command "Win"/"GUI" in its UI). User hit a snag choosing keys with the keyboard mid-remap ("not able to use win now") → advised using the mouse in the picker.
|
|
75
|
+
19. **Discovery 2 (screenshot):** Layer 0 selected in the UI (gray pill), its layout correct, **but Layer 2 shown green = the keyboard's active layer**. Physical Mac/Win switch not changing the active firmware layer.
|
|
76
|
+
20. Advised: move physical switch to Mac, check Layer 0 goes green. User: **"layer 2 is being highlighted no matter where i switch"** → QMK layer selector stuck on Layer 2. Advised editing Layer 2's three positions to Mac order (`LAlt`/`LWin`/`LWin`) as workaround; firmware reflash as the real fix for the stuck selector.
|
|
77
|
+
|
|
78
|
+
### The actual fix
|
|
79
|
+
|
|
80
|
+
21. **User: "I removed the rule which was saying correct keys for swapped Bluetooth or something in complex modification, and now it's working for some reason."**
|
|
81
|
+
|
|
82
|
+
The complex correction rule added in step 13 was the active breaker. Removing it fixed everything immediately. No layer edits were needed; Launcher work was abandoned mid-way.
|
|
83
|
+
|
|
84
|
+
### Root cause of the whole day
|
|
85
|
+
|
|
86
|
+
EventViewer was misread as proof of final macOS output. It shows Karabiner-processed events — the "from" column (`Karabiner DriverKit VirtualHIDKeyboard`) is the virtual device, and the trace interpretation that "the keyboard is emitting Windows-order codes" was the swap rule's own output in several of the earlier episodes. The Oct 1 fix (correction for 640) was correct *while the keyboard was in a bad state*, but the keyboard state kept changing underneath (resets, re-pairs, Launcher connections refreshing it), so a persistent correction alternated between correcting and double-swapping. That interplay is the entire source of the "random every few minutes" behavior.
|
|
87
|
+
|
|
88
|
+
### Config drift found and fixed 2026-10-27
|
|
89
|
+
|
|
90
|
+
The user's UI toggle wrote `enabled: false` to the **live** config only. Repo and `karabiner_scripts/` copies still had the rule with **no `enabled` field — which defaults to enabled** in Karabiner. Any `install.sh` re-sync would have re-broken the keyboard. Rule fully deleted from both copies on 2026-10-27; verified all three copies now agree (rule gone/disabled, 3 device entries, no swaps, macOS remaps null).
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Incident 2026-10-01 (afternoon): identity flip broke Caps-as-super, then modifiers
|
|
95
|
+
|
|
96
|
+
### Morning context
|
|
97
|
+
|
|
98
|
+
Factory reset (`Fn + J + Z`) temporarily fixed the swap, then it broke again ("now its fucked again"). Live check: Karabiner clean (all corrections off since Sep 27, hidutil null, config mtime Sep 27 10:52:40) — yet swapped after wake/reconnect at 12:33:05.
|
|
99
|
+
|
|
100
|
+
### The identity discovery
|
|
101
|
+
|
|
102
|
+
`hidutil list` showed the keyboard as **`0x3434 0x280 "Keychron Bluetooth Keyboard"`** — new vendor/product pair. Historically it was `0x3434 0x230 "Keychron K3 Pro"` (decimal `13364/560`). The reset/re-pair had re-enumerated it as product **640** — an identity the config didn't know. Advised re-pairing in Mac mode as the root fix; added 640 as a known device entry as the workaround.
|
|
103
|
+
|
|
104
|
+
### Caps-as-super failure
|
|
105
|
+
|
|
106
|
+
"NOW CAPS IS NOT BEING USED AS SUPER." Full investigation:
|
|
107
|
+
|
|
108
|
+
1. Verified Caps rule present (rule index 0 — first shot at the event), devices list, profile.
|
|
109
|
+
2. Added a `product_id: 640` device entry (is_keyboard only) to live + scripts + repo.
|
|
110
|
+
3. `karabiner_cli` probes: sandboxed runs hung (`asio.system:1`, `--show-current-profile-name` hung) → looked like service trouble; outside sandbox it reported the 640 as **both keyboard and pointing device**.
|
|
111
|
+
4. macOS per-device prefs (`ioreg`, `.GlobalPreferences`) — no Keychron modifier mapping.
|
|
112
|
+
5. First full probe trace (14:46): physical LOpt → `left_command`, LCmd → `left_option`, RCmd → `right_option`, **Caps → raw `caps_lock`**, `a` → `a`. Mouse clicks carried `flags caps` (latched Caps at that moment — separate red herring). Two failures at once: Karabiner not applying device rules to this identity, and apparent swapped modifiers.
|
|
113
|
+
6. **Root cause of Caps:** the 640 entry lacked `is_pointing_device: true`; Karabiner ANDs identifiers, so the entry never matched the combined keyboard+pointing interface. Fixed all 3 copies with a ruby script. Reload confirmed 14:48:20.
|
|
114
|
+
7. Trace 2 (14:48:52): **Caps → super chord restored** (LCmd+LOpt+LShift+LCtrl down/up). Modifiers still showing swapped.
|
|
115
|
+
8. Added device-scoped `simple_modifications` swap correction on 640 (left/right Option↔Command). Reload 14:49:40.
|
|
116
|
+
9. Trace 3 (14:59): all correct — LOpt→`left_option`, LCmd→`left_command`, RCmd→`right_command`, Caps→super chord, `a`→`a`. "now its working fuckin hell."
|
|
117
|
+
|
|
118
|
+
### Docs + commit
|
|
119
|
+
|
|
120
|
+
- User asked for a doc so it never happens again → replaced the stale July troubleshooting section in repo `README.md` with the root-cause notes and probe protocol.
|
|
121
|
+
- Commit `e604489` → amended to `ad72f55` ("Document Keychron Karabiner device fix"), author/committer `Sagar Sarkale <sagarsarkale.work@gmail.com>`. Push initially blocked by the safety layer.
|
|
122
|
+
- Helper script `keychron-modifier-swap.sh` deliberately **not** committed at the time — it hard-coded only product 560.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Incident between: two transports at once
|
|
127
|
+
|
|
128
|
+
"It happened again" — `hidutil list` showed **both** `0x230 Keychron K3 Pro` (USB) and `0x280 Keychron Bluetooth Keyboard` (BT) simultaneously; `karabiner_cli --list-connected-devices` confirmed both in Karabiner's view. Correction existed only on 640. Deliberately did **not** add a swap to 560 (that exact move had caused a double-swap on Sep 25). Asked for a trace including the "from" device column, and gave the fastest physical test: unplug USB / switch to BT-only. Confirmed the uncorrected transport was carrying keystrokes. This is why gold state keeps a 560 entry registered.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Incident 2026-09-25: "swap resets every few minutes"
|
|
133
|
+
|
|
134
|
+
The opening saga. Full session log:
|
|
135
|
+
|
|
136
|
+
### Diagnosis (first turns)
|
|
137
|
+
|
|
138
|
+
1. User: Karabiner keeps swapping left Option/Command "every few minutes."
|
|
139
|
+
2. Inspected live config + automatic backups. Found complex rule **"Swap left and right Option/Command on Keychron"** plus per-device `simple_modifications` — overlapping mapping surfaces.
|
|
140
|
+
3. **Key evidence:** automatic backup `karabiner_20260925.json` (12:46:07) had the rule active; live config changed at 13:07:43 contained `"enabled": false` on exactly that rule. Diff = that single line.
|
|
141
|
+
4. Karabiner logs showed reloads at 12:46:07, 13:00:48, 13:07:43 — config file being rewritten, then reloaded.
|
|
142
|
+
5. **Writer hunt:** `ps aux` + `launchctl list` → Karabiner, Raycast, Logitech Options+ running; no goku/skhd/yabai/hidutil keymap daemons. Searched Raycast config/support, LaunchAgents, Preferences plists, home-directory scripts referencing karabiner/left_option/left_command — nothing. Broad home search abandoned as too slow.
|
|
143
|
+
6. Backup history clean across all automatic backups → disabled state was transient, written after backups, not baked into any template.
|
|
144
|
+
7. Concluded: Karabiner's own UI/API path was writing the toggle; recommended moving the swap out of complex rules into device `simple_modifications` where no enable/disable flag exists.
|
|
145
|
+
|
|
146
|
+
### Watcher (intermittency trap)
|
|
147
|
+
|
|
148
|
+
8. User: "this keeps happening intermittently." Built **`watch-karabiner-swap.sh`** — 1s poll of config hash + rule state, logs only on change, captures reload lines and process context. First start raced the chmod (permission denied), restarted detached as PID 77522, logging to `outputs/karabiner-swap-watch.log`. Started from broken state (`rule_state: false`).
|
|
149
|
+
9. Later: user reported a change; watcher had **died** without catching anything; config mtime unchanged since 13:07:43; Karabiner log showed no new reload (only an update check at 13:40:36). Conclusion: this occurrence was **device/layer/reconnect state**, not a config rewrite. Two distinct failure modes established: (a) config file rewritten with the rule disabled, (b) behavior changes with no config change at all.
|
|
150
|
+
|
|
151
|
+
### The flip-flop fix attempts
|
|
152
|
+
|
|
153
|
+
10. **Attempt A (user-approved):** jq transform on live + `karabiner_scripts/`: removed the complex rule, added the four-way Option/Cmd swap as device `simple_modifications` on `13364/560`. Backed up both files with timestamps. Reload 15:23:27. Verified structure.
|
|
154
|
+
11. **Propagated to repo** (`all-configs/karabiner/karabiner.json`). jq reformatted the whole file → restored from backup, applied minimal perl patch (remove rule block, insert simple_modifications). Clean diff.
|
|
155
|
+
12. **User: "keychron is swapped btw wtf"** — the device-level swap double-swapped: the keyboard was *already* presenting the modifier order the user wanted at that moment. Removed `simple_modifications` from all 3 files. Reload 15:26:47. Restored repo formatting again (jq churn), leaving only the complex-rule removal.
|
|
156
|
+
13. **User: "bc thats swapped again"** — with Karabiner completely clean (no complex rule, no device swap, hidutil null), it flipped back. Conclusion: the keyboard firmware/layer state was changing underneath. Re-added the device swap to all 3 files to correct the current bad state. Reload 15:51:24.
|
|
157
|
+
14. Built **`keychron-modifier-swap.sh`** (on/off/status helper) and committed it into the repo so the mapping could be flipped in one command per state change. Repo diff cleaned once more via backup-restore + perl patch (jq kept reformatting).
|
|
158
|
+
|
|
159
|
+
### Tooling + interpretation lessons
|
|
160
|
+
|
|
161
|
+
15. "Is there a CLI way?" — this Mac **lacks `hidutil eventmonitor`**. Documented CLI checks (helper status, hidutil property, modifiermapping, hidutil list). Keychron visible as `0x3434/0x230` matching `13364/560`.
|
|
162
|
+
16. "Any stable GitHub repo?" — KeyCastr (GUI), Objective-See **sniffMK** (CLI-ish, root, old), pqrs **osx-event-observer-examples** (code, not tool). EventViewer stays the probe.
|
|
163
|
+
17. "Why are we doing this?" — articulated the three-layer model: Keychron firmware/layer, macOS native modifier mapping, Karabiner config. Goal: identify which layer owns the current swap.
|
|
164
|
+
18. **EventViewer screenshot lesson:** user pasted a trace showing `from Karabiner DriverKit VirtualHIDKeyboard 1.8.0` → that is Karabiner's **output**, not raw Keychron input. With the correction on, EventViewer shows corrected events; it cannot prove what the keyboard emits. Protocol established: disable correction → press physical Option/Command → read trace → decide.
|
|
165
|
+
19. **"Mac keyboard fine, Keychron swapped" episode:** with the Keychron-only complex rule confirmed as the cause of that particular swap, turned the correction **off in all 3 files**. Reload 10:52:40 (Sep 27). Both keyboards normal.
|
|
166
|
+
20. **"But what is causing it?"** — root cause as understood then: a Keychron-only swap rule existing in config + intermittent state changes + the stale `enabled: false` churn. All corrections off, macOS clean.
|
|
167
|
+
21. **"check it just happened" (Oct 1 morning):** all configs off, hidutil null, Keychron connected normally, config unchanged since Sep 27 10:52:40, only event = wake/reconnect 12:33:05 loading config. With Karabiner fully clean and still broken → the cause was below Karabiner. Led directly into the Oct 1 identity-flip incident.
|
|
168
|
+
|
|
169
|
+
**Postscript:** the external writer of the Sep 25 `enabled: false` flips was never found. With the Oct 15 root cause known, the flips tracked the keyboard's own state changes interacting with the persistent swap rule — not a daemon.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Incident 2026-06-12: Caps Lock was on
|
|
174
|
+
|
|
175
|
+
Left Option appeared to send `left_command`, `Cmd+C` typed `ç`. **Caps Lock was on** — the apparent swap was Caps Lock state + keyboard layout. A factory reset (`Fn + J + Z`) was performed unnecessarily before noticing. Lessons: check Caps Lock first (EventViewer: latched Caps shows as `flags caps` on mouse events); K3 Pro is QMK/VIA; physical Mac/PC switch should be on Mac. This incident recurred as a red herring on 2026-10-15 (trace had `flags caps` on mouse clicks).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Hard-won cross-cutting lessons
|
|
180
|
+
|
|
181
|
+
1. **EventViewer shows post-Karabiner events.** The "from" column names the virtual HID device. Never conclude "firmware emits swapped codes" from an EventViewer trace while any Karabiner rule is active. This single misreading cost most of Oct 15.
|
|
182
|
+
2. **Sandboxed `karabiner_cli` lies.** Inside restricted shells it can hang (`asio.system:1`) or falsely show services absent. Run it with normal permissions before concluding Karabiner is dead.
|
|
183
|
+
3. **Karabiner ANDs device identifiers.** Both interface shapes of the BT identity exist (keyboard+pointing vs keyboard-only) → the two 640 entries in gold state.
|
|
184
|
+
4. **A complex rule with no `enabled` field defaults to enabled.** Karabiner UI toggles write `enabled: false` to the live config only — repo copies need manual deletion, not just UI toggles, or `install.sh` reintroduces the rule.
|
|
185
|
+
5. **Three copies must stay in sync:** repo `karabiner/karabiner.json`, live `~/.config/karabiner/karabiner.json`, rsync copy `~/.config/karabiner/karabiner_scripts/karabiner.json`. After edits: `jq empty` + confirm `core_configuration is updated` in `~/.local/share/karabiner/log/console_user_server.log`.
|
|
186
|
+
6. **The keyboard enumerates under two identities:** USB `0x3434/0x230` (product 560, `Keychron K3 Pro`) and BT `0x3434/0x280` (product 640, `Keychron Bluetooth Keyboard`). Both can be connected simultaneously; only one carries keystrokes. After any reset/re-pair, re-check identity.
|
|
187
|
+
7. **Keychron Launcher layer quirk:** Layer 2 (Windows) can be stuck active regardless of the physical switch. Check which layer is green before editing anything.
|
|
188
|
+
8. **Don't commit config changes while the fix is unproven** (Oct 15 commit attempt was rightly stopped).
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Debug playbook
|
|
193
|
+
|
|
194
|
+
### 0. Check Caps Lock first
|
|
195
|
+
|
|
196
|
+
EventViewer → click mouse. `flags caps` on clicks = Caps latched → press Caps once, retest. (Two incidents were/started as this.)
|
|
197
|
+
|
|
198
|
+
### 1. Verify gold state (below). If gold holds and keys are wrong → keyboard-side, step 5. Do NOT add Karabiner swaps.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
jq '[.profiles[].complex_modifications.rules[] | select((.manipulators//[])|tostring|test("left_option|left_command|right_option|right_command")) | {description, enabled}]' ~/.config/karabiner/karabiner.json
|
|
202
|
+
jq '[.profiles[].devices[] | select(.identifiers.vendor_id==13364) | {identifiers, swap: (.simple_modifications != null and (.simple_modifications|length > 0))}]' ~/.config/karabiner/karabiner.json
|
|
203
|
+
hidutil property --get UserKeyMapping
|
|
204
|
+
defaults read -g com.apple.keyboard.modifiermapping 2>/dev/null
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 2. Identity + transport
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
hidutil list | rg -i 'keychron|karabiner|internal keyboard'
|
|
211
|
+
/Library/Application\ Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli --list-connected-devices # outside sandboxed shells
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Expected BT form: `vendor_id 13364, product_id 640, is_keyboard: true, is_pointing_device: true`. If both 560 and 640 appear, only one carries keystrokes.
|
|
215
|
+
|
|
216
|
+
### 3. Profile + reload
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
/Library/Application\ Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli --show-current-profile-name
|
|
220
|
+
tail -n 20 ~/.local/share/karabiner/log/console_user_server.log
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Healthy: `Default profile`, `core_configuration is updated` after edits, no parse errors.
|
|
224
|
+
|
|
225
|
+
### 4. EventViewer probe
|
|
226
|
+
|
|
227
|
+
Clear → press down/up one at a time: physical left Option, left Command, right Command, Caps, `a`. Expected healthy: `left_option`, `left_command`, `right_command`, Caps = super chord, `a`. Interpret as post-Karabiner (lesson 1).
|
|
228
|
+
|
|
229
|
+
### 5. Keyboard-side fixes — the only class of fix that ever held
|
|
230
|
+
|
|
231
|
+
1. Caps Lock off (step 0).
|
|
232
|
+
2. Physical OS switch firmly to Mac; power-cycle BT.
|
|
233
|
+
3. Keychron Launcher (`launcher.keychron.com`, USB cable mode): check which layer is green. Layer 0 = Mac base (`Ctrl LOpt LCmd space RCmd`). If Layer 2 stuck active: remap its three positions to `Alt`/`Win`/`Win` as workaround.
|
|
234
|
+
4. Factory reset `Fn + J + Z` (~4s), re-pair `Fn + 1/2/3` hold ~4s.
|
|
235
|
+
5. Delete the BT pairing in macOS System Settings → Bluetooth, re-pair fresh.
|
|
236
|
+
6. Firmware reflash **last** — exact K3 Pro model/layout firmware only. This is the escalation for the stuck Layer 2 selector.
|
|
237
|
+
|
|
238
|
+
### Do / Don't
|
|
239
|
+
|
|
240
|
+
**Do:** keep all three config copies in sync; delete (not disable) swap rules in repo copies; validate JSON; confirm reload; re-check device identity after every reset/re-pair.
|
|
241
|
+
|
|
242
|
+
**Don't:** re-add any Keychron Option/Command swap to Karabiner; add global Command/Option swaps; commit unproven fixes; trust sandboxed CLI failures; read EventViewer as raw firmware output; edit Launcher layers before checking which layer is actually active.
|