Tuna

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.