feat(drive): Add the jpdrive accessibility driver - #1009
Merged
Conversation
JeanMertz
force-pushed
the
pr/jpdrive
branch
2 times, most recently
from
August 21, 2026 05:33
d3b5881 to
36ead6f
Compare
Debugging the macOS app from a conversation needs a way to read what is actually on screen and act on it. Screenshots answer "what does it look like" but not "what is the button called, is it enabled, does the menu item exist" — and none of that is reachable from the app's own test bundle, which runs inside the process and cannot see menu enablement, the pasteboard, or a relaunch. `jpdrive` reads and drives another application through its accessibility tree, and writes one JSON document to stdout either way: a result, or an error with a non-zero exit status. It is what the `debug_app_*` tools shell out to. A standalone SwiftPM package rather than a target in the app's Xcode project, so the binary lands at a predictable path and nothing has to search derived data for it. The logic lives in a `DriveKit` library with a one-line executable on top, because SwiftPM cannot cleanly test an executable target and the tree traversal is where the bugs are. The tests run against a fake accessibility tree, so they need no running app and no accessibility grant. The package mirrors the app's strictness: Swift 6 language mode, `ExistentialAny`, and warnings as errors. SwiftPM 6.0 has no first-class setting for the last of those, so it goes through `unsafeFlags`, which is rejected only for a package consumed as a dependency — this one never is. Accessibility is gated by TCC, and a grant given to a terminal does not obviously reach a tool that terminal started. `just drive-doctor` reports whether the calling process may read another app's tree, so that question is answered by running it under each host rather than guessed at. Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.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.
Debugging the macOS app from a conversation needs a way to read what is
actually on screen and act on it. Screenshots answer "what does it look
like" but not "what is the button called, is it enabled, does the menu
item exist" — and none of that is reachable from the app's own test
bundle, which runs inside the process and cannot see menu enablement,
the pasteboard, or a relaunch.
jpdrivereads and drives another application through its accessibilitytree, and writes one JSON document to stdout either way: a result, or an
error with a non-zero exit status. It is what the
debug_app_*toolsshell out to.
A standalone SwiftPM package rather than a target in the app's Xcode
project, so the binary lands at a predictable path and nothing has to
search derived data for it. The logic lives in a
DriveKitlibrary witha one-line executable on top, because SwiftPM cannot cleanly test an
executable target and the tree traversal is where the bugs are. The
tests run against a fake accessibility tree, so they need no running app
and no accessibility grant.
The package mirrors the app's strictness: Swift 6 language mode,
ExistentialAny, and warnings as errors. SwiftPM 6.0 has no first-classsetting for the last of those, so it goes through
unsafeFlags, whichis rejected only for a package consumed as a dependency — this one never
is.
Accessibility is gated by TCC, and a grant given to a terminal does not
obviously reach a tool that terminal started.
just drive-doctorreports whether the calling process may read another app's tree, so that
question is answered by running it under each host rather than guessed
at.
Signed-off-by: Jean Mertz git@jeanmertz.com