Skip to content

Add hs.ocr#65

Merged
cmsj merged 2 commits into
mainfrom
hs.ocr
May 27, 2026
Merged

Add hs.ocr#65
cmsj merged 2 commits into
mainfrom
hs.ocr

Conversation

@cmsj
Copy link
Copy Markdown
Owner

@cmsj cmsj commented May 26, 2026

Closes #58

@cmsj cmsj self-assigned this May 26, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 26, 2026

Greptile Summary

This PR introduces hs.ocr, a new Hammerspoon module that exposes Apple's Vision framework for on-device text recognition via a Promise-based JavaScript API. It also includes a docs update that renames newcreate / newSearchcreateSearch across several existing modules.

  • hs.ocr module (HSOCRModule, HSOCRObservation, HSOCRResult): recognition runs in a Task.detached background task; OCRConfig and RawObservation are correctly marked Sendable for safe actor-boundary crossing; the Vision bottom-left → top-left coordinate flip in HSOCRObservation is correct.
  • Integration tests (HSOCRIntegrationTests): broad coverage across API shape, error handling, options parsing, and functional correctness; the minimumConfidence filter test only verifies a non-increase in observation count, which may not catch a broken filter on high-contrast input.
  • Docs: api.json and hammerspoon.d.ts are updated to reflect the new module and the new/newSearchcreate/createSearch renames in bonjour, notify, and task.

Confidence Score: 4/5

The change is safe to merge; the new OCR module correctly handles actor isolation, background Vision work, and coordinate conversion, with no data-loss or correctness bugs in the changed paths.

The implementation is clean and well-tested. The only findings are minor: two constants declared as var instead of let, and a filter test that doesn't exercise the filter on high-contrast images. Nothing in the changed code would cause wrong results or crashes for users.

No files require special attention; HSOCRModule.swift is the most logic-heavy file and looks correct throughout.

Important Files Changed

Filename Overview
Hammerspoon 2/Modules/hs.ocr/HSOCRModule.swift New OCR module exposing Apple's Vision framework to JS via a Promise-returning recognizeText API and synchronous supportedLanguages; actor isolation and Sendable data bridging look correct.
Hammerspoon 2/Modules/hs.ocr/HSOCRObservation.swift Vision bottom-left→top-left coordinate conversion is correct; typeName is var instead of let.
Hammerspoon 2/Modules/hs.ocr/HSOCRResult.swift Aggregates observations into a single text string by joining with newlines; typeName is var instead of let.
Hammerspoon 2Tests/IntegrationTests/HSOCRIntegrationTests.swift Comprehensive integration tests covering API shape, error handling, and functional correctness; minimumConfidence filter test only verifies a non-increase, not actual filtering.
Hammerspoon 2/Engine/ModuleRoot.swift Adds ocr property to both the protocol and implementation, consistent with all other modules.
Hammerspoon 2Tests/Helpers/JSTestHarness.swift One-line addition to register HSOCRModule under the ocr key, consistent with all other modules.
docs/api.json Adds hs.ocr API documentation and renames newSearch/new to createSearch/create in bonjour/notify/task docs.
docs/hammerspoon.d.ts TypeScript declarations updated to reflect the new hs.ocr module and createSearch/create renames.

Comments Outside Diff (1)

  1. Hammerspoon 2Tests/IntegrationTests/HSOCRIntegrationTests.swift, line 892-918 ([link](https://github.com/cmsj/hammerspoon2/blob/9064e419e850fbd73c1b495ba51445f3376b5225/Hammerspoon 2Tests/IntegrationTests/HSOCRIntegrationTests.swift#L892-L918))

    P2 Filter test only verifies non-increase

    The assertion _ocrFiltered <= _ocrUnfiltered passes even when Vision returns all results with confidence ≥ 0.9999 (trivially equal counts). For large bold high-contrast text, that is exactly what happens, so the test never actually exercises the filter path. Consider adding a second assertion such as _ocrFiltered === 0 when minimumConfidence: 1.1 (guaranteed to filter everything), which would give a hard signal that the filtering logic actually runs.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: Hammerspoon 2Tests/IntegrationTests/HSOCRIntegrationTests.swift
    Line: 892-918
    
    Comment:
    **Filter test only verifies non-increase**
    
    The assertion `_ocrFiltered <= _ocrUnfiltered` passes even when Vision returns all results with confidence ≥ 0.9999 (trivially equal counts). For large bold high-contrast text, that is exactly what happens, so the test never actually exercises the filter path. Consider adding a second assertion such as `_ocrFiltered === 0` when `minimumConfidence: 1.1` (guaranteed to filter everything), which would give a hard signal that the filtering logic actually runs.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
Hammerspoon 2/Modules/hs.ocr/HSOCRObservation.swift:85
`typeName` is declared as `var` but it is a fixed type-name constant that never changes. The protocol only requires `{ get }`, so `let` expresses the intent more precisely and prevents accidental mutation on the actor.

```suggestion
    @objc let typeName = "HSOCRObservation"
```

### Issue 2 of 3
Hammerspoon 2/Modules/hs.ocr/HSOCRResult.swift:72
Same as `HSOCRObservation`: `typeName` never changes after initialisation, so `let` is the correct storage keyword here.

```suggestion
    @objc let typeName = "HSOCRResult"
```

### Issue 3 of 3
Hammerspoon 2Tests/IntegrationTests/HSOCRIntegrationTests.swift:892-918
**Filter test only verifies non-increase**

The assertion `_ocrFiltered <= _ocrUnfiltered` passes even when Vision returns all results with confidence ≥ 0.9999 (trivially equal counts). For large bold high-contrast text, that is exactly what happens, so the test never actually exercises the filter path. Consider adding a second assertion such as `_ocrFiltered === 0` when `minimumConfidence: 1.1` (guaranteed to filter everything), which would give a hard signal that the filtering logic actually runs.

Reviews (1): Last reviewed commit: "Add hs.ocr" | Re-trigger Greptile

Comment thread Hammerspoon 2/Modules/hs.ocr/HSOCRObservation.swift
Comment thread Hammerspoon 2/Modules/hs.ocr/HSOCRResult.swift
@cmsj cmsj merged commit 3694168 into main May 27, 2026
4 checks passed
@cmsj cmsj deleted the hs.ocr branch May 27, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Native OCR

1 participant