Automattic / Automattic/harper

Application picker: `mdfind` returns non-application bundles and the correct filter is unresolved

Open
#4,084 1 comment 2 reactions 0 assignees View on GitHub
desktop enhancement
Dominant language
Rust
Stars
15.4k
Forks
627
Avg merge
1d 15h
Merged PRs (30d)
106

Description

## What

Harper Desktop discovers installed applications by shelling out to `mdfind` in `harper-desktop/src-tauri/src/mac_broker/app_catalog.rs`, once for the whole catalog and again per bundle ID:

```rust
// app_catalog.rs:32
Command::new("mdfind").arg(format!("kMDItemContentType == \"{APPLICATION_BUNDLE_CONTENT_TYPE}\""))

// app_catalog.rs:83
Command::new("mdfind").arg(format!("kMDItemCFBundleIdentifier == \"{predicate_bundle_id}\""))
```

Two separate problems come out of this.

## 1. The result set is not a list of applications

On one macOS machine, that first query returns 441 bundles:

```
mdfind 'kMDItemContentType == "com.apple.application-bundle"' -> 441
of those, outside /Applications -> 386
/Applications/*.app actually on disk -> 43
```

Some of the 386 are clearly not things a user would ever pick:

```
/System/Library/CoreServices/DiskImageMounter.app
```

But most of them are things a user obviously would, such as `/System/Applications/Mail.app`, `Preview.app` and `TextEdit.app`. So neither "everything `mdfind` returns" nor "only `/Applications`" is the right set, and the correct filter is an open question rather than an oversight.

@hippietrail explored this before Harper and published his experiments at https://github.com/hippietrail/bumble. His summary, which matches the numbers above, is that both `mdfind` and the Spotlight APIs need tweaking to find all the real apps and exclude the ones that are not really apps, and that neither matched the ideal. He offered a useful target for "ideal": the set shown by the **Apps** app introduced in macOS Tahoe. Amusingly `/System/Applications/Apps.app` is itself in the `mdfind` results.

Worth recording one correction here, since it is easy to assume otherwise: `mdfind` and `NSMetadataQuery` do **not** return the same thing in practice, even though `mdfind` is presumably built on the same Spotlight index. @hippietrail has run both; this is his observation, not mine.

## 2. The calls are blocking with no timeout

Both call sites run `.output()` synchronously with no timeout and no cancellation. `bumble`'s Tauri version uses a 300ms timeout with cancellation, plus bundle ID deduplication, which is the shape this probably wants.

## Suggested direction

Nothing here is urgent, and it is deliberately not bundled into #4024, which stays a six-line fix for the reported bug.

- Decide the target set. Matching the Tahoe **Apps** app seems like the most defensible definition.
- Work out the filter that produces it, which is the actual hard part.
- Separately, consider moving off the blocking subprocess, whether or not the source changes.

`bumble` has three implementations to crib from: a Tauri app, a raw Objective-C runtime CLI, and one using the `objc2` crate.

Contributor guide

Open the contributing guide

Research direction

Start in harper-desktop/src-tauri/src/mac_broker/app_catalog.rs and inspect both mdfind call sites. Compare the three implementations in hippietrail/bumble, then determine a filter matching the macOS Tahoe Apps app while excluding unwanted bundles. Done should also cover timeout or cancellation behavior and bundle ID deduplication.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust, tauri
Domain
desktop
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.