We take two versions of the layout:
% new="WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20"
% new="WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20"
% old="Glorious Engrammer v41"
% mkdir tmp
mkdir: cannot create directory ‘tmp’: File exists
% cp ~/Downloads/$new.json tmp
% cp ~/Downloads/$old.json tmp
% cd tmp
~/projects/glovebox/tmp % ls
'Glorious Engrammer v41.json' 'WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20.json'
% mkdir $new
% mkdir $old
Extract both layouts using glovebox:
% uv run python3 -m glovebox.cli keymap extract $old.json $old/files
2025-05-29 23:04:16,391 - glovebox.keymap.extract - INFO - Creating output directories: /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files and /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers
2025-05-29 23:04:16,392 - glovebox.keymap.extract - INFO - Loading keymap data from Glorious Engrammer v41.json
2025-05-29 23:04:16,398 - glovebox.keymap.extract - INFO - Validating loaded keymap data structure...
2025-05-29 23:04:16,424 - glovebox.keymap.extract - INFO - Extracted custom_devicetree to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/device.dtsi
2025-05-29 23:04:16,425 - glovebox.keymap.extract - INFO - Extracted custom_defined_behaviors to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/keymap.dtsi
2025-05-29 23:04:16,425 - glovebox.keymap.extract - INFO - Extracted base configuration to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/base.json
2025-05-29 23:04:16,425 - glovebox.keymap.extract - INFO - Extracting 32 layers...
2025-05-29 23:04:16,427 - glovebox.keymap.extract - INFO - Extracted layer 'Enthium' to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/Enthium.json
2025-05-29 23:04:16,428 - glovebox.keymap.extract - INFO - Extracted layer 'Engrammer' to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/Engrammer.json
2025-05-29 23:04:16,429 - glovebox.keymap.extract - INFO - Extracted layer 'Engram' to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/Engram.json
...
2025-05-29 23:04:16,444 - glovebox.keymap.extract - INFO - Extracted layer 'Magic' to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files/layers/Magic.json
2025-05-29 23:04:16,444 - glovebox.keymap.extract - INFO - Finished extracting layers to /home/rick/projects/glovebox/tmp/Glorious Engrammer v41/files
% uv run python3 -m glovebox.cli keymap extract $new.json $new/files
2025-05-29 23:04:26,156 - glovebox.keymap.extract - INFO - Creating output directories: /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files and /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers
2025-05-29 23:04:26,156 - glovebox.keymap.extract - INFO - Loading keymap data from WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20.json
2025-05-29 23:04:26,163 - glovebox.keymap.extract - INFO - Validating loaded keymap data structure...
2025-05-29 23:04:26,170 - glovebox.keymap.extract - INFO - Extracted custom_devicetree to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/device.dtsi
2025-05-29 23:04:26,170 - glovebox.keymap.extract - INFO - Extracted custom_defined_behaviors to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/keymap.dtsi
2025-05-29 23:04:26,170 - glovebox.keymap.extract - INFO - Extracted base configuration to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/base.json
2025-05-29 23:04:26,170 - glovebox.keymap.extract - INFO - Extracting 32 layers...
2025-05-29 23:04:26,171 - glovebox.keymap.extract - INFO - Extracted layer 'Enthium' to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Enthium.json
2025-05-29 23:04:26,171 - glovebox.keymap.extract - INFO - Extracted layer 'Engrammer' to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Engrammer.json
2025-05-29 23:04:26,172 - glovebox.keymap.extract - INFO - Extracted layer 'Engram' to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Engram.json
...
2025-05-29 23:04:26,185 - glovebox.keymap.extract - INFO - Extracted layer 'Magic' to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Magic.json
2025-05-29 23:04:26,185 - glovebox.keymap.extract - INFO - Finished extracting layers to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files
% ls
'Glorious Engrammer v41' 'Glorious Engrammer v41.json'
'WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20' 'WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20.json'
% tree
.
├── 'Glorious Engrammer v41'
│ └── files
│ ├── layers
│ │ ├── Canary.json
│ │ ├── Colemak.json
│ │ ├── ColemakDH.json
│ │ ├── Cursor.json
│ │ ├── device.dtsi
│ │ ├── Dvorak.json
│ │ ├── Emoji.json
│ │ ├── Engram.json
│ │ ├── Engrammer.json
│ │ ├── Enthium.json
│ │ ├── Factory.json
│ │ ├── Function.json
│ │ ├── Gaming.json
│ │ ├── keymap.dtsi
│ │ ├── LeftIndex.json
│ │ ├── LeftMiddy.json
│ │ ├── LeftPinky.json
│ │ ├── LeftRingy.json
│ │ ├── Lower.json
│ │ ├── Magic.json
│ │ ├── Mouse.json
│ │ ├── MouseFast.json
│ │ ├── MouseSlow.json
│ │ ├── MouseWarp.json
│ │ ├── Number.json
│ │ ├── QWERTY.json
│ │ ├── RightIndex.json
│ │ ├── RightMiddy.json
│ │ ├── RightPinky.json
│ │ ├── RightRingy.json
│ │ ├── Symbol.json
│ │ ├── System.json
│ │ ├── Typing.json
│ │ └── World.json
│ └── base.json
├── 'WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20'
│ └── files
│ ├── layers
│ │ ├── Canary.json
│ │ ├── Colemak.json
│ │ ├── ColemakDH.json
│ │ ├── Cursor.json
│ │ ├── device.dtsi
│ │ ├── Dvorak.json
│ │ ├── Emoji.json
│ │ ├── Engram.json
│ │ ├── Engrammer.json
│ │ ├── Enthium.json
│ │ ├── Factory.json
│ │ ├── Function.json
│ │ ├── Gaming.json
│ │ ├── keymap.dtsi
│ │ ├── LeftIndex.json
│ │ ├── LeftMiddy.json
│ │ ├── LeftPinky.json
│ │ ├── LeftRingy.json
│ │ ├── Lower.json
│ │ ├── Magic.json
│ │ ├── Mouse.json
│ │ ├── MouseFast.json
│ │ ├── MouseSlow.json
│ │ ├── MouseWarp.json
│ │ ├── Number.json
│ │ ├── QWERTY.json
│ │ ├── RightIndex.json
│ │ ├── RightMiddy.json
│ │ ├── RightPinky.json
│ │ ├── RightRingy.json
│ │ ├── Symbol.json
│ │ ├── System.json
│ │ ├── Typing.json
│ │ └── World.json
│ └── base.json
├── 'Glorious Engrammer v41.json'
└── 'WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20.json'
You can diff individual layers:
% diff --unified $old/files/layers/Symbol.json $new/files/layers/Symbol.json
The diff shows changes like key position mappings (LBKT to RBKT, RBKT to SEMI), removal of custom behaviors, and layout modifications.
--- "Glorious Engrammer v41/files/layers/Symbol.json" 2025-05-29 23:04:16.438630901 +0200
+++ "WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Symbol.json" 2025-05-29 23:04:26.181038745 +0200
@@ -4,10 +4,10 @@
"locale": "en-US",
"uuid": "",
"parent_uuid": "",
- "date": "2025-01-13T16:31:59Z",
+ "date": "2025-05-29T16:16:50Z",
"creator": "rick3",
"title": "Layer: Symbol",
- "notes": "Extracted layer 'Symbol' from Glorious Engrammer v41.json",
+ "notes": "Extracted layer 'Symbol' from WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20.json",
"tags": [
"symbol"
],
@@ -69,7 +69,7 @@
"value": "&kp",
"params": [
{
- "value": "LBKT",
+ "value": "RBKT",
"params": []
}
]
@@ -96,7 +96,7 @@
"value": "&kp",
"params": [
{
- "value": "RBKT",
+ "value": "SEMI",
"params": []
}
]
@@ -115,40 +115,20 @@
"params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&sk RIGHT_INDEX_MOD",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&sk RIGHT_MIDDY_MOD",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&sk RIGHT_RINGY_MOD",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&sk RIGHT_PINKY_MOD",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
"value": "&none",
@@ -158,7 +138,7 @@
"value": "&kp",
"params": [
{
- "value": "EXCL",
+ "value": "LBKT",
"params": []
}
]
@@ -167,7 +147,7 @@
"value": "&kp",
"params": [
{
- "value": "COMMA",
+ "value": "EXCL",
"params": []
}
]
@@ -194,7 +174,7 @@
"value": "&kp",
"params": [
{
- "value": "SEMI",
+ "value": "COMMA",
"params": []
}
]
@@ -218,49 +198,44 @@
]
},
{
- "value": "&kp",
+ "value": "Custom",
"params": [
{
- "value": "LEFT",
+ "value": "&sk RIGHT_INDEX_MOD",
"params": []
}
]
},
{
- "value": "&kp",
+ "value": "Custom",
"params": [
{
- "value": "UP",
+ "value": "&sk RIGHT_MIDDY_MOD",
"params": []
}
]
},
{
- "value": "&kp",
+ "value": "Custom",
"params": [
{
- "value": "DOWN",
+ "value": "&sk RIGHT_RINGY_MOD",
"params": []
}
]
},
{
- "value": "&kp",
+ "value": "Custom",
"params": [
{
- "value": "RIGHT",
+ "value": "&sk RIGHT_PINKY_MOD",
"params": []
}
]
},
{
- "value": "&kp",
- "params": [
- {
- "value": "HOME",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
"value": "&kp",
@@ -362,13 +337,8 @@
]
},
{
- "value": "&kp",
- "params": [
- {
- "value": "END",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
"value": "&kp",
@@ -452,13 +422,8 @@
]
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&tog LAYER_Symbol",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
"value": "&none",
@@ -501,31 +466,26 @@
]
},
{
- "value": "Custom",
+ "value": "&kp",
"params": [
{
- "value": "&select_word",
+ "value": "INS",
"params": []
}
]
},
{
- "value": "Custom",
+ "value": "&kp",
"params": [
{
- "value": "&select_line",
+ "value": "ESC",
"params": []
}
]
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&select_all",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
"value": "&none",
@@ -603,44 +563,29 @@
"params": []
},
{
- "value": "&none",
- "params": []
- },
- {
"value": "Custom",
"params": [
{
- "value": "&kp _UNDO",
+ "value": "&tog LAYER_Symbol",
"params": []
}
]
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&kp _REDO",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&extend_word",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
},
{
- "value": "Custom",
- "params": [
- {
- "value": "&extend_line",
- "params": []
- }
- ]
+ "value": "&none",
+ "params": []
+ },
+ {
+ "value": "&none",
+ "params": []
},
{
"value": "&none",
It's possible to change the base of the JSON to modify the description/title/etc.:
cat WIP\ Nth11\ Bas52\ Cmb20\ Cr18\ Nm12\ Fn13\ Sm19\ St14\ Mu25\ Ej6\ Lw6\ Gm2\ Rgb21\ h+20/files/base.json
The base.json contains metadata like keyboard type, title, creator, layer names, and configuration parameters.
{
"keyboard": "glove80",
"title": "Glorious Engrammer v42 preview with v41 QWERTY layout",
"creator": "rick3",
"locale": "en-US",
"notes": "based on https://my.glove80.com/#/layout/user/c0513215-6b64-4613-b1c7-a511c9f095a4",
"firmware_api_version": "1",
"uuid": "",
"date": "2025-05-29T16:16:50Z",
"layers": [],
"layer_names": [
"Enthium",
"Engrammer",
"Engram",
"Dvorak",
"Colemak",
"QWERTY",
"ColemakDH",
"Canary",
"Typing",
"LeftPinky",
"LeftRingy",
"LeftMiddy",
"LeftIndex",
"RightPinky",
"RightRingy",
"RightMiddy",
"RightIndex",
"Cursor",
"Number",
"Function",
"Emoji",
"World",
"Symbol",
"System",
"Mouse",
"MouseSlow",
"MouseFast",
"MouseWarp",
"Gaming",
"Factory",
"Lower",
"Magic"
],
"holdTaps": [],
"combos": [],
"macros": [],
"kconfig": {},
"custom_defined_behaviors": "",
"custom_devicetree": "",
"parent_uuid": "c0513215-6b64-4613-b1c7-a511c9f095a4",
"tags": [
"sunaku",
"custom-defined-behaviors",
"home-row-mods",
"rgb",
"gaming-layer",
"symbol-layer",
"programming",
"vim",
"unicode",
"emoji",
"enthium",
"engram",
"dvorak",
"colemak",
"qwerty",
"canary"
],
"config_parameters": [
{
"paramName": "HID_POINTING",
"value": "y"
},
{
"paramName": "EXPERIMENTAL_RGB_LAYER",
"value": "y"
}
],
"inputListeners": []
}
Let's copy the old QWERTY layout:
% bak $new/files/layers/QWERTY.json
% cp $old/files/layers/QWERTY.json $new/files/layers/QWERTY.json
We can now reassemble it into a JSON file:
% uv run python3 -m glovebox.cli keymap combine $new/files --output $new/mine-glorious-engrammer-v42pre.json
2025-05-29 23:32:49,016 - glovebox.keymap.combine - INFO - Combining layers from /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files into /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/mine-glorious-engrammer-v42pre.json
2025-05-29 23:32:49,016 - glovebox.keymap.combine - INFO - Expecting 32 layers based on base.json: ['Enthium', 'Engrammer', 'Engram', 'Dvorak', 'Colemak', 'QWERTY', 'ColemakDH', 'Canary', 'Typing', 'LeftPinky', 'LeftRingy', 'LeftMiddy', 'LeftIndex', 'RightPinky', 'RightRingy', 'RightMiddy', 'RightIndex', 'Cursor', 'Number', 'Function', 'Emoji', 'World', 'Symbol', 'System', 'Mouse', 'MouseSlow', 'MouseFast', 'MouseWarp', 'Gaming', 'Factory', 'Lower', 'Magic']
2025-05-29 23:32:49,016 - glovebox.keymap.combine - INFO - Determined expected key count per layer: 80 (from /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/files/layers/Enthium.json)
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Processing layer 'Enthium' from file: Enthium.json
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Added layer 'Enthium' (index 0)
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Processing layer 'Engrammer' from file: Engrammer.json
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Added layer 'Engrammer' (index 1)
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Processing layer 'Engram' from file: Engram.json
2025-05-29 23:32:49,017 - glovebox.keymap.combine - INFO - Added layer 'Engram' (index 2)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'Dvorak' from file: Dvorak.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'Dvorak' (index 3)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'Colemak' from file: Colemak.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'Colemak' (index 4)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'QWERTY' from file: QWERTY.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'QWERTY' (index 5)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'ColemakDH' from file: ColemakDH.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'ColemakDH' (index 6)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'Canary' from file: Canary.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'Canary' (index 7)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'Typing' from file: Typing.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'Typing' (index 8)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'LeftPinky' from file: LeftPinky.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'LeftPinky' (index 9)
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Processing layer 'LeftRingy' from file: LeftRingy.json
2025-05-29 23:32:49,018 - glovebox.keymap.combine - INFO - Added layer 'LeftRingy' (index 10)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'LeftMiddy' from file: LeftMiddy.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'LeftMiddy' (index 11)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'LeftIndex' from file: LeftIndex.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'LeftIndex' (index 12)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'RightPinky' from file: RightPinky.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'RightPinky' (index 13)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'RightRingy' from file: RightRingy.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'RightRingy' (index 14)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'RightMiddy' from file: RightMiddy.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'RightMiddy' (index 15)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'RightIndex' from file: RightIndex.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'RightIndex' (index 16)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'Cursor' from file: Cursor.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'Cursor' (index 17)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'Number' from file: Number.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'Number' (index 18)
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Processing layer 'Function' from file: Function.json
2025-05-29 23:32:49,019 - glovebox.keymap.combine - INFO - Added layer 'Function' (index 19)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'Emoji' from file: Emoji.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'Emoji' (index 20)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'World' from file: World.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'World' (index 21)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'Symbol' from file: Symbol.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'Symbol' (index 22)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'System' from file: System.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'System' (index 23)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'Mouse' from file: Mouse.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'Mouse' (index 24)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'MouseSlow' from file: MouseSlow.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'MouseSlow' (index 25)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'MouseFast' from file: MouseFast.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'MouseFast' (index 26)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'MouseWarp' from file: MouseWarp.json
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Added layer 'MouseWarp' (index 27)
2025-05-29 23:32:49,020 - glovebox.keymap.combine - INFO - Processing layer 'Gaming' from file: Gaming.json
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Added layer 'Gaming' (index 28)
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Processing layer 'Factory' from file: Factory.json
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Added layer 'Factory' (index 29)
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Processing layer 'Lower' from file: Lower.json
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Added layer 'Lower' (index 30)
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Processing layer 'Magic' from file: Magic.json
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Added layer 'Magic' (index 31)
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Successfully processed 32 out of 32 expected layers.
2025-05-29 23:32:49,021 - glovebox.keymap.combine - INFO - Restored custom_devicetree from layers/device.dtsi.
2025-05-29 23:32:49,023 - glovebox.keymap.combine - INFO - Restored custom_defined_behaviors from layers/keymap.dtsi.
2025-05-29 23:32:49,036 - glovebox.keymap.combine - INFO - Combined keymap saved successfully to /home/rick/projects/glovebox/tmp/WIP Nth11 Bas52 Cmb20 Cr18 Nm12 Fn13 Sm19 St14 Mu25 Ej6 Lw6 Gm2 Rgb21 h+20/mine-glorious-engrammer-v42pre.json
Navigate to the MoErgo Layout Editor.
Go to a new keymap and enable the "Local Backup and Restore" option in "Experimental Settings".
Then go back to the layer at the bottom to import the JSON.
Build and wait...
This used to work but requires significant effort. The process was stopped partway and needs refactoring.
If we download the keymap generated by MoErgo, we can compile it:
~/projects/glovebox/tmp % mine=28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious\ Engrammer\ v42\ preview\ with\ v41\ QWERTY\ layout
% mkdir $mine
mkdir: cannot create directory ‘28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout’: File exists
% cp ~/Downloads/28e97485-dab5-4afb-afbc-5de5f1c52c45_v25.05_Glorious\ Engrammer\ v42\ preview\ with\ v41\ QWERTY\ layout.uf2 .
% cp ~/Downloads/$mine.keymap $mine/glove80.keymap
We need to create the kconfig
% cat glove80.conf
# CONFIG_EXPERIMENTAL_RGB_LAYER=y
CONFIG_ZMK_POINTING=y
CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN=y
Using v25.05 everything it working correctly if no EXPERIMENTAL_RGB_LAYER
% uv run python3 -m glovebox.cli --debug firmware build --output-dir fw/ --branch v25.05 glove80.keymap glove80.conf 2025-05-30 00:19:17,542 - glovebox.build.docker - INFO - Starting Docker build with ID: 20250530-001917-ff849575 2025-05-30 00:19:17,542 - glovebox.build.docker - DEBUG - Docker command: docker run --rm -v /home/rick/projects/glovebox/tmp/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout/fw/artifacts-20250530-001917-ff849575:/build -e REPO=moergo-sc/zmk -e BRANCH=v25.05 -e JOBS=24 -e KEYMAP=glove80.keymap -e KCONFIG=glove80.conf -e BUILD_DIR=/build moergo-zmk-build:latest [2025-05-29 22:19:17] [INFO] ========== Build Environment ========== [2025-05-29 22:19:17] [INFO] Build ID: 8984a4e0-v25.05-598b0350-20250529221917 [2025-05-29 22:19:17] [INFO] Build directory: /build [2025-05-29 22:19:17] [INFO] Builder directory: /app/builder [2025-05-29 22:19:17] [INFO] Git repository path: /app/src [2025-05-29 22:19:17] [INFO] Branch: v25.05 [2025-05-29 22:19:17] [INFO] Repository: moergo-sc/zmk [2025-05-29 22:19:17] [INFO] Keymap: glove80.keymap [2025-05-29 22:19:17] [INFO] Kconfig: glove80.conf [2025-05-29 22:19:17] [INFO] Output name: glove80 [2025-05-29 22:19:17] [INFO] Number of jobs: 24 [2025-05-29 22:19:17] [INFO] Build log: /build/artifacts/8984a4e0-v25.05-598b0350-20250529221917/build-8984a4e0-v25.05-598b0350-20250529221917.log [2025-05-29 22:19:17] [INFO] Artifacts directory: /build/artifacts/8984a4e0-v25.05-598b0350-20250529221917 [2025-05-29 22:19:17] [INFO] Temporary directory: /tmp [2025-05-29 22:19:17] [INFO] Nix version: nix (Nix) 2.18.4 [2025-05-29 22:19:17] [INFO] ====================================== [2025-05-29 22:19:17] [INFO] /build/glove80.conf [2025-05-29 22:19:17] [INFO] # CONFIG_EXPERIMENTAL_RGB_LAYER=y CONFIG_ZMK_POINTING=y CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN=y [2025-05-29 22:19:17] [INFO] Verified keymap and kconfig files exist [2025-05-29 22:19:17] [INFO] Starting phase: Repository Setup ::group::Repository Setup [2025-05-29 22:19:17] [INFO] Checking out branch: v25.05 From https://github.com/moergo-sc/zmk
- tag v25.05 -> FETCH_HEAD HEAD is now at 598b0350 Configure Glove80 board definitions for custom features [2025-05-29 22:19:18] [INFO] Git commit: 598b03508c308de2139c61216eb1b2fdc447501e [2025-05-29 22:19:18] [INFO] Phase completed in 1s ::endgroup:: [2025-05-29 22:19:18] [INFO] Starting phase: Build Preparation ::group::Build Preparation [2025-05-29 22:19:18] [INFO] Build log: /build/artifacts/8984a4e0-v25.05-598b0350-20250529221917/build-8984a4e0-v25.05-598b0350-20250529221917.log [2025-05-29 22:19:18] [INFO] Artifacts directory: /build/artifacts/8984a4e0-v25.05-598b0350-20250529221917 [2025-05-29 22:19:18] [INFO] Phase completed in 0s ::endgroup:: [2025-05-29 22:19:18] [INFO] Starting phase: Firmware Build ::group::Firmware Build [2025-05-29 22:19:18] [INFO] Building firmware... [2025-05-29 22:19:18] [INFO] Running nix-build with args: keymap=glove80.keymap, kconfig=glove80.conf, outputName=glove80, buildId=8984a4e0-v25.05-598b0350-20250529221917 JOBS=24 KCONFIG=glove80.conf HOSTNAME=44a60baeea56 REPO=moergo-sc/zmk BUILDER_DIR=/app/builder ZMK_DIR=/app/src ENV=/etc/profile.d/nix.sh PWD=/app/builder NIX_PROFILES=/nix/var/nix/profiles/default /root/.nix-profile NIX_PATH=moergo-zmk=/app/src:builder=/app/builder:nixpkgs=/nix/store/mcbn9iy9pnnk040cbrp3a5h3hfgaxvgc-fake_nixpkgs HOME=/root NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt KEYMAP=glove80.keymap BRANCH=v25.05 USER=root SHLVL=1 BASH_ENV=/etc/profile.d/nix.sh PAGER=cat APP_DIR=/app NIX_BUILD_SHELL=/bin/bash SSL_CERT_FILE=/nix/store/gn6h902da0glvbpfw9pdj0idrc7483bf-nss-cacert-3.101/etc/ssl/certs/ca-bundle.crt BUILD_DIR=/build PATH=/root/.nix-profile/bin:/app/builder/bin:/usr/bin:/bin _=/usr/bin/env OLDPWD=/app/src these 6 derivations will be built: /nix/store/5md3j0v2a0bp0pyd63pccis202p597gp-zmk_glove80_lh.drv /nix/store/br7d8hchjiv898lsqav3shns97k1j3nb-collect_build_artifact_lh.drv /nix/store/7f1k72642rgyv47jizz5rf8yfzk4qnim-zmk_glove80_rh.drv /nix/store/lbjks937ssg9v1jypmsd6nkr9cxqg4j3-collect_build_artifact_rh.drv /nix/store/bq10khs50z5hwq9av1jlnc79slqrbwm8-combined_firmware.drv /nix/store/4fzfd2xygksdgr0snkn3g9ns8746w7i2-glove80-firmware.drv building '/nix/store/5md3j0v2a0bp0pyd63pccis202p597gp-zmk_glove80_lh.drv'... building '/nix/store/7f1k72642rgyv47jizz5rf8yfzk4qnim-zmk_glove80_rh.drv'... Running phase: unpackPhase unpacking source archive /nix/store/kmfgl81pcqd2hj9ingbchmna6ilx1cb6-source Running phase: unpackPhase unpacking source archive /nix/store/kmfgl81pcqd2hj9ingbchmna6ilx1cb6-source source root is source/app source root is source/app Running phase: patchPhase Running phase: patchPhase Running phase: updateAutotoolsGnuConfigScriptsPhase Running phase: updateAutotoolsGnuConfigScriptsPhase Running phase: configurePhase fixing cmake files... Running phase: configurePhase fixing cmake files... ... [343/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mutex.c.obj [344/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timer.c.obj [345/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timeout.c.obj [346/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/dynamic_disabled.c.obj [347/362] Building C object modules/hal_nordic/nrfx/CMakeFiles/modules__hal_nordic__nrfx.dir/nix/store/m4dajjqch946470gdyh7v2kmvps4bk8w-zmk-module-hal_nordic/hal_nordic/nrfx/drivers/src/nrfx_gpiote.c.obj [348/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/work.c.obj [349/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/poll.c.obj [350/362] Building C object modules/hal_nordic/nrfx/CMakeFiles/modules__hal_nordic__nrfx.dir/nix/store/m4dajjqch946470gdyh7v2kmvps4bk8w-zmk-module-hal_nordic/hal_nordic/nrfx/drivers/src/nrfx_spim.c.obj [351/362] Building C object modules/hal_nordic/nrfx/CMakeFiles/modules__hal_nordic__nrfx.dir/nix/store/m4dajjqch946470gdyh7v2kmvps4bk8w-zmk-module-hal_nordic/hal_nordic/nrfx/drivers/src/nrfx_usbd.c.obj [352/362] Linking C static library modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a [353/362] Building C object zephyr/subsys/bluetooth/host/CMakeFiles/subsys__bluetooth__host.dir/gatt.c.obj [354/362] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sched.c.obj [355/362] Linking C static library zephyr/subsys/bluetooth/host/libsubsys__bluetooth__host.a [356/362] Linking C static library zephyr/kernel/libkernel.a [321/321] Linking C executable zephyr/zmk.elf /nix/store/mczmw3rln2jm6nm080dapyjpj3833rg9-gcc-arm-embedded-12.3.rel1/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.bfd: warning: zephyr/zmk.elf has a LOAD segment with RWX permissions Memory region Used Size Region Size %age Used FLASH: 180572 B 792 KB 22.27% RAM: 35924 B 256 KB 13.70% IDT_LIST: 0 GB 2 KB 0.00% /nix/store/kv2vw4bhcf23h2zjs7h8sxky9jsbzr1p-zephyr/zephyr/scripts/build/uf2conv.py:204: SyntaxWarning: invalid escape sequence '\s' words = re.split('\s+', line) Converting to uf2, output size: 361472, start address: 0x26000 Wrote 361472 bytes to zmk.uf2 Running phase: installPhase Running phase: fixupPhase shrinking RPATHs of ELF executables and libraries in /nix/store/q5xm8ycc11ffg1hbqayj9r71r7g2r7dz-zmk_glove80_rh shrinking /nix/store/q5xm8ycc11ffg1hbqayj9r71r7g2r7dz-zmk_glove80_rh/zmk.elf patchelf: cannot find section '.dynamic'. The input file is most likely statically linked checking for references to /tmp/nix-build-zmk_glove80_rh.drv-0/ in /nix/store/q5xm8ycc11ffg1hbqayj9r71r7g2r7dz-zmk_glove80_rh... patchelf: cannot find section '.dynamic'. The input file is most likely statically linked patching script interpreter paths in /nix/store/q5xm8ycc11ffg1hbqayj9r71r7g2r7dz-zmk_glove80_rh building '/nix/store/lbjks937ssg9v1jypmsd6nkr9cxqg4j3-collect_build_artifact_rh.drv'... [357/362] Linking C executable zephyr/zephyr_pre0.elf /nix/store/mczmw3rln2jm6nm080dapyjpj3833rg9-gcc-arm-embedded-12.3.rel1/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.bfd: warning: zephyr/zephyr_pre0.elf has a LOAD segment with RWX permissions Copying build files from /nix/store/q5xm8ycc11ffg1hbqayj9r71r7g2r7dz-zmk_glove80_rh to /nix/store/aj2y2hal4sy3g8kkd6m0279z406ispvr-collect_build_artifact_rh [358/362] Generating linker.cmd [359/362] Generating isr_tables.c, isrList.bin [360/362] Building C object zephyr/CMakeFiles/zephyr_final.dir/misc/empty_file.c.obj [361/362] Building C object zephyr/CMakeFiles/zephyr_final.dir/isr_tables.c.obj [362/362] Linking C executable zephyr/zmk.elf /nix/store/mczmw3rln2jm6nm080dapyjpj3833rg9-gcc-arm-embedded-12.3.rel1/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.bfd: warning: zephyr/zmk.elf has a LOAD segment with RWX permissions Memory region Used Size Region Size %age Used FLASH: 349220 B 792 KB 43.06% RAM: 101004 B 256 KB 38.53% IDT_LIST: 0 GB 2 KB 0.00% /nix/store/kv2vw4bhcf23h2zjs7h8sxky9jsbzr1p-zephyr/zephyr/scripts/build/uf2conv.py:204: SyntaxWarning: invalid escape sequence '\s' words = re.split('\s+', line) Converting to uf2, output size: 698880, start address: 0x26000 Wrote 698880 bytes to zmk.uf2 Running phase: installPhase Running phase: fixupPhase shrinking RPATHs of ELF executables and libraries in /nix/store/w6i59qhl0i90y1cr5xmpdpfz1bh90cfh-zmk_glove80_lh shrinking /nix/store/w6i59qhl0i90y1cr5xmpdpfz1bh90cfh-zmk_glove80_lh/zmk.elf patchelf: cannot find section '.dynamic'. The input file is most likely statically linked checking for references to /tmp/nix-build-zmk_glove80_lh.drv-0/ in /nix/store/w6i59qhl0i90y1cr5xmpdpfz1bh90cfh-zmk_glove80_lh... patchelf: cannot find section '.dynamic'. The input file is most likely statically linked patching script interpreter paths in /nix/store/w6i59qhl0i90y1cr5xmpdpfz1bh90cfh-zmk_glove80_lh building '/nix/store/br7d8hchjiv898lsqav3shns97k1j3nb-collect_build_artifact_lh.drv'... Copying build files from /nix/store/w6i59qhl0i90y1cr5xmpdpfz1bh90cfh-zmk_glove80_lh to /nix/store/vz0pqjdiz1kf74ziazhkvcp8k8macihy-collect_build_artifact_lh building '/nix/store/bq10khs50z5hwq9av1jlnc79slqrbwm8-combined_firmware.drv'... cat /nix/store/vz0pqjdiz1kf74ziazhkvcp8k8macihy-collect_build_artifact_lh/zmk.uf2 /nix/store/aj2y2hal4sy3g8kkd6m0279z406ispvr-collect_build_artifact_rh/zmk.uf2 > /nix/store/w0d65qidd7j8xyzslp0gqv3mwqnv6csw-combined_firmware/glove80.uf2 building '/nix/store/4fzfd2xygksdgr0snkn3g9ns8746w7i2-glove80-firmware.drv'... finishing /nix/store/yx94wa722k47dj5mxdrx8s2p2b1fxz7d-glove80-firmware /nix/store/yx94wa722k47dj5mxdrx8s2p2b1fxz7d-glove80-firmware ::endgroup:: [2025-05-29 22:19:39] [INFO] Phase completed in 21s ::group::Create Build Artifacts [2025-05-29 22:19:39] [INFO] Starting phase: Create Build Artifacts [2025-05-29 22:19:39] [INFO] Build artifacts saved to /build/artifacts/8984a4e0-v25.05-598b0350-20250529221917/ [2025-05-29 22:19:39] [INFO] Firmware available at /build/glove80.uf2 [2025-05-29 22:19:39] [INFO] Phase completed in 0s ::endgroup:: [2025-05-29 22:19:39] [INFO] Build process completed successfully 2025-05-30 00:19:39,455 - glovebox.build.docker - INFO - Firmware found and copied to: /home/rick/projects/glovebox/tmp/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout/fw/glove80.uf2
Folder output, it's possible to recover the devicetree_generated if the compilation failed. That allow to debug more easily the root of the issue.
% \eza -la --sort=modified -R fw drwxr-xr-x - rick 30 May 00:19 artifacts-20250530-001917-ff849575 .r--r--r-- 1.1M rick 30 May 00:19 glove80.uf2
fw/artifacts-20250530-001917-ff849575: .rw-r--r-- 446k rick 30 May 00:03 glove80.keymap .rw-r--r-- 96 rick 30 May 00:11 glove80.conf drwxr-xr-x - root 30 May 00:19 artifacts
fw/artifacts-20250530-001917-ff849575/artifacts: drwxr-xr-x - root 30 May 00:19 8984a4e0-v25.05-598b0350-20250529221917
fw/artifacts-20250530-001917-ff849575/artifacts/8984a4e0-v25.05-598b0350-20250529221917: .rw-r--r-- 4.0M root 30 May 00:19 build-8984a4e0-v25.05-598b0350-20250529221917.log dr-xr-xr-x - root 30 May 00:19 lf dr-xr-xr-x - root 30 May 00:19 rh .r--r--r-- 1.1M root 30 May 00:19 glove80.uf2 .rw-r--r-- 446k root 30 May 00:19 glove80.keymap .rw-r--r-- 96 root 30 May 00:19 glove80.conf .r--r--r-- 679 root 30 May 00:19 build-info.json
fw/artifacts-20250530-001917-ff849575/artifacts/8984a4e0-v25.05-598b0350-20250529221917/lf: .r--r--r-- 699k root 30 May 00:19 zmk.uf2 .r-xr-xr-x 349k root 30 May 00:19 zmk.bin .r--r--r-- 982k root 30 May 00:19 zmk.hex .r--r--r-- 264k root 30 May 00:19 zmk.dts .r--r--r-- 62k root 30 May 00:19 zmk.kconfig .r-xr-xr-x 7.2M root 30 May 00:19 zmk.elf .r--r--r-- 9.6M root 30 May 00:19 devicetree_generated.h
fw/artifacts-20250530-001917-ff849575/artifacts/8984a4e0-v25.05-598b0350-20250529221917/rh: .r-xr-xr-x 181k root 30 May 00:19 zmk.bin .r--r--r-- 361k root 30 May 00:19 zmk.uf2 .r--r--r-- 508k root 30 May 00:19 zmk.hex .r--r--r-- 264k root 30 May 00:19 zmk.dts .r--r--r-- 61k root 30 May 00:19 zmk.kconfig .r-xr-xr-x 5.2M root 30 May 00:19 zmk.elf .r--r--r-- 9.6M root 30 May 00:19 devicetree_generated.h
Building with PR34 is not working due to missing include I don't know how Moergo inject them.
/build/glove80.keymap:23:10: fatal error: dt-bindings/zmk/pointing.h: No such file or directory
## Flashing
The flashing process automatically detects and flashes both halves of the keyboard sequentially.
```sh
~/projects/glovebox/tmp % cd $mine
~/pr/glovebox/tm/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout % uv run python3 -m glovebox.cli firmware flash fw/$mine.uf2
% uv run python3 -m glovebox.cli firmware flash fw/glove80.uf2
2025-05-30 00:29:57,666 - glovebox.flash.lsdev - INFO - USB device monitoring started
2025-05-30 00:29:57,666 - glovebox.flash.usb - INFO - --- Waiting for device 1/2 matching 'vendor=Adafruit and serial~=GLV80-.* and removable=true' ---
2025-05-30 00:29:57,666 - glovebox.flash.lsdev - INFO - NAME SIZE TYPE REMOVABLE MODEL VENDOR SERIAL
2025-05-30 00:29:57,666 - glovebox.flash.lsdev - INFO - ---------------------------------------------------------------------------------------------------------
2025-05-30 00:30:06,170 - glovebox.flash.lsdev - INFO - New device detected: /dev/sda
2025-05-30 00:30:06,171 - glovebox.flash.usb - INFO - Attempting to flash sda...
2025-05-30 00:30:06,172 - glovebox.flash.usb - INFO - Attempt 1/3: Mounting device /dev/sda (GLV80-99287219E27D6FC3_GLV80LHBOOT)...
2025-05-30 00:30:06,949 - glovebox.flash.usb - INFO - Device GLV80-99287219E27D6FC3_GLV80LHBOOT mounted at /run/media/rick/GLV80LHBOOT
2025-05-30 00:30:06,949 - glovebox.flash.usb - INFO - Copying /home/rick/projects/glovebox/tmp/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout/fw/glove80.uf2 to /run/media/rick/GLV80LHBOOT/glove80.uf2
2025-05-30 00:30:20,393 - glovebox.flash.usb - INFO - Firmware file copied successfully.
2025-05-30 00:30:21,750 - glovebox.flash.usb - INFO - Successfully flashed device sda (1/2)
2025-05-30 00:30:21,757 - glovebox.flash.lsdev - INFO - Device removed: /dev/sda
2025-05-30 00:30:24,750 - glovebox.flash.usb - INFO - --- Waiting for device 2/2 matching 'vendor=Adafruit and serial~=GLV80-.* and removable=true' ---
2025-05-30 00:30:24,750 - glovebox.flash.lsdev - INFO - NAME SIZE TYPE REMOVABLE MODEL VENDOR SERIAL
2025-05-30 00:30:24,750 - glovebox.flash.lsdev - INFO - ---------------------------------------------------------------------------------------------------------
2025-05-30 00:30:34,195 - glovebox.flash.lsdev - INFO - New device detected: /dev/sda
2025-05-30 00:30:34,195 - glovebox.flash.usb - INFO - Attempting to flash sda...
2025-05-30 00:30:34,195 - glovebox.flash.usb - INFO - Attempt 1/3: Mounting device /dev/sda (GLV80-735A88B1887FDE8B_GLV80RHBOOT)...
2025-05-30 00:30:34,973 - glovebox.flash.usb - INFO - Device GLV80-735A88B1887FDE8B_GLV80RHBOOT mounted at /run/media/rick/GLV80RHBOOT
2025-05-30 00:30:34,973 - glovebox.flash.usb - INFO - Copying /home/rick/projects/glovebox/tmp/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout/fw/glove80.uf2 to /run/media/rick/GLV80RHBOOT/glove80.uf2
2025-05-30 00:30:43,600 - glovebox.flash.usb - INFO - Firmware file copied successfully.
2025-05-30 00:30:45,354 - glovebox.flash.usb - INFO - Successfully flashed device sda (2/2)
2025-05-30 00:30:45,356 - glovebox.flash.lsdev - INFO - Device removed: /dev/sda
2025-05-30 00:30:48,354 - glovebox.flash.lsdev - INFO - USB device monitoring stopped
2025-05-30 00:30:48,355 - glovebox.flash.usb - INFO - Flash summary: 2 succeeded, 0 failed.
Build command and output for PR34 branch fails due to missing include files:
/build/glove80.keymap:23:10: fatal error: dt-bindings/zmk/pointing.h: No such file or directory
I don't known how MoErgo inject them.
Build command and output
% uv run python3 -m glovebox.cli --debug firmware build --output-dir fw/ --branch pull/34/head glove80.keymap glove80.conf
2025-05-30 00:09:43,207 - glovebox.build.docker - INFO - Starting Docker build with ID: 20250530-000943-28e1e837
2025-05-30 00:09:43,208 - glovebox.build.docker - DEBUG - Docker command: docker run --rm -v /home/rick/projects/glovebox/tmp/28e97485-dab5-4afb-afbc-5de5f1c52c45_Glorious Engrammer v42 preview with v41 QWERTY layout/fw/artifacts-20250530-000943-28e1e837:/build -e REPO=moergo-sc/zmk -e BRANCH=pull/34/head -e JOBS=24 -e KEYMAP=glove80.keymap -e KCONFIG=glove80.conf -e BUILD_DIR=/build moergo-zmk-build:latest
[2025-05-29 22:09:43] [INFO] ========== Build Environment ==========
[2025-05-29 22:09:43] [INFO] Build ID: ebe7528b-pull-34-head-598b0350-20250529220943
[2025-05-29 22:09:43] [INFO] Build directory: /build
[2025-05-29 22:09:43] [INFO] Builder directory: /app/builder
[2025-05-29 22:09:43] [INFO] Git repository path: /app/src
[2025-05-29 22:09:43] [INFO] Branch: pull/34/head
[2025-05-29 22:09:43] [INFO] Repository: moergo-sc/zmk
[2025-05-29 22:09:43] [INFO] Keymap: glove80.keymap
[2025-05-29 22:09:43] [INFO] Kconfig: glove80.conf
[2025-05-29 22:09:43] [INFO] Output name: glove80
[2025-05-29 22:09:43] [INFO] Number of jobs: 24
[2025-05-29 22:09:43] [INFO] Build log: /build/artifacts/ebe7528b-pull-34-head-598b0350-20250529220943/build-ebe7528b-pull-34-head-598b0350-20250529220943.log
[2025-05-29 22:09:43] [INFO] Artifacts directory: /build/artifacts/ebe7528b-pull-34-head-598b0350-20250529220943
[2025-05-29 22:09:43] [INFO] Temporary directory: /tmp
[2025-05-29 22:09:43] [INFO] Nix version: nix (Nix) 2.18.4
[2025-05-29 22:09:43] [INFO] ======================================
[2025-05-29 22:09:43] [INFO] /build/glove80.conf
[2025-05-29 22:09:43] [INFO] CONFIG_EXPERIMENTAL_RGB_LAYER=y
CONFIG_ZMK_POINTING=y
CONFIG_ZMK_BLE_DEVICE_NAME_APPEND_SN=y
[2025-05-29 22:09:43] [INFO] Verified keymap and kconfig files exist
::group::Repository Setup
[2025-05-29 22:09:43] [INFO] Starting phase: Repository Setup
[2025-05-29 22:09:43] [INFO] Checking out branch: pull/34/head
From https://github.com/moergo-sc/zmk
* branch refs/pull/34/head -> FETCH_HEAD
Previous HEAD position was 598b0350 Configure Glove80 board definitions for custom features
HEAD is now at 13603b56 chore(underglow): Add missing include header
[2025-05-29 22:09:45] [INFO] Git commit: 13603b56bb85d0d6194be349c0fd4f3ef9d0ff0f
[2025-05-29 22:09:45] [INFO] Phase completed in 2s
::endgroup::
::group::Build Preparation
[2025-05-29 22:09:45] [INFO] Starting phase: Build Preparation
[2025-05-29 22:09:45] [INFO] Build log: /build/artifacts/ebe7528b-pull-34-head-598b0350-20250529220943/build-ebe7528b-pull-34-head-598b0350-20250529220943.log
[2025-05-29 22:09:45] [INFO] Artifacts directory: /build/artifacts/ebe7528b-pull-34-head-598b0350-20250529220943
[2025-05-29 22:09:45] [INFO] Phase completed in 0s
::endgroup::
[2025-05-29 22:09:45] [INFO] Starting phase: Firmware Build
::group::Firmware Build
[2025-05-29 22:09:45] [INFO] Building firmware...
[2025-05-29 22:09:45] [INFO] Running nix-build with args: keymap=glove80.keymap, kconfig=glove80.conf, outputName=glove80, buildId=ebe7528b-pull-34-head-598b0350-20250529220943
...
Loading Zephyr default modules (Zephyr base (cached)).
-- Application: /tmp/nix-build-zmk_glove80_rh.drv-0/source/app
-- CMake version: 3.27.8
-- Found Python3: /nix/store/qrrwy165fvfdxcp6yn01yjbi7fsn3zmf-python3-3.11.6-env/bin/python (found suitable version "3.11.6", minimum required is "3.8") found components: Interpreter
-- Cache files will be written to: /tmp/nix-build-zmk_glove80_lh.drv-0/.cache
-- Zephyr version: 3.5.0 (/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr)
-- Found Python3: /nix/store/qrrwy165fvfdxcp6yn01yjbi7fsn3zmf-python3-3.11.6-env/bin/python (found suitable version "3.11.6", minimum required is "3.8") found components: Interpreter
-- Cache files will be written to: /tmp/nix-build-zmk_glove80_rh.drv-0/.cache
-- Zephyr version: 3.5.0 (/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr)
-- Using keymap file: /build/glove80.keymap
-- Board: glove80_lh
-- Using keymap file: /build/glove80.keymap
-- Board: glove80_rh
-- Found toolchain: gnuarmemb (/nix/store/mkvk7zrbvp1s74g92kjd4qx60nmclfn3-gcc-arm-embedded-12.3.rel1)
-- Found Dtc: /nix/store/vrigkjb8pzdc01ggppbfyh6mcnnv2lzw-dtc-1.7.0/bin/dtc (found suitable version "1.7.0", minimum required is "1.4.6")
-- Found BOARD.dts: /tmp/nix-build-zmk_glove80_lh.drv-0/source/app/boards/arm/glove80/glove80_lh.dts
-- Found devicetree overlay: /build/glove80.keymap
-- Found toolchain: gnuarmemb (/nix/store/mkvk7zrbvp1s74g92kjd4qx60nmclfn3-gcc-arm-embedded-12.3.rel1)
-- Found Dtc: /nix/store/vrigkjb8pzdc01ggppbfyh6mcnnv2lzw-dtc-1.7.0/bin/dtc (found suitable version "1.7.0", minimum required is "1.4.6")
-- Found BOARD.dts: /tmp/nix-build-zmk_glove80_rh.drv-0/source/app/boards/arm/glove80/glove80_rh.dts
-- Found devicetree overlay: /build/glove80.keymap
In file included from <command-line>:
/build/glove80.keymap:23:10: fatal error: dt-bindings/zmk/pointing.h: No such file or directory
23 | #include <dt-bindings/zmk/pointing.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
CMake Error at /nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr/cmake/modules/extensions.cmake:3885 (message):
failed to preprocess devicetree files (error code 1):
/tmp/nix-build-zmk_glove80_lh.drv-0/source/app/boards/arm/glove80/glove80_lh.dts;/build/glove80.keymap
Call Stack (most recent call first):
/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr/cmake/modules/dts.cmake:226 (zephyr_dt_preprocess)
/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr/cmake/modules/zephyr_default.cmake:129 (include)
/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
/nix/store/6p8b3xwjz1w7vijrcysij2f17fn73492-zephyr/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:97 (include_boilerplate)
CMakeLists.txt:8 (find_package)
-- Configuring incomplete, errors occurred!
note: keeping build directory '/tmp/nix-build-zmk_glove80_lh.drv-0'
error: builder for '/nix/store/jysh7l7xg3qk4gnsc8iwkhk7v8z9n5cw-zmk_glove80_lh.drv' failed with exit code 1
error: 1 dependencies of derivation '/nix/store/2gq6ssdg7z4mvxwcf9661mkzmlgbd9pv-collect_build_artifact_lh.drv' failed to build
note: keeping build directory '/tmp/nix-build-zmk_glove80_rh.drv-0'
error: 1 dependencies of derivation '/nix/store/p9yvxcis888wz70brhxjbfhwy3636pdb-glove80-firmware.drv' failed to build
{
"DEEP_SLEEP": {
"kconfig_name": "CONFIG_ZMK_SLEEP",
"type": "bool",
"default": false,
"description": "Enable deep sleep, but may affect BLE reconnection. For detail ZMK documentation see CONFIG_ZMK_SLEEP."
},
"DEEP_SLEEP_TIMEOUT_MS": {
"kconfig_name": "CONFIG_ZMK_IDLE_SLEEP_TIMEOUT",
"type": "int",
"default": 900000,
"description": "Milliseconds of inactivity before entering deep sleep."
},
"BATTERY_REPORT_INTERVAL_SEC": {
"kconfig_name": "CONFIG_ZMK_BATTERY_REPORT_INTERVAL",
"type": "int",
"default": 600,
"description": "Battery level report interval in seconds. For detail ZMK documentation see CONFIG_ZMK_BATTERY_REPORT_INTERVAL."
},
"COMBO_MAX_PRESSED_COMBOS": {
"kconfig_name": "CONFIG_ZMK_COMBO_MAX_PRESSED_COMBOS",
"type": "int",
"default": 4,
"description": "Maximum number of currently pressed combos. For detail ZMK documentation see CONFIG_ZMK_COMBO_MAX_PRESSED_COMBOS."
},
"COMBO_MAX_COMBOS_PER_KEY": {
"kconfig_name": "CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY",
"type": "int",
"default": 5,
"description": "Maximum number of active combos that use the same key position. For detail ZMK documentation see CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY."
},
"COMBO_MAX_KEYS_PER_COMBO": {
"kconfig_name": "CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO",
"type": "int",
"default": 4,
"description": "Maximum number of keys to press to activate a combo. For detail ZMK documentation see CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO."
},
"BEHAVIORS_QUEUE_SIZE": {
"kconfig_name": "CONFIG_ZMK_BEHAVIORS_QUEUE_SIZE",
"type": "int",
"default": 64,
"description": "Maximum number of behaviors to allow queueing from a macro or other complex behavior. For detail ZMK documentation see CONFIG_ZMK_BEHAVIORS_QUEUE_SIZE."
},
"KSCAN_DEBOUNCE_PRESS_MS": {
"kconfig_name": "CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS",
"type": "int",
"default": 5,
"description": "Keyscan press debounce in milliseconds. For detail ZMK documentation see CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS."
},
"KSCAN_DEBOUNCE_RELEASE_MS": {
"kconfig_name": "CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS",
"type": "int",
"default": 5,
"description": "Keyscan release debounce in milliseconds. For detail ZMK documentation see CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS."
},
"SETTINGS_SAVE_DEBOUNCE_MS": {
"kconfig_name": "CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE",
"type": "int",
"default": 60000,
"description": "Milliseconds to wait after a setting change before writing it to flash memory. For detail ZMK documentation see CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE."
},
"BLE_LL_SW_LLCP": {
"kconfig_name": "CONFIG_BT_LL_SW_LLCP",
"type": "bool",
"default": false,
"description": "Maps to KConfig variable CONFIG_BT_LL_SW_LLCP. Make sure you set BLE_LL_SW_LLCP_LEGACY to opposite value. Do not override this unless instructed by MoErgo. Only available in v23.11/v23.12/v24.01."
},
"BLE_LL_SW_LLCP_LEGACY": {
"kconfig_name": "CONFIG_BT_LL_SW_LLCP_LEGACY",
"type": "bool",
"default": false,
"description": "Maps to KConfig variable CONFIG_BT_LL_SW_LLCP_LEGACY. Make sure you set BLE_LL_SW_LLCP to opposite value. Do not override this unless instructed by MoErgo. Only available in v23.11/v23.12/v24.01."
},
"BLE_GATT_AUTO_SEC_REQ": {
"kconfig_name": "CONFIG_BT_GATT_AUTO_SEC_REQ",
"type": "bool",
"default": false,
"description": "Maps to KConfig variable CONFIG_BT_GATT_AUTO_SEC_REQ. Do not override unless instructed by MoErgo. Default is 'y' only for split peripheral side."
},
"BLE_AUTO_PHY_UPDATE": {
"kconfig_name": "CONFIG_BT_AUTO_PHY_UPDATE",
"type": "bool",
"default": true,
"description": "Maps to KConfig variable CONFIG_BT_AUTO_PHY_UPDATE. Do not override unless instructed by MoErgo."
},
"BLE_CTLR_PHY_2M": {
"kconfig_name": "CONFIG_BT_CTLR_PHY_2M",
"type": "bool",
"default": true,
"description": "Maps to CONFIG_BT_CTLR_PHY_2M. Do not override this unless instructed by MoErgo."
},
"HID_POINTING": {
"kconfig_name": "CONFIG_ZMK_POINTING",
"type": "bool",
"default": false,
"description": "Enables mouse emulation capability. Re-pair your keyboard with your host via Bluetooth after enabling this feature."
},
"BLE_PASSKEY_ENTRY": {
"kconfig_name": "CONFIG_ZMK_BLE_PASSKEY_ENTRY",
"type": "bool",
"default": false,
"description": "Require typing passkey from host to pair BLE connection."
},
"BLE_DEVICE_NAME_APPEND_SN": {
"kconfig_name": "CONFIG_BT_DEVICE_NAME_APPEND_SN",
"type": "bool",
"default": false,
"description": "When enabled, the advertised BLE device name is appended by the first 6 hexadecimal digits of the serial number."
},
"SPLIT_BLE_PREF_LATENCY": {
"kconfig_name": "CONFIG_ZMK_SPLIT_BLE_PREF_LATENCY",
"type": "int",
"default": 30,
"description": "Latency to use for split central/peripheral connection."
},
"BLE_SMP_ALLOW_UNAUTH_OVERWRITE": {
"kconfig_name": "CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE",
"type": "bool",
"default": false,
"description": "Allows overwrite of keys from previously paired hosts. This is useful for connecting with dual-boot hosts."
},
"BLE_SMP_MIN_ENC_KEY_SIZE": {
"kconfig_name": "CONFIG_BT_SMP_MIN_ENC_KEY_SIZE",
"type": "int",
"default": 7,
"description": "Minimum encryption key size accepted in octets. Must be between 7 and 16."
},
"BLE_BAS": {
"kconfig_name": "CONFIG_BT_BAS",
"type": "bool",
"default": true,
"description": "Enable the Bluetooth BAS (battery reporting service)."
},
"HID_NKRO": {
"kconfig_name": "CONFIG_ZMK_HID_REPORT_TYPE_NKRO",
"type": "bool",
"default": true,
"description": "Enable full N-key roll over"
},
"HID_FULL_CONSUMER_REPORT": {
"kconfig_name": "CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_FULL",
"type": "bool",
"default": true,
"description": "Enable all consumer key codes, but may have compatibility issues with some host OSes."
},
"HID_SEPARATE_MOD_RELEASE_REPORT": {
"kconfig_name": "CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT",
"type": "bool",
"default": false,
"description": "Send modifier release event after non-modifier release event. This is available only for PR31, and not yet in production firmware."
},
"USB_LOGGING": {
"kconfig_name": "CONFIG_ZMK_USB_LOGGING",
"type": "bool",
"default": false,
"description": "For debugging only; do not set this unless instructed by MoErgo. USB Logging is known to cause change in timing-sensitive behavior."
},
"INPUT_LOG_LEVEL_DBG": {
"kconfig_name": "CONFIG_INPUT_LOG_LEVEL_DBG",
"type": "bool",
"default": false,
"description": "For debugging only; do not set this unless instructed by MoErgo. DEBUG log level is known to cause change in timing-sensitive behavior"
},
"SYSTEM_WORKQUEUE_STACK_SIZE": {
"kconfig_name": "CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE",
"type": "int",
"default": 2048,
"description": "For debugging only; do not set this unless instructed by MoErgo."
},
"HW_STACK_PROTECTION": {
"kconfig_name": "CONFIG_HW_STACK_PROTECTION",
"type": "bool",
"default": false,
"description": "For debugging only; do not set this unless instructed by MoErgo."
},
"EXPERIMENTAL_RGB_UNDERGLOW_AUTO_OFF_IDLE": {
"kconfig_name": "CONFIG_EXPERIMENTAL_RGB_UNDERGLOW_AUTO_OFF_IDLE",
"type": "bool",
"default": false,
"description": "To save battery, turn off the RGB when the keyboard is not used for 30s."
},
"EXPERIMENTAL_RGB_LAYER": {
"kconfig_name": "CONFIG_EXPERIMENTAL_RGB_LAYER",
"type": "bool",
"default": false,
"description": "For PR36 community firmware only. Enables per-layer RGB."
}
}