feat: human-readable action logs for GUI harnesses#62
Merged
Conversation
Replace the raw osascript payload dump ("key down control / key code 46")
with one status line per routed action showing the physical control name
per pad family and the action it triggers, e.g.:
● triangle → push-to-talk
● right stick flick right → thinking depth up
● R3 → send ctrl+shift+m
- src/labels.ts: controlLabel (PlayStation vs ABXY face names) and
actionLabel (decodes keys bindings: arrows, ctrl chars, CSI-u chords)
- LayerRouter.lastControl exposes the matched ControlId so stick
gestures are nameable at the cli
- cli tracks the connected pad type and announces each dispatched action
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A chord whose 'key up' never lands (failed/timed-out osascript, process exit mid-dictation-hold, two chords interleaving) left Control/Shift/D stuck for the whole machine — clicks became right-clicks and typing broke until reboot. - serialize osascript runs through a queue with a 5s timeout so chords can never interleave - on a failed key-down chord, synchronously release every key the harness can hold (control/option/shift/command/"d") - Harness.dispose(): GUI shutdown (Ctrl+C/SIGTERM) now releases all held keys instead of a no-op Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Follow-up commit 392f82e: fixes the system-wide stuck-modifier hazard (Ctrl stuck → left click acts as right click, keyboard unusable until reboot). Root cause was not the logging change — synthetic
Fix: osascript runs are serialized through a queue with a 5s timeout; any failed key-down chord triggers a synchronous release of every key the harness can hold; and |
- logs show ✕ ○ □ △ instead of cross/circle/square/triangle - push_to_talk is now hold-to-talk in GUI mode: the cli forwards both button edges (action.pressed), the harness maps down→hold chord, up→release chord — replacing the press-to-start/press-to-stop toggle and its desync-prone module state Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Running
openmicro codex-app, every button press logged the raw osascript payload ("key down control / key code 46") — gibberish to an end user. Logs now show the physical button pressed (named per pad family) and the action it executes:Changes
controlLabelmaps logical controls to physical names per controller family (cross/circle/square/triangle for DualSense/DS4, A/B/X/Y for Xbox/GameSir/generic) andactionLabeldescribes actions, decodingkeysbindings (arrows, ctrl chars, CSI-u chords) into readable key names.LayerRouter.lastControlexposes the ControlId matched by the last successfulroute(), so stick-gesture actions are nameable at the cli.guiStatus, and drop the raw payload dump.Testing
test/labels.test.ts(6 tests) covering per-family face names, stick gestures, and keys decoding.🤖 Generated with Claude Code