Files
conjure/README.md
T

16 KiB
Raw Blame History

Conjure

A native macOS application launcher. Open it normally or activate it with a configured global shortcut, search for an application, and press Return to open it or bring its existing instance forward.

Build, run, and install

Requires macOS 14 or later and a Swift 6 toolchain (Xcode 16 or later).

make run

This builds a release executable, assembles an ad-hoc-signed application at .build/Conjure.app, gracefully quits any running instance of that exact development bundle, and launches a fresh process through Launch Services. This ensures rebuilt code is loaded; simply opening an already-running app in Finder does not reload its executable. Other copies of Conjure are left running. The local signature is for development, not notarized distribution.

make build   # Build the application without opening it.
make install # Install the application at /Applications/Conjure.app.
make test    # Run behavior and installation safety tests.

make install rebuilds the signed bundle and installs it without launching it. To install for your user only, or if /Applications is not writable:

make install INSTALL_DIR="$HOME/Applications"

Installation verifies a temporary copy before replacing the entire existing bundle, so removed resources do not linger. Quit the app at the destination before reinstalling; other running copies are left alone. Unrelated apps and symbolic-link destinations are not replaced. Installation does not request administrator privileges, and the signature remains local/ad-hoc rather than notarized.

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 or Control-K/Control-J changes the selection without leaving search or modifying its text.
  • Return, keypad Enter, the Open Application button, or a double-click opens the selection.
  • Command-K or the bottom-right Actions button opens a searchable selector for the selected application. Return chooses Uninstall application; Escape closes the selector and returns focus to search.
  • Escape or Command-W dismisses the launcher and restores the previously active application. Switching focus away dismisses it without stealing focus back.
  • Reopen from Finder to show it again with an empty search. Dismissal leaves the process running; Command-Q quits it.
  • Every activation brings the launcher to the currently active macOS Space, including full-screen Spaces, without switching desktops.
  • Standard macOS text-editing shortcuts work in the search field.
  • Command-comma opens the native Settings window.
  • Right-click the launcher background for Settings and Quit.
  • Drag the panel background to move it freely. Three stippled guides mark the target left, right, and top edges: the launcher is horizontally centered, its top edge sits one-fifth down the current display's usable area, and the side guides are exactly one launcher-width apart. Each axis brightens within its 12-point snap range, but the window snaps only when the mouse button is released. Releasing outside the range leaves that axis untouched; dismissal cancels without snapping. Guides remain continuous underneath the frosted launcher rather than being cut out around it. They disappear on release or dismissal and do not intercept input.
  • The final dragged or snapped position is saved locally with the display's stable identifier and restored across restarts. Before showing the launcher, Conjure checks that the saved display is connected and the whole panel fits its current usable area. Missing displays, invalid coordinates, or off-screen positions fall back to the default centered, one-fifth-down alignment on an available display; the fallback is kept inside the usable area when the panel fits. First launch uses the same default alignment.

Conjure runs as a native accessory app: no Dock icon, app-switcher entry, or menu-bar menus. Keyboard menu shortcuts remain available while its window is focused.

Global shortcut

Show the launcher and press ⌘,, or right-click its background and choose Settings…. Click Record Shortcut… and press a combination containing Command, Option, or Control. Shift can be added. The shortcut is saved locally and restored when Conjure starts. No shortcut is claimed until you choose one; Clear disables it.

For Command-Space, click Use ⌘Space. If it conflicts, open System Settings → Keyboard → Keyboard Shortcuts and disable or change the conflicting Spotlight or Input Sources binding, or another app's shortcut, then try again. The Settings window includes an Open Keyboard Settings… button. Conjure reports conflicts rather than modifying macOS preferences, and a failed change preserves your working shortcut.

The global shortcut shows the launcher with an empty query and search focused. Press it again while the launcher is focused to dismiss it and return to the previously active app. If Conjure is running in the background, the shortcut brings it forward. Recording temporarily pauses global activation; Escape, moving focus out of the recorder, or closing Settings cancels recording and restores the saved binding.

Activation uses the native macOS hotkey API, without an Accessibility permission or a global keyboard monitor. It works only while Conjure is running; it does not launch a quit app or enable launch at login.

Launch at login

Open Settings with ⌘, and enable Launch at login. Conjure uses macOS's native login-item service and reads its actual registration status rather than storing a separate preference. If macOS requires approval, Settings explains this and offers Open Login Items Settings…. Registration errors are shown beside the control, and the checkbox returns to the actual system state. Install Conjure in /Applications before enabling it; disable the toggle to unregister it.

Conjure recognizes the native login-launch Apple event and starts without showing a window or taking focus, while still registering its saved global shortcut. Opening it manually from Finder still shows the launcher, including when it is already running. If shortcut registration fails at login, the error is retained and shown in Settings when you next open Conjure manually. Normal manual launches continue to report startup errors immediately.

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, full-name prefix, word prefix, ordered word initials, substring, then ordered-subsequence fuzzy matches. Fuzzy matches favor smaller gaps and earlier starts. Equally good text matches are ordered by successful launch count, then most recent launch, then alphabetically. Usage never promotes a weaker text match above a stronger one or changes which applications match. Hover over a result to see its path. Launch failures appear in a native alert without dismissing the launcher.

Words are runs of letters or numbers separated by spaces, punctuation, or symbols. For example, settings matches the second word of System Settings, gc matches Google Chrome, and ss matches System Settings. Initials must occur in order but can skip words: both vsc and vc match Visual Studio Code.

With an empty search, applications are ordered by successful launch count, then most recent launch, then alphabetically. Usage is stored locally in the app's preferences and survives restarts. Only launches through Conjure count; failed launches do not. Applications without history remain alphabetical.

