Skip to content

Add hs.spotlight#70

Merged
cmsj merged 4 commits into
mainfrom
hs.spotlight
May 28, 2026
Merged

Add hs.spotlight#70
cmsj merged 4 commits into
mainfrom
hs.spotlight

Conversation

@cmsj
Copy link
Copy Markdown
Owner

@cmsj cmsj commented May 28, 2026

No description provided.

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

greptile-apps Bot commented May 28, 2026

Greptile Summary

Adds hs.spotlight, a new module that wraps NSMetadataQuery to expose Spotlight metadata searches to the Hammerspoon JavaScript engine. The implementation covers query creation, scoped searching, sorting, grouping, value-list aggregation, live-update callbacks, and a comprehensive integration test suite.

  • New files: HSSpotlightQuery, HSSpotlightItem, HSSpotlightGroup, and HSSpotlightModule implement the full query lifecycle; the module is wired into ModuleRoot and the test harness.
  • One defect: setQuery passes the raw predicate string to NSPredicate(format:), which treats %-sequences as format specifiers and will crash on any predicate containing characters like %@, %d, or %K (common in URL-encoded filenames or query values). Switching to NSPredicate(fromMetadataQueryString:) fixes this.

Confidence Score: 3/5

Safe to merge after fixing the predicate crash; all other code is well-structured and thoroughly tested.

The setQuery implementation will crash at runtime whenever a user's predicate string contains a % followed by a valid format specifier character (e.g. %@, %d, %K). This is a silent API contract violation that can surface on any predicate containing URL-encoded characters or email addresses. Everything else in the module looks solid.

HSSpotlightQuery.swift — specifically the setQuery method's NSPredicate(format:) call.

Important Files Changed

Filename Overview
Hammerspoon 2/Modules/hs.spotlight/HSSpotlightQuery.swift Core query class; setQuery passes user predicate directly to NSPredicate(format:), which treats %@/%d/%K etc. as format specifiers and will crash on predicates containing those characters.
Hammerspoon 2/Modules/hs.spotlight/HSSpotlightModule.swift Module registration, factory helpers (create, search), and constant dictionaries (scope, attribute). No issues found.
Hammerspoon 2/Modules/hs.spotlight/HSSpotlightItem.swift Thin wrapper around NSMetadataItem with a bridging helper that converts URLs and arrays; looks correct.
Hammerspoon 2/Modules/hs.spotlight/HSSpotlightGroup.swift Wrapper for NSMetadataQueryResultGroup; delegates cleanly to the underlying object; no issues found.
Hammerspoon 2Tests/IntegrationTests/HSSpotlightIntegrationTests.swift Comprehensive integration test suite covering API structure, lifecycle, configuration, and live-query execution; no issues found.
Hammerspoon 2/Engine/ModuleRoot.swift Adds spotlight property to both the protocol and concrete implementation; consistent with existing module registrations.
Hammerspoon 2Tests/Helpers/JSTestHarness.swift Adds "spotlight" case to the module loader switch; straightforward and consistent with existing cases.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
Hammerspoon 2/Modules/hs.spotlight/HSSpotlightQuery.swift:344-347
`NSPredicate(format:)` treats its argument as a printf-style format string. A user-supplied predicate that happens to contain `%@`, `%d`, `%K`, or any other valid format specifier—e.g. `kMDItemFSName == 'Report%20Final.pdf'` or `kMDItemWhereFroms CONTAINS '%40gmail'`—will crash at the moment the format string is parsed, because no corresponding varargs are provided. Use `NSPredicate(fromMetadataQueryString:)`, which is specifically designed to parse raw Spotlight MDQuery expression strings without format-string interpolation.

```suggestion
        let wasRunning = isRunning
        if wasRunning { query.stop() }
        guard let pred = NSPredicate(fromMetadataQueryString: predicate) else {
            AKError("hs.spotlight.setQuery(): invalid predicate syntax — \(predicate)")
            if wasRunning { _ = start() }
            return self
        }
        query.predicate = pred
        if wasRunning { _ = start() }
```

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

Comment thread Hammerspoon 2/Modules/hs.spotlight/HSSpotlightQuery.swift
cmsj and others added 3 commits May 28, 2026 22:05
@cmsj cmsj merged commit 4611d58 into main May 28, 2026
4 checks passed
@cmsj cmsj deleted the hs.spotlight branch May 28, 2026 22:20
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.

1 participant