Ariver
2026-06-30 bcceca83ce966598e00e0319d85ec11d6df9d272
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#!/usr/bin/env bash
set -euo pipefail
 
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
 
python3 - "$ROOT_DIR" <<'PY'
import json
import re
import sys
from pathlib import Path
 
root = Path(sys.argv[1])
app_dir = root / "Apptag"
localization_dir = app_dir / "Localization"
 
EXPECTED_LANGUAGE_COUNT = 29
REQUIRED_HOTKEY_KEYS = [
    "hotkeys.customize",
    "hotkeys.restoreDefault",
    "hotkeys.recording",
    "hotkeys.recordingInline",
    "hotkeys.recordingCancelled",
    "hotkeys.saved",
    "hotkeys.restored",
    "hotkeys.proRequired",
    "hotkeys.error.modifierRequired",
    "hotkeys.error.unsupportedKey",
    "hotkeys.error.reserved",
    "hotkeys.error.duplicate",
    "hotkeys.error.registrationFailed",
    "pro.feature.customHotkeys",
    "pro.feature.customHotkeys.benefit",
    "pro.prompt.customHotkeys",
]
 
 
def fail(message: str) -> None:
    raise SystemExit(f"FAIL: {message}")
 
 
def read(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except Exception as error:
        fail(f"could not read {path}: {error}")
 
 
def require(source: str, needle: str, message: str) -> None:
    if needle not in source:
        fail(message)
 
 
def function_body(source: str, signature: str) -> str:
    start = source.find(signature)
    if start == -1:
        fail(f"missing function signature: {signature}")
    brace = source.find("{", start)
    if brace == -1:
        fail(f"missing function body for: {signature}")
    depth = 0
    for index in range(brace, len(source)):
        char = source[index]
        if char == "{":
            depth += 1
        elif char == "}":
            depth -= 1
            if depth == 0:
                return source[brace + 1:index]
    fail(f"unterminated function body for: {signature}")
 
 
def load_json(path: Path) -> dict[str, str]:
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
    except Exception as error:
        fail(f"{path.name} is not valid JSON: {error}")
    if not isinstance(data, dict):
        fail(f"{path.name} must contain a JSON object")
    return data
 
 
settings = read(app_dir / "LauncherHotkeySettings.swift")
app = read(app_dir / "ApptagApp.swift")
preferences = read(app_dir / "PreferencesView.swift")
pro = read(app_dir / "ProEntitlement.swift")
access_views = read(app_dir / "ProAccessViews.swift")
defaults = read(app_dir / "AppDefaults.swift")
quick_search = read(app_dir / "QuickSearch.swift")
 
require(settings, 'private static let namespace = "customHotkeys.v1"', "custom hotkeys must use the new v1 namespace")
require(settings, "defaultHotkey(for kind: LauncherHotkeyKind) -> LauncherHotkey", "default hotkey helper is missing")
require(settings, "kind.hotkey", "default hotkey must remain the fixed built-in shortcut")
require(settings, "ProEntitlementPolicy.isUnlocked(.customHotkeys)", "effective hotkey must be gated by Pro entitlement")
require(settings, "structuralValidationError(for: saved) == nil", "stored hotkeys must pass structural validation before use")
require(settings, "!duplicatesOtherEffectiveHotkey(saved, kind: kind)", "effective hotkey must reject duplicated saved shortcuts")
require(settings, "effectiveHotkeyIgnoringDuplicateCheck(for:", "duplicate validation must avoid recursive effectiveHotkey calls")
require(settings, "kEventKeyModifierFnMask", "Fn modifier support is required for the default Quick Search hotkey")
require(settings, "modifiers == UInt32(kEventKeyModifierFnMask)", "Fn-only must be restricted explicitly")
require(settings, "hotkey.keyCode == UInt32(kVK_Space)", "Fn-only must only be valid for Space")
require(settings, "isReservedBySystem", "system-reserved shortcuts must be rejected")
require(settings, "modifiers == UInt32(shiftKey)", "Shift-only must remain rejected")
if "modifiers == UInt32(shiftKey) || modifiers == UInt32(optionKey)" in settings:
    fail("Option-only shortcuts such as Option+Space must be allowed")
require(settings, "private static let functionKeyCodes: Set<Int>", "function keys must use an explicit Carbon key-code set")
require(settings, "functionKeyCodes.contains(key)", "supported-key validation must check the explicit function key set")
if "kVK_F1...kVK_F12" in settings:
    fail("Carbon function key codes are not contiguous; kVK_F1...kVK_F12 crashes at runtime")
 
effective_body = function_body(settings, "static func effectiveHotkey(for kind: LauncherHotkeyKind) -> LauncherHotkey")
if "validationError(for:" in effective_body:
    fail("effectiveHotkey must not call validationError because duplicate checks can recurse")
 
validation_body = function_body(settings, "static func validationError(for hotkey: LauncherHotkey, kind: LauncherHotkeyKind) -> LauncherHotkeyValidationError?")
require(validation_body, "structuralValidationError(for:", "public validation must run structural checks")
require(validation_body, "duplicatesOtherEffectiveHotkey", "public validation must reject duplicates")
 
apply_body = function_body(app, "func applyCustomHotkey(_ hotkey: LauncherHotkey, for kind: LauncherHotkeyKind) -> LauncherHotkeyCustomizationResult")
require(apply_body, "guard ProEntitlementPolicy.isUnlocked(.customHotkeys) else", "AppDelegate save path must be Pro-gated")
require(apply_body, "LauncherHotkeySettings.validationError(for: hotkey, kind: kind)", "AppDelegate save path must validate the candidate")
require(apply_body, "activateHotkey(hotkey, for: kind, persistCustom: true)", "custom save must go through transactional activation")
 
restore_body = function_body(app, "func restoreDefaultHotkey(for kind: LauncherHotkeyKind) -> LauncherHotkeyCustomizationResult")
require(restore_body, "guard ProEntitlementPolicy.isUnlocked(.customHotkeys) else", "restore default path must be Pro-gated")
require(restore_body, "persistCustom: false", "restore default must clear custom storage after successful registration")
 
activate_body = function_body(app, "private func activateHotkey(")
try_register_index = activate_body.find("tryRegisterHotkey(hotkey")
success_index = activate_body.find("case .success(let newRef):")
if try_register_index == -1 or success_index == -1:
    fail("transactional registration body is incomplete")
success_body = activate_body[success_index:]
unregister_index = success_body.find("UnregisterEventHotKey(oldRef)")
save_index = success_body.find("LauncherHotkeySettings.save")
if unregister_index == -1 or save_index == -1:
    fail("transactional success branch is incomplete")
if not (try_register_index < success_index and unregister_index < save_index):
    fail("custom hotkey must register first, then unregister old ref, then persist")
require(activate_body, "return .registrationFailed(status)", "registration failure must not save the candidate")
 
require(app, "observeProEntitlementChanges()", "AppDelegate must observe Pro entitlement changes")
require(app, "static private(set) weak var shared: AppDelegate?", "Preferences must have a stable AppDelegate bridge for custom hotkey writes")
require(app, "Self.shared = self", "AppDelegate must publish its stable shared bridge during initialization")
require(app, "private var configuredHotkeysSuspendedForRecording = false", "AppDelegate must track hotkey recording suspension")
require(app, "registerConfiguredHotkeys()", "Pro entitlement changes must re-register effective hotkeys")
require(app, "LauncherHotkeySettings.effectiveHotkey(for: .main).displayString", "menu title must display the effective App Grid shortcut")
require(app, "LauncherHotkeySettings.effectiveHotkey(for: kind)", "hotkey registration must read effective shortcuts")
require(app, "RegisterEventHotKey", "Carbon RegisterEventHotKey must remain the global hotkey backend")
require(app, "UnregisterEventHotKey(oldRef)", "old hotkey ref must be released after successful replacement")
 
register_configured_body = function_body(app, "private func registerConfiguredHotkeys()")
require(register_configured_body, "guard !configuredHotkeysSuspendedForRecording else { return }", "configured hotkeys must stay unregistered while recording")
 
suspend_body = function_body(app, "func suspendConfiguredHotkeysForRecording()")
require(suspend_body, "guard !configuredHotkeysSuspendedForRecording else { return }", "recording suspension must be idempotent")
require(suspend_body, "configuredHotkeysSuspendedForRecording = true", "recording suspension must set the guard flag")
require(suspend_body, "unregisterHotkey(for: .main)", "recording must suspend the App Grid global hotkey")
require(suspend_body, "unregisterHotkey(for: .quickSearch)", "recording must suspend the Quick Search global hotkey")
if "LauncherHotkeySettings.save" in suspend_body or "clearCustomHotkey" in suspend_body:
    fail("recording suspension must not write custom hotkey storage")
 
resume_body = function_body(app, "func resumeConfiguredHotkeysAfterRecording()")
require(resume_body, "guard configuredHotkeysSuspendedForRecording else { return }", "recording resume must be idempotent")
require(resume_body, "configuredHotkeysSuspendedForRecording = false", "recording resume must clear the guard flag")
require(resume_body, "registerConfiguredHotkeys()", "recording resume must restore effective hotkeys")
 
for forbidden in ["CGEventTapCreate", "AXIsProcessTrusted", "IOHIDManagerCreate", "addGlobalMonitorForEvents(matching: .keyDown"]:
    if forbidden in app + preferences + settings + quick_search:
        fail(f"forbidden API used for custom hotkeys: {forbidden}")
 
require(preferences, "presentSettingsProPrompt(for: .customHotkeys)", "free users must see the Pro prompt instead of recording")
require(preferences, "NSEvent.addLocalMonitorForEvents(matching: .keyDown)", "recording must use local key-down capture in Settings")
require(preferences, "Int(event.keyCode) == kVK_Escape", "Esc must cancel recording")
require(preferences, "LauncherHotkeySettings.candidate(from: event)", "recording must normalize NSEvent into LauncherHotkey")
require(preferences, "AppDelegate.shared?", "recording must use the stable AppDelegate bridge instead of NSApp.delegate casting")
require(preferences, "appDelegate.suspendConfiguredHotkeysForRecording()", "recording must suspend existing global hotkeys before capture")
require(preferences, "AppDelegate.shared?.resumeConfiguredHotkeysAfterRecording()", "recording cleanup must restore effective global hotkeys")
require(preferences, ".applyCustomHotkey(candidate, for: kind)", "recording must call the AppDelegate transactional save path")
require(preferences, "CustomizableHotkeyInfoRow", "Settings hotkey rows must expose custom controls")
require(preferences, "StaticHotkeyInfoRow(", "internal App Grid Space shortcut must remain static")
require(preferences, "LauncherHotkeySettings.effectiveHotkey(for: .main).displayString", "Settings must display effective App Grid shortcut")
require(preferences, "LauncherHotkeySettings.effectiveHotkey(for: .quickSearch).displayString", "Settings must display effective Quick Search shortcut")
require(preferences, "HotkeyPrimaryActionButton", "custom hotkey rows must use the shared action button")
require(preferences, 'customizeTitle: tr("hotkeys.customize")', "locked custom hotkey actions must still show the action label")
require(preferences, 'proBadgeTitle: tr("pro.card.badge")', "locked custom hotkey actions must compose the global Pro badge beside the action label")
require(preferences, "ProStatusPill(text: proBadgeTitle, style: .locked, compact: true)", "locked custom hotkey action must use the global Pro pill")
require(preferences, "if canRestore {", "restore-default action must only appear when a custom shortcut exists")
 
start_recording_body = function_body(preferences, "private func startHotkeyRecording(for kind: LauncherHotkeyKind)")
suspend_index = start_recording_body.find("appDelegate.suspendConfiguredHotkeysForRecording()")
monitor_index = start_recording_body.find("NSEvent.addLocalMonitorForEvents(matching: .keyDown)")
if suspend_index == -1 or monitor_index == -1 or not suspend_index < monitor_index:
    fail("recording must suspend global hotkeys before installing the local monitor")
 
stop_recording_body = function_body(preferences, "private func stopHotkeyRecording(showCancelledToast: Bool = false)")
require(stop_recording_body, "let wasRecording", "recording cleanup must only resume when a recording was active")
require(stop_recording_body, "NSEvent.removeMonitor(hotkeyRecorderMonitor)", "recording cleanup must remove the local monitor")
require(stop_recording_body, "recordingHotkeyKind = nil", "recording cleanup must clear recording state")
require(stop_recording_body, "AppDelegate.shared?.resumeConfiguredHotkeysAfterRecording()", "recording cleanup must restore global hotkeys")
 
capture_recording_body = function_body(preferences, "private func captureHotkeyEvent(_ event: NSEvent)")
stop_index = capture_recording_body.find("stopHotkeyRecording(showCancelledToast: false)")
handle_index = capture_recording_body.find("handleHotkeyCustomizationResult(result)")
if stop_index == -1 or handle_index == -1 or not stop_index < handle_index:
    fail("recording capture must restore global hotkeys before showing save/failure feedback")
 
require(preferences, "if newTab != .hotkeys", "leaving the Hotkeys tab must end recording")
require(preferences, "stopHotkeyRecording(showCancelledToast: false)", "recording must clean up on tab change, Pro changes, and view disappearance")
 
custom_row_start = preferences.find("private struct CustomizableHotkeyInfoRow")
custom_row_end = preferences.find("private struct HotkeyStatusPill")
if custom_row_start == -1 or custom_row_end == -1 or custom_row_end <= custom_row_start:
    fail("could not inspect CustomizableHotkeyInfoRow layout")
custom_row = preferences[custom_row_start:custom_row_end]
if ".buttonStyle(.borderedProminent)" in custom_row:
    fail("custom hotkey rows must not use the default blue borderedProminent Pro button")
 
hotkey_button_start = preferences.find("private struct HotkeyPrimaryActionButton")
hotkey_button_end = preferences.find("private struct HotkeySecondaryActionButton")
if hotkey_button_start == -1 or hotkey_button_end == -1 or hotkey_button_end <= hotkey_button_start:
    fail("could not inspect HotkeyPrimaryActionButton layout")
hotkey_button = preferences[hotkey_button_start:hotkey_button_end]
require(hotkey_button, ".buttonStyle(.bordered)", "locked custom hotkey action must visually match Data tab Pro-gated buttons")
 
require(pro, "case customHotkeys", "ProFeature.customHotkeys is missing")
require(pro, "case .premiumThemes, .layoutImport, .layoutExport, .customTagColors, .unlimitedNotes, .persistentAppSorting, .customHotkeys:", "customHotkeys must be unlocked only by the Pro access state")
require(pro, "NotificationCenter.default.post(name: .tagLauncherProEntitlementChanged", "entitlement changes must notify hotkey registration")
require(access_views, "case .customHotkeys:", "Pro prompt routing must include custom hotkeys")
 
cleanup_body = function_body(defaults, "private static func removeShortcutCustomizationDefaults()")
if "customHotkeys.v1" in cleanup_body:
    fail("legacy cleanup must not delete new custom hotkey storage")
 
language_files = sorted(localization_dir.glob("*.json"))
if len(language_files) != EXPECTED_LANGUAGE_COUNT:
    fail(f"expected {EXPECTED_LANGUAGE_COUNT} localization files, found {len(language_files)}")
 
for path in language_files:
    data = load_json(path)
    missing = [
        key for key in REQUIRED_HOTKEY_KEYS
        if not isinstance(data.get(key), str) or not data[key].strip()
    ]
    if missing:
        fail(f"{path.name} missing custom hotkey translations: {', '.join(missing)}")
    if "%status%" not in data["hotkeys.error.registrationFailed"]:
        fail(f"{path.name} hotkeys.error.registrationFailed must keep %status% placeholder")
 
print("PASS Pro custom hotkeys static QA: Pro gating, recording suspension, transactional save path, duplicate-safe effective shortcuts, local recording, Pro-consistent row UI, and 29-language copy are wired")
PY
 
swift - <<'SWIFT'
import Carbon
import Darwin
 
func fail(_ message: String) -> Never {
    fputs("FAIL: \(message)\n", stderr)
    exit(1)
}
 
@discardableResult
func register(
    label: String,
    keyCode: Int,
    modifiers: UInt32,
    id: UInt32,
    expectSuccess: Bool
) -> EventHotKeyRef? {
    let hotkeyID = EventHotKeyID(signature: OSType(0x54474C51), id: id) // 'TGLQ'
    var ref: EventHotKeyRef?
    let status = RegisterEventHotKey(
        UInt32(keyCode),
        modifiers,
        hotkeyID,
        GetApplicationEventTarget(),
        0,
        &ref
    )
    if expectSuccess {
        guard status == noErr, let ref else {
            fail("\(label) should register successfully, got status \(status)")
        }
        return ref
    }
    if status == noErr {
        if let ref { UnregisterEventHotKey(ref) }
        fail("\(label) should not register successfully")
    }
    return nil
}
 
let modifiers = UInt32(controlKey | optionKey | shiftKey)
let mainRef = register(
    label: "main representative shortcut",
    keyCode: kVK_ANSI_9,
    modifiers: modifiers,
    id: 1,
    expectSuccess: true
)
let quickSearchRef = register(
    label: "quick search representative shortcut",
    keyCode: kVK_ANSI_8,
    modifiers: modifiers,
    id: 2,
    expectSuccess: true
)
let replacementRef = register(
    label: "same-id replacement shortcut",
    keyCode: kVK_ANSI_7,
    modifiers: modifiers,
    id: 1,
    expectSuccess: true
)
let optionSpaceRef = register(
    label: "Option-Space shortcut",
    keyCode: kVK_Space,
    modifiers: UInt32(optionKey),
    id: 4,
    expectSuccess: true
)
_ = register(
    label: "duplicate shortcut conflict",
    keyCode: kVK_ANSI_7,
    modifiers: modifiers,
    id: 3,
    expectSuccess: false
)
 
if let optionSpaceRef { UnregisterEventHotKey(optionSpaceRef) }
if let replacementRef { UnregisterEventHotKey(replacementRef) }
if let quickSearchRef { UnregisterEventHotKey(quickSearchRef) }
if let mainRef { UnregisterEventHotKey(mainRef) }
 
print("PASS Pro custom hotkeys runtime QA: Carbon accepts representative custom registrations, Option-Space, same-id replacement, and rejects duplicate active shortcuts")
SWIFT