SIGN IN SIGN UP

Add Capture Text (OCR area capture) (#18)

* Add Capture Text (OCR area capture)

Draw an area and the recognized text is copied to the clipboard.
Reuses the native area selector and the existing Vision-based
ImageTextRecognizer. Available from the menu bar and as a
rebindable hotkey (default Option+5).

* Give Capture Text visible feedback

Capture Text leaves nothing behind - no file, no history entry, no
preview card - so the capture sound was the only signal that anything
happened, and users with sounds turned off got no feedback at all.

Adds a brief toast on the display the area was drawn on, confirming
what reached the clipboard or reporting that nothing was recognized.
Also gates the no-text beep behind the playSounds preference, which
the success path already respected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtc7EvrdPzYHw4g58A7DYX

* Expose Capture Text to Shortcuts

The other capture actions all have App Intents; Capture Text did not,
leaving a hole in the Shortcuts/Siri surface. An OCR action that
returns a String is the most composable of the set.

Adds CaptureTextOutcome so the intent can tell a cancelled selection
apart from a region that had no text in it, rather than collapsing
both into a nil and reporting the wrong reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtc7EvrdPzYHw4g58A7DYX

* Return recognized text in reading order

Vision does not document an ordering for text observations, so joining
them as they arrive scrambles anything laid out in columns. This was
tolerable when OCR was an incidental "copy text from image" action; it
is not when it backs a dedicated capture mode.

Groups observations into visual lines top to bottom and orders each
line left to right. Written as an explicit grouping pass because a
tolerance-based comparator is not a strict weak ordering, which
sorted(by:) requires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtc7EvrdPzYHw4g58A7DYX

* Append textCapture to the end of CaptureHotkeyAction

registerHotkeys() keeps the first action in allCases order when two
share a shortcut, so inserting a case mid-enum silently changes which
action wins a duplicate binding. Appending keeps the existing order
intact and lines the cases up with their hotKeyIDs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtc7EvrdPzYHw4g58A7DYX

* Document Capture Text

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gtc7EvrdPzYHw4g58A7DYX

---------

Co-authored-by: Fayaz Ahmed <fayazara@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
O
Omar Faruk committed
143032aec2ff9ed8093f127e1394556fbad361d4
Parent: 4e00bd4
Committed by GitHub <noreply@github.com> on 9/1/2026, 6:43:01 AM