Extension API
Status: public beta. This catalog is the supported extension boundary. Other symbols may be visible in the shared TunaKit binary without being supported extension API.
This page tracks the current supported TunaKit API. APIs under Unreleased require the next TunaKit package release before an external extension can compile against them.
Declaration
| API | Kind | Purpose |
|---|---|---|
Extension |
class | Framework entry point; override declaration and optionally connection definitions or didLoad() |
ExtensionDeclaration |
struct | Complete Swift declaration for metadata, catalogs, settings, types, rankings, and enrichments |
ExtensionMetadata |
struct | User-visible name, author, description, and SF Symbol |
ExtensionDeclarationCompatibility |
struct | Minimum Tuna and TunaKit versions used when packaging |
CatalogDeclaration |
struct | Stable catalog ID, concrete catalog type, name, defaults, and settings |
CatalogInitialGlobalScope |
enum | Initial .none or explicit .all membership in global search |
ActionCatalogDeclaration |
struct | Stable action-catalog ID, concrete type, and name |
See Extension Declaration and Manifest for every field.
Catalogs and search
| API | Kind | Purpose |
|---|---|---|
Catalog |
protocol | Base catalog contract: identity, name, objects, initializer, and asynchronous scan |
CatalogDefinition |
struct | The host-provided identity, name, enablement, advanced status, and settings |
ActionCatalog |
protocol | Declared actions with no scan, enablement, settings, or source semantics |
ActionCatalogDefinition |
struct | The host-provided identity and name for an action catalog |
CatalogHierarchyNode |
protocol | Makes an item browsable with right arrow |
BrowseCatalogItem |
class | Eager browsable entity |
DeferredBrowseCatalogItem |
class | Browsable entity whose children load on demand |
ScopedSearchBrowseCatalogItem |
class | Browsable entry backed by provider search |
ScopedCatalogSearchProviding |
protocol | Provider-backed search as the user types |
ScopedCatalogSearchPagingProviding |
protocol | Paged provider-backed search |
CatalogSortingProviding |
protocol | Declares catalog-specific sort choices |
CatalogResultsSortModeProviding |
protocol | Supplies the initial result sort mode |
CatalogViewProviding |
protocol | Selects list, grid, or custom catalog presentation |
CatalogHierarchyViewProviding |
protocol | Selects presentation for one hierarchy node’s children |
CatalogResultsPresentation |
enum | Couples a hierarchy view style with its grid configuration |
CatalogGridConfiguration |
struct | Configures grid columns, cell sizes, gaps, outer padding, and cell padding |
CatalogGridPreviewProviding |
protocol | Makes grid cells render item previews instead of extended text |
CatalogQuickLookProviding |
protocol | Asynchronously prepares local files for on-demand Quick Look |
CatalogAsyncPreviewProviding.cachesAsyncPreview |
property | Defaults to true; return false to disable caching, preloading, and shared in-flight loads when provider terms require each displayed preview to load independently |
CatalogItemPreview.init(animatedImageData:) |
initializer | Creates a data-backed animated preview; Tuna plays it for the selected grid item and detail preview |
Call reportScanFinished() after replacing objects. Tuna owns indexing and scheduling.
Browse entries
CatalogHierarchyNode only supplies child navigation. It deliberately does not change an item’s
semantic type or default action: a browsable directory remains .directory, and a browsable
contact remains .contact.
For a generic entry whose purpose is to open another result scope, use BrowseCatalogItem or
DeferredBrowseCatalogItem; they use .searchCatalogEntry, which makes Browse the default.
Use ScopedSearchBrowseCatalogItem for a live provider-backed root; it uses
.dynamicSearchCatalogEntry, making Search the default while retaining Browse for recent or
grouped children. Deferred entries inherit their catalog’s presentation unless initialized with an
explicit childResultsPresentation. Only hand-roll a hierarchy entry when the standard types
cannot express it, and assign the matching type explicitly.
Catalog lifecycle
| API | Adopt when |
|---|---|
StartupScanningCatalog |
The catalog needs to opt out of Tuna’s default startup scan |
RescanSchedulingCatalog |
A watcher or similar source needs to ask Tuna to schedule a rescan |
RetainedCatalogStateReleasing |
The catalog retains caches that Tuna may ask it to release |
CatalogDiagnosticsReporting |
The catalog can explain availability or report useful metrics |
These are capabilities, not callbacks to call yourself. Tuna retains control of timing and policy.
Items and identity
| API | Kind | Purpose |
|---|---|---|
CatalogItem |
class | Base searchable item with stable id, mutable presentation, type, icon, and preview |
CatalogEntity |
class | General-purpose thing; adds optional path and metadata |
CatalogAction |
class | Verb with subject/target rules and a callback |
CatalogMessageItem |
class | Informational or empty-state result |
TextSnippetItem |
class | Text entity and target |
URLItem |
class | URL entity with preview support |
FileSystemEntity |
class | File/directory entity with filesystem metadata |
CatalogReference |
struct | Stable catalog identifier used in persisted references |
ItemReference |
enum | Stable catalog item or transient item reference |
An id is permanent machine identity. title and searchKeys are presentation and matching
data. Each search key is matched independently — a query never matches across key boundaries —
and searchText is the single-key default. Never derive persisted identity from display text.
Actions
| API | Purpose |
|---|---|
CatalogActionTargetRequirement |
Declares no, optional, or required target pane |
supportedSubjectTypes |
Limits the subject types accepted by an action |
allowedTargetTypes |
Limits selectable target types |
targetSearchScope |
Restricts targets to named catalogs and optionally loads or refreshes them when target selection is prepared |
targetRequirementResolver |
Resolves target requirement from the selected subject |
targetPredicateResolver |
Resolves a subject-aware target predicate |
targetTextSeedProvider |
Seeds target-pane text from the subject |
PredicateAwareAction |
Concrete action with subject and target predicates |
ActionAvailabilityProviding |
Hides an action when its app, permission, or required state is unavailable |
ActionFilteringProviding |
Lets a subject narrow the action list |
ActionConfigurationTypeProviding |
Declares every concrete type a dynamic subject may resolve to while configuring commands |
CommandHeadlessEligibility |
Proves whether Hidden execution is safe |
CommandExecutionPolicy |
Declares dismiss, keep-visible, or result-driven presentation intent |
Runnable |
Makes an item directly executable through async run() |
RunnableWithInput |
Adds async text, file, or files input execution |
CatalogAction and batch callbacks are async and return ActionResult. Runnable implementations
must declare headless eligibility separately from execution policy; RunnableWithInput may override
both contracts for input execution.
targetSearchScope defaults to .library. Use .catalogs for finite dynamic target collections.
Its preparation policy can use current indexed values, load a catalog once after registration, or
refresh it once whenever that action’s target selection is prepared. Tuna coalesces active scans and
reruns target search when the prepared catalog finishes scanning.
Dynamic subjects that may resolve to several types should implement
ActionConfigurationTypeProviding. Tuna offers the union of compatible actions in Combo Mode and
global hotkey setup without resolving live data. A single-type ActionSubjectResolving item can
keep that type in typeID; execution still resolves and validates the concrete subject.
Results
| API | Use for |
|---|---|
ActionResult.success |
Completed action with no additional presentation |
ActionResult.cancelled |
User cancelled; completes quietly without command history |
ActionResult.failure |
User-visible failure |
ActionResult.subjects |
Inline results that should replace the staged subjects |
ActionResult.results |
Results that should become searchable in the results list |
ActionResult.background |
Background work tracked by Tuna |
ActionResult.review |
A confirmation/review presentation before execution |
CLIProcessRequest |
A subprocess request routed through Tuna’s command runner |
Consult Xcode autocomplete for associated values; the exact result payloads remain beta.
Types and rankings
| API | Purpose |
|---|---|
TypeID |
Stable type identifier connecting entities and actions |
TypeRegistrationDefinition |
Registers a custom type, display name, and parent types |
DefaultActionRankingDefinition |
Supplies default action ordering for a type |
ActionReference |
References an action by catalog and item ID |
Common built-ins include .entity, .action, .file, .directory, .application, .url,
.textSnippet, .contact, .emailAddress, .phoneNumber, .image, .color, and
.searchCatalogEntry.
Settings and connections
| API | Purpose |
|---|---|
CatalogSettingDefinition |
Declares string, Boolean, secret, or option-backed settings |
CatalogSettingStore |
Reads and writes declared settings; secrets use Keychain |
ExtensionConnectionDefinition |
Declares secret-token or OAuth connection UI |
OAuthPKCEConfiguration |
Configures direct authorization-code + PKCE instead of the web broker |
OAuthAuthorizationCodeClient |
Exchanges authorization codes and refresh tokens without a client secret |
OAuthAuthorizationCallback |
Strictly parses direct OAuth success and failure callbacks |
ExtensionConnectionRecord |
Persisted non-secret connection metadata |
ExtensionConnectionStore |
Reads/writes connection records and Keychain tokens |
PKCE / PKCEPair |
OAuth PKCE generation helpers |
App enrichments
| API | Purpose |
|---|---|
AppBrowseEnrichmentDefinition |
Adds declared catalog entries when browsing matching apps |
AppBrowseEnrichmentEntryDefinition |
Catalog reference and optional title for browse enrichment |
AppActionEnrichmentDefinition |
Adds action catalogs and an optional preferred action order for matching apps |
Presentation protocols
The supported beta conveniences include item preview, icon, pasteboard, custom result view, sort, and layout protocols used by the public examples. They are less stable than the declaration, catalog, identity, type, and action contracts.
Text, automation, copy, and display representations are deliberately separate:
| API | Purpose |
|---|---|
TextValueProviding |
Supplies exact primary text without trimming or substituting a display label |
CopyRepresentationProviding |
Overrides Copy to Clipboard without changing the item’s primary text |
PasteboardDataProviding |
Supplies one non-text pasteboard representation, optionally alongside copied text |
PasteboardDataRepresentation |
Encoded data and its NSPasteboard.PasteboardType raw value |
CatalogItemInteractionReporting |
Reports result appearance/disappearance, pointer activation, and successful host Paste actions for provider analytics |
providedTextValue() |
Returns nonblank TextValueProviding content for an item of any type |
textInputValue() |
Returns exact primary text only when the item also has a textSnippet-derived type |
automationInput() |
Returns strict typed .text or .file machine input; solver results use their unformatted value |
copyTextRepresentation() |
Returns copy-specific text; solver results keep locale-aware formatting |
displayTextValue() / displayTextFallback() |
Returns presentation text; only the fallback may use an item’s detail or title |
Use the strict text or automation helpers to validate action input. Display fallbacks are for UI, not for deciding that an item can be passed to a command.
Use PasteboardDataProviding when Copy or Paste must include a non-text flavor such as
public.html, RTF, or image data. If the item also has a copyable text representation, Tuna writes
both flavors so receiving apps can choose the richest format they support.
CatalogItemInteractionReporting callbacks must return immediately and schedule analytics work
asynchronously. Appearance follows the result cell lifecycle and does not prove that an async
preview loaded; providers with an asset-level impression rule should combine it with their preview
completion. Activation means the user clicked or tapped the result. Share means Tuna’s built-in
Paste or Paste as Plain Text action completed successfully.
Not extension API
AI prompt/provider APIs, Tuna app state and controllers, host scheduling policy, theme APIs, low-level concurrency wrappers, host-only UI, and undocumented host hooks are not supported extension API.
