QuickActions SDK
QuickActions SDK
Overview
QuickActions SDK lets plugins register global actions in the MetaK / Quick Actions panel and reuse Flow Transfer native sharing. meta / plugin.meta remains as a compatibility alias. New code should prefer quickActions / plugin.quickActions.
Quick Start
Plugin index.js can use globalThis.quickActions directly. plugin.quickActions points to the same SDK instance.
quickActions.registerAction({
id: 'share-current-item',
render: {
basic: {
title: 'Share current item',
subtitle: 'Use system share, AirDrop, or mail',
icon: { type: 'class', value: 'i-ri-share-line' }
},
shortcut: '⌘⇧S',
group: 'Share'
},
priority: 120
})
quickActions.onActionExecute(async ({ actionId, item }) => {
if (actionId !== 'share-current-item') return
const result = await quickActions.shareItem(item, {
preferredTargets: ['airdrop', 'system-share', 'mail']
})
if (!result.success) {
logger.warn('Native share failed', result.error)
}
})
API Reference
registerAction(action)
Register a global action shown in the MetaK / Quick Actions panel.
const unregister = quickActions.registerAction({
id: 'copy-title',
render: {
basic: {
title: 'Copy title',
subtitle: 'Copy the current item title',
icon: { type: 'class', value: 'i-ri-file-copy-line' }
},
group: 'Text'
}
})
// Later
unregister()
unregisterAll()
Unregister all Quick Actions created by the current plugin.
onActionExecute(handler)
Listen for actions registered by the current plugin. The callback only receives actionId values owned by this plugin.
const dispose = quickActions.onActionExecute(({ actionId, item }) => {
logger.info('quick action executed', { actionId, itemId: item.id })
})
dispose()
getNativeShareTargets(payloadType?)
Read native share targets that are actually available on the current platform. The result comes from the Flow Transfer target registry and only includes targets where isNativeShare === true.
| Platform | Targets |
|---|---|
| macOS | system-share, airdrop, mail, messages |
| Windows | mail |
| Linux | mail |
const targets = await quickActions.getNativeShareTargets('files')
const canAirDrop = targets.some(target => target.id === 'airdrop')
resolveNativeShareTarget(options?)
Resolve one available native share target from the payload type and plugin preferences, so plugins do not duplicate platform fallback logic.
Default strategy:
| Payload type | Default order |
|---|---|
files / image | airdrop -> system-share -> mail |
text / html / json / custom | system-share -> mail -> messages |
const target = await quickActions.resolveNativeShareTarget({
payloadType: 'files',
preferredTargets: ['airdrop', 'mail'],
allowFallback: false
})
if (!target) {
logger.info('No preferred native share target available')
}
allowFallback defaults to true. When set to false, unavailable preferred targets return undefined instead of silently selecting another target.
nativeShare(payload, options?)
Share a Flow payload through Flow Transfer's flow:native:share channel. Permission, error, and platform fallback semantics stay aligned with Flow Transfer.
const result = await quickActions.nativeShare(
{
type: 'text',
data: 'Hello from Tuff',
context: {
sourcePluginId: plugin.getInfo().name,
metadata: { title: 'Share text' }
}
},
{ target: 'mail' }
)
createSharePayloadFromItem(item, options?)
Convert the current CoreBox item into a shareable Flow payload.
- File items prefer
{ type: 'files', data: [path] } - Link or generic items use
{ type: 'text', data: title + subtitle + url } metadatapreservesitemId,itemKind,sourceId, andsourceType
shareItem(item, options?)
Wrap the common item -> Flow payload -> target resolution -> native share path. This is the preferred helper for MetaK global share actions.
const result = await quickActions.shareItem(item, {
preferredTargets: ['airdrop', 'system-share', 'mail']
})
if (!result.success) {
logger.warn('Share failed', result.error)
}
If your plugin needs full control over payload or target selection, use createSharePayloadFromItem() + resolveNativeShareTarget() + nativeShare().
Type Summary
interface QuickActionsSDK {
registerAction(action: TuffQuickAction): () => void
unregisterAll(): void
onActionExecute(handler: QuickActionExecuteHandler): () => void
getNativeShareTargets(payloadType?: FlowPayloadType): Promise<FlowTargetInfo[]>
resolveNativeShareTarget(options?: QuickActionNativeShareTargetOptions): Promise<FlowTargetInfo | undefined>
nativeShare(payload: FlowPayload, options?: { target?: string }): Promise<NativeShareResult>
createSharePayloadFromItem(item: TuffItem, options?: QuickActionItemSharePayloadOptions): FlowPayload
shareItem(item: TuffItem, options?: QuickActionShareItemOptions): Promise<NativeShareResult>
}
Best Practices
- Use
quickActionsfor new code, and keepmetaonly for old plugin compatibility. - Before sharing, call
getNativeShareTargets()orresolveNativeShareTarget()instead of guessing availability fromprocess.platform. - Prefer
airdropfor files and images; prefersystem-sharefor text-like payloads. - Windows and Linux currently expose only the explicit
mailfallback, not a fake system share panel. - Handle
result.success === falseand provide copy, mail, or plugin-specific fallback behavior.