feat: add native macOS application launcher

This commit is contained in:
2026-10-11 18:16:01 +02:00
commit 0d033667ff
10 changed files with 780 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
# Conjure
A native macOS application launcher. Open it normally, search for an application, and press Return to open it or bring its existing instance forward. Global shortcuts are deliberately deferred.
## Build and run
Requires macOS 14 or later and a Swift 6 toolchain (Xcode 16 or later).
```sh
make run
```
This builds a release executable, assembles an ad-hoc-signed application at `.build/Conjure.app`, and opens it through Launch Services. You can also open that app directly in Finder. The local signature is for development, not notarized distribution.
```sh
make build # Build the application without opening it.
make test # Run the discovery and search behavior tests.
```
Open `Package.swift` in Xcode to edit the project. Use the bundled app above to run it with its application identity and metadata.
## Controls
- Type to filter applications; the first match is selected automatically.
- Up/Down changes the selection without leaving search.
- Return, keypad Enter, the Open Application button, or a double-click opens the selection.
- Escape, closing the window, or switching focus away dismisses the launcher.
- Reopen from Finder or the Dock to show it again with an empty search. Dismissal leaves the process running; Command-Q quits it.
- Standard macOS text-editing shortcuts work in the search field.
## Discovery and search
Applications are discovered in `/Applications`, `/System/Applications`, `/System/Library/CoreServices/Applications`, and `~/Applications`, including nested folders. Discovery runs off the UI thread and refreshes whenever the launcher is presented. Hidden items, invalid bundles, and helpers inside application packages are excluded; symlinked applications are deduplicated by their canonical paths.
Search is case- and accent-insensitive. Ranking is exact name, prefix, substring, then ordered-subsequence fuzzy matches. Fuzzy matches favor smaller gaps and earlier starts. Ties and empty searches are alphabetical. Hover over a result to see its path. Launch failures appear in a native alert without dismissing the launcher.
## Native UI
AppKit owns the window chrome, search field, inset table selection, application icons, buttons, menus, fonts, and semantic colors. Appearance follows macOS light/dark settings; no custom-painted Raycast skin or third-party UI dependencies.
- `Sources/Conjure`: application lifecycle, native window, and application launching.
- `Sources/ConjureKit`: filesystem discovery and search ranking.
- `Tests/ConjureKitTests`: deterministic discovery and ranking checks.
The launcher uses Apple's [inset table style](https://developer.apple.com/documentation/appkit/nstableview/style-swift.enum/inset), [application launching](https://developer.apple.com/documentation/appkit/nsworkspace/openapplication(at:configuration:completionhandler:)), and [reopen lifecycle](https://developer.apple.com/documentation/appkit/nsapplicationdelegate/applicationshouldhandlereopen(_:hasvisiblewindows:)).