Background discovery preserves the selected application even if its row changes. If that application disappears, the first remaining result is selected. Changing the query or reopening the launcher selects the first result.

Applications with identical display names show a muted containing-folder hint beside the name. Copies sharing the same folder show their full application bundle paths instead. Home paths abbreviate to ~, and long hints truncate in the middle. Unique names have no hint; locations are recalculated whenever discovery refreshes.

Application actions and uninstall

Select an application and open Actions ⌘K. The red Uninstall application action opens a review sheet with file checkboxes, paths, sizes, and a selected-item count. Filtering by name or path does not change selections. Up/Down highlights rows; Space toggles the highlighted eligible item when the file list has focus. Back or Escape returns to the launcher. Return or the uninstall button opens a final confirmation; nothing is moved merely by choosing the action.

The actions selector is an arrowless panel inside the launcher, aligned to the bottom and right edges of the footer action pill, replacing it visually while open rather than floating above it. It shares the launcher's frosted Sunset background, 38-point selection row height, 14-point action text, rounded selection styling, and Return key badge; selection width follows the panel. The application name appears at the top and borderless action search sits eight points from the bottom, without a divider. The transition is direct, without a morph animation. Escape, Command-K, an outside click, or switching away closes it and restores the pill. Closing while Conjure remains active restores launcher search focus; switching away does not steal focus back. Return in action search chooses the visible action rather than launching the underlying application.

Discovery includes the application bundle and exact bundle-ID paths in your Library: Preferences, Caches, Application Support, Logs, Saved Application State, Application Scripts, and Containers. Embedded extension identifiers are included. App-group entitlements are read from validated native code signatures; related shared Group Containers and Application Scripts remain unchecked because other applications may use them. Conjure does not guess name-based leftovers or include package receipts. This is conservative discovery, not a guarantee that every associated file is found.

System-managed applications, Conjure itself, invalid bundles, symbolic-link paths, locked items, and files owned by another user are not removable. Locked candidates show a reason. A locked application bundle can still have eligible user-owned associated data; removing that data does not remove the locked application itself. No administrator authorization is requested. Running instances of the selected application and its embedded applications are asked to quit gracefully; refusal or timeout stops the operation before moving files.

Uninstall freezes the selected paths and records filesystem identities, then stages items by exclusive same-volume moves into private quarantine directories. A durable journal records each intended move before it happens. Staging failure attempts reverse-order restoration without overwriting recreated original paths. Only after every item is staged is the operation committed and finalized into Trash. A finalization failure retains committed quarantine data rather than trying to undo an already committed uninstall.

Interrupted operations are recovered on startup: uncommitted operations restore their originals; committed operations finish moving items to Trash. Unresolved operations block new uninstalls. Failure feedback offers Retry recovery and identifies retained journal/quarantine paths. Startup recovery feedback and retry remain available in Settings without taking focus during a login launch. Authenticated journals live under ~/Library/Application Support/Conjure/UninstallTransactions; completed journals retain original-to-Trash mappings in Completed.

Files are never permanently deleted by uninstall. Trash moves preserve file metadata, but Finder's Put Back metadata is not created; restore completed items manually using the retained original-path mappings. Rollback is best-effort, not atomic: inaccessible or disconnected volumes and recreated paths can require manual recovery. Same-user malicious code with access to the journal key is outside the journal-authentication guarantee. Unsupported filesystem semantics fail closed.

Native UI

The launcher keeps its Raycast-inspired 750 × 474-point, titlebar-free rounded panel, large borderless search field, compact icon rows, right-aligned application labels, and bottom-right launch pill. Its Sunset palette uses a dark brown background, soft amber and rust glows, warm cream text, and orange accents on the caret, selection, and action outline.

The application icon uses the same orange sparkles SF Symbol on a self-contained, rounded dark-brown tile. Scripts/icon.swift renders every standard and Retina icon size, and make build packages the resulting .icns in the signed bundle for Finder and other system icon surfaces. Conjure remains an accessory app; adding an application icon does not add a Dock or app-switcher entry.

Settings shares the launcher's dark appearance, frosted HUD material, Sunset background glows, cream headings, and orange control accents. The material and tint extend behind the title bar, while controls stay below it. Native window controls and shortcut recording behavior remain available.

The brown tint is 35% opaque over an active, behind-window NSVisualEffectView using the native HUD material. This exposes macOS's blurred backdrop while retaining the warm palette and glows; the system material supplies an opaque fallback when Reduce Transparency is enabled. Both the panel and launch pill use native rounded alpha masks alongside layer clipping, keeping material inside its rounded outline and making the window shadow follow the same shape.

AppKit still provides text editing, table navigation, scrolling, application icons, controls, menus, fonts, and visual-effect materials. The background uses cached native radial gradients that fade to transparent: static soft blobs, without animations, timers, image assets, blur filters, or third-party UI dependencies. Decorative drawing does not intercept clicks. Increased-contrast settings strengthen the selection outline, and text colors are tuned for readability across the glows and selection.

  • Sources/Conjure: application lifecycle, launcher, Settings, contextual actions and uninstall review windows, and application launching.
  • Sources/ConjureKit: filesystem discovery, search ranking, launch history, global shortcut registration, launcher alignment geometry, associated-file discovery, and journaled uninstall/recovery.
  • Tests/ConjureKitTests: deterministic discovery, ranking, history, shortcut validation, alignment boundaries, installation safety, and uninstall failure/recovery checks.

The launcher uses Apple's visual-effect materials, table row selection drawing, application launching, and reopen lifecycle.