()
| 131 | * User customization is currently gated to Anthropic employees. |
| 132 | */ |
| 133 | export async function loadKeybindings(): Promise<KeybindingsLoadResult> { |
| 134 | const defaultBindings = getDefaultParsedBindings() |
| 135 | |
| 136 | // Skip user config loading for external users |
| 137 | if (!isKeybindingCustomizationEnabled()) { |
| 138 | return { bindings: defaultBindings, warnings: [] } |
| 139 | } |
| 140 | |
| 141 | const userPath = getKeybindingsPath() |
| 142 | |
| 143 | try { |
| 144 | const content = await readFile(userPath, 'utf-8') |
| 145 | const parsed: unknown = jsonParse(content) |
| 146 | |
| 147 | // Extract bindings array from object wrapper format: { "bindings": [...] } |
| 148 | let userBlocks: unknown |
| 149 | if (typeof parsed === 'object' && parsed !== null && 'bindings' in parsed) { |
| 150 | userBlocks = (parsed as { bindings: unknown }).bindings |
| 151 | } else { |
| 152 | // Invalid format - missing bindings property |
| 153 | const errorMessage = 'keybindings.json must have a "bindings" array' |
| 154 | const suggestion = 'Use format: { "bindings": [ ... ] }' |
| 155 | logForDebugging(`[keybindings] Invalid keybindings.json: ${errorMessage}`) |
| 156 | return { |
| 157 | bindings: defaultBindings, |
| 158 | warnings: [ |
| 159 | { |
| 160 | type: 'parse_error', |
| 161 | severity: 'error', |
| 162 | message: errorMessage, |
| 163 | suggestion, |
| 164 | }, |
| 165 | ], |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | // Validate structure - bindings must be an array of valid keybinding blocks |
| 170 | if (!isKeybindingBlockArray(userBlocks)) { |
| 171 | const errorMessage = !Array.isArray(userBlocks) |
| 172 | ? '"bindings" must be an array' |
| 173 | : 'keybindings.json contains invalid block structure' |
| 174 | const suggestion = !Array.isArray(userBlocks) |
| 175 | ? 'Set "bindings" to an array of keybinding blocks' |
| 176 | : 'Each block must have "context" (string) and "bindings" (object)' |
| 177 | logForDebugging(`[keybindings] Invalid keybindings.json: ${errorMessage}`) |
| 178 | return { |
| 179 | bindings: defaultBindings, |
| 180 | warnings: [ |
| 181 | { |
| 182 | type: 'parse_error', |
| 183 | severity: 'error', |
| 184 | message: errorMessage, |
| 185 | suggestion, |
| 186 | }, |
| 187 | ], |
| 188 | } |
| 189 | } |
| 190 |
no test coverage detected