From 77c974fa06b9ec84edd6a48e7d562c6fa2d63b3e Mon Sep 17 00:00:00 2001 From: Felix Graupner Date: Mon, 3 Aug 2026 12:56:18 +0200 Subject: [PATCH 1/2] Stop leaking a preference file per test run Each UUID-named test suite left an empty ~/Library/Preferences/.plist behind, because removePersistentDomain(forName:) empties a domain but cfprefsd keeps the file. Over the project's history this accumulated 379 stray files in the developer's Preferences directory. Route the eight cleanup sites through a helper that also drops the suite and unlinks the plist. Co-Authored-By: Claude Opus 5 --- Tests/AgentMicroTests.swift | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Tests/AgentMicroTests.swift b/Tests/AgentMicroTests.swift index 539a8ca..d132160 100644 --- a/Tests/AgentMicroTests.swift +++ b/Tests/AgentMicroTests.swift @@ -3,6 +3,21 @@ import Carbon.HIToolbox import XCTest @testable import AgentMicro +/// Removes a temporary `UserDefaults` suite completely. +/// +/// `removePersistentDomain(forName:)` only empties the domain; `cfprefsd` still +/// leaves an empty `~/Library/Preferences/.plist` behind. Every test run +/// creates a fresh UUID-named suite, so without this the developer's Preferences +/// directory accumulates one stray file per suite per run, forever. +func removeDefaultsSuite(_ suiteName: String, defaults: UserDefaults) { + defaults.removePersistentDomain(forName: suiteName) + defaults.removeSuite(named: suiteName) + let plist = FileManager.default + .homeDirectoryForCurrentUser + .appendingPathComponent("Library/Preferences/\(suiteName).plist") + try? FileManager.default.removeItem(at: plist) +} + final class AgentMicroTests: XCTestCase { func testPrivacySettingsDeepLinksTargetTheExpectedTCCPanes() { XCTAssertEqual( @@ -103,7 +118,7 @@ final class AgentMicroTests: XCTestCase { func testAgentMicroMigratesLegacyPreferencesAndApplicationSupport() throws { let suiteName = "AgentMicroTests.migration.\(UUID().uuidString)" let defaults = try XCTUnwrap(UserDefaults(suiteName: suiteName)) - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } defaults.set("de", forKey: "CodexPad.appLanguage") let root = FileManager.default.temporaryDirectory @@ -2083,7 +2098,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryPersistsOfferedTriggersAcrossProfiles() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } let codex = ProfileFactory.codex(catalog: CodexActionCatalog()) let claude = ProfileFactory.claude(catalog: CodexActionCatalog(resourceName: "ClaudeActions", app: .claude)) @@ -2101,7 +2116,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryAdvancesPastEveryPreviouslyOfferedCandidate() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } let profiles = [ProfileFactory.codex(catalog: CodexActionCatalog())] CodexTriggerRegistry.reserve("cmd-ctrl-opt-shift-a", defaults: defaults) @@ -2120,7 +2135,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryRemembersAnActionAcrossPadControls() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } CodexTriggerRegistry.remember( "cmd-ctrl-opt-shift-f7", @@ -2140,7 +2155,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryConfirmsOnlyAfterSuccessfulSetup() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } CodexTriggerRegistry.remember( "cmd-ctrl-opt-shift-f8", @@ -2165,7 +2180,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryRestoresConfirmedActionAfterRestart() throws { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } let definition = try XCTUnwrap(CodexActionCatalog().action(id: "toggle-pet")) CodexTriggerRegistry.markConfirmed( @@ -2184,7 +2199,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistryImportsExistingBindingsFromInactiveLayers() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } var profile = ProfileFactory.codex(catalog: CodexActionCatalog()) var inactiveLayer = profile.layers[0] @@ -2208,7 +2223,7 @@ final class AgentMicroTests: XCTestCase { func testTriggerRegistrySkipsTriggersUsedInAnotherProfile() { let suiteName = "CodexPadTests.triggerRegistry.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suiteName)! - defer { defaults.removePersistentDomain(forName: suiteName) } + defer { removeDefaultsSuite(suiteName, defaults: defaults) } let codex = ProfileFactory.codex(catalog: CodexActionCatalog()) var claude = ProfileFactory.claude(catalog: CodexActionCatalog(resourceName: "ClaudeActions", app: .claude)) From a7e0faaa4e027f86a91f50ed613b16889322495f Mon Sep 17 00:00:00 2001 From: Felix Graupner Date: Mon, 3 Aug 2026 12:56:18 +0200 Subject: [PATCH 2/2] State plainly that other boards are unsupported The section warned that lookalike pads "can" differ, which reads as a caution about a low-probability case. The real position is stronger: differing control counts cannot work at all, since the control count, pin map, and LED chain are compile-time constants; and matching layouts are not expected to be wired identically either. Also name porting as the actual path for other hardware, so readers do not look for a configuration option that does not exist. Co-Authored-By: Claude Opus 5 --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index ef0294a..677788a 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,26 @@ Visually identical pads can contain different controllers or pinouts. Never flash a device based on appearance alone. Check the factory VID/PID and follow the firmware repository's preflight procedure. +### Other boards are not supported + +Support means one board. Treat every other device as incompatible until someone +proves otherwise on that specific hardware. + +**Guaranteed not to work.** Any pad with a different number of controls — more +or fewer keys, no encoder, a second encoder — cannot run this firmware. The +control count, the pin map, and the six-LED chain are compile-time constants, so +a mismatch is not a degraded experience, it is a non-functional device. + +**Not expected to work.** A pad with the same six-key, one-encoder layout may +still differ in controller, pin assignment, LED order, or SW2 wiring. If such a +board happens to be wired identically, that is luck, not compatibility. Nothing +about the enclosure, product name, or listing predicts what is on the PCB. + +Other hardware would need the firmware **ported** to it: the pin and LED maps in +the firmware repository's `HARDWARE_NOTES.md` describe what has to be +re-measured and changed. That is development work, not a configuration step, and +this project cannot verify the result for you. + | USB identity | Support | | --- | --- | | `1189:8890` | Verified factory CH57x configuration path